diff --git a/BUILD.gn b/BUILD.gn
index 861191e82..d62cd51 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1408,7 +1408,6 @@
       data += [
         "//third_party/blink/web_tests/platform/win/",
         "//third_party/blink/web_tests/platform/win10/",
-        "//third_party/blink/web_tests/platform/win7/",
       ]
       if (is_linux || is_fuchsia) {
         data += [ "//third_party/blink/web_tests/platform/linux/" ]
@@ -1475,7 +1474,6 @@
       data += [
         "//third_party/blink/web_tests/platform/win/",
         "//third_party/blink/web_tests/platform/win10/",
-        "//third_party/blink/web_tests/platform/win7/",
       ]
       if (is_linux || is_fuchsia) {
         data += [ "//third_party/blink/web_tests/platform/linux/" ]
diff --git a/DEPS b/DEPS
index c8855ca..d7592d73 100644
--- a/DEPS
+++ b/DEPS
@@ -280,15 +280,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '4e085a7ab0698ce157ad2d64622992169d56f860',
+  'skia_revision': '768043eb0dacda8e8355e272c7b3864d660cd869',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '8bb533629d6ed294c5d66425da571e0f8fef0a69',
+  'v8_revision': 'f43eac146e5ee86a4941d61cfef58bce836e35f4',
   # 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': '659fb3c50e7c48c454cae1b269607b5a99ceb24e',
+  'angle_revision': 'c525ccf7de8344414334014ada2c2cef09a8f2f2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -296,7 +296,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'c5807c5522f360c78ab123e8342d66a15114acfa',
+  'pdfium_revision': '9b8ab7d0d124b7140e02b1342878933719870833',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -307,7 +307,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:8.20220711.1.1',
+  'fuchsia_version': 'version:8.20220712.0.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.
@@ -347,11 +347,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling OTS
   # and whatever else without interference from each other.
-  'ots_revision': 'ee537ac096667eed6559124164c3e8482646fd77',
+  'ots_revision': '46bea9879127d0ff1c6601b078e2ce98e83fcd33',
   # 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': '1dee059cfe3ff27f6e12795142099f14afaff00e',
+  'catapult_revision': '0da11c3cda0476f7ffac11fe74e48117d562a022',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -359,7 +359,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': 'c2a3fab7e76794bdb8e7a7aed138059ba8582a49',
+  'devtools_frontend_revision': '788bf6c18e508676255542ad790063d03e7ea38a',
   # 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.
@@ -1146,7 +1146,7 @@
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
-      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '98ffe74a1036ae363a12dc57d14dd88535504dcb',
+      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'b25c4015bf76a84f0132546a2176802330b7f86c',
       'condition': 'checkout_linux',
   },
 
@@ -1573,8 +1573,8 @@
   'src/third_party/qemu-linux-arm64': {
       'packages': [
           {
-              'package': 'fuchsia/qemu/linux-arm64',
-              'version': 'b1b61a39e3ab0935cd030f27e01740578b04b967'
+              'package': 'fuchsia/third_party/qemu/linux-arm64',
+              'version': 'BpnoBb2d44_SOm9toN6Lju5a2RLGAc1TPUO6xyijoP8C'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia and checkout_fuchsia_for_arm64_host',
@@ -1704,10 +1704,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '0f7bb3315610bc1a77ead47660a6ce2195a0a1c6',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '46fce27f8542c6d85cf427d76848b88c8bda7467',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'deec4fea50711c51954e7b19ba4d92aeaa5a1ff1',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'c501f30333ce8b46a92b75a6bf75733ddb0e9741',
+    Var('webrtc_git') + '/src.git' + '@' + '5525e6310b34626a2193ee8267a20d2d0d3b8015',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1780,7 +1780,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@8af0d8049d7cee666748e26e30316887c53252c0',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@32af5467dc29eb84ccac53e0abe53dd26a43bd8c',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/WATCHLISTS b/WATCHLISTS
index 6cbd5ce7..4a64057 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1711,6 +1711,9 @@
     'screen_ai': {
       'filepath': 'screen_ai',
     },
+    'search_prefetch': {
+      'filepath': 'chrome/browser/prefetch/search_prefetch',
+    },
     'security': {
       'filepath': 'base/json/'\
                   '|base/memory/.*shared_memory'\
@@ -2800,6 +2803,7 @@
     'scanning': ['gavinwill+scanning-watch@chromium.org',
                  'zentaro+scanning-watch@chromium.org'],
     'screen_ai': ['rhalavati+watch@chromium.org'],
+    'search_prefetch': ['lingqi+watch@chromium.org'],
     'security': ['security-watchlist@chromium.org'],
     'select_to_speak': ['katie+watch@chromium.org',
                         'anastasi+watch@google.com'],
diff --git a/android_webview/test/components/crx_smoke_tests.py b/android_webview/test/components/crx_smoke_tests.py
index c8e64d2..9dc13dc 100644
--- a/android_webview/test/components/crx_smoke_tests.py
+++ b/android_webview/test/components/crx_smoke_tests.py
@@ -98,9 +98,11 @@
 
     cls._device_components_dir = ('/data/data/%s/app_webview/components' %
                                   webview_package_name)
-    logcat_output_dir = (
-        os.path.dirname(cls._typ_runner.args.write_full_results_to or '') or
-        os.getcwd())
+
+    if cls.child.artifact_output_dir:
+      logcat_output_dir = os.path.dirname(cls.child.artifact_output_dir)
+    else:
+      logcat_output_dir = os.getcwd()
 
     # Set up a logcat monitor
     cls._logcat_monitor = logcat_monitor.LogcatMonitor(
diff --git a/ash/assistant/ui/main_stage/animated_container_view.cc b/ash/assistant/ui/main_stage/animated_container_view.cc
index a484b8a..4ae10c4b 100644
--- a/ash/assistant/ui/main_stage/animated_container_view.cc
+++ b/ash/assistant/ui/main_stage/animated_container_view.cc
@@ -125,8 +125,11 @@
   // their views immediately and we want to ensure that any animation observers
   // will be notified of an abort, not an animation completion.  Otherwise there
   // is potential to enter into a bad state (see crbug/952996).
-  for (const auto& animator : animators_)
+  for (const auto& animator : animators_) {
     animator->AbortAnimation();
+    // TODO(b/237704325): Fix ChromeVox focusing on removed chip views
+    animator->view()->SetVisible(false);
+  }
 
   animators_.clear();
 
diff --git a/ash/assistant/ui/main_stage/suggestion_container_view.cc b/ash/assistant/ui/main_stage/suggestion_container_view.cc
index 1c2da6a..997b146 100644
--- a/ash/assistant/ui/main_stage/suggestion_container_view.cc
+++ b/ash/assistant/ui/main_stage/suggestion_container_view.cc
@@ -72,7 +72,6 @@
         layer()->GetAnimator(), CreateAnimateInAnimation(), observer,
         base::BindRepeating<void(const std::string&, int)>(
             base::UmaHistogramPercentage, kAssistantSuggestionChipHistogram));
-    ElementAnimator::view()->SetVisible(true);
   }
 
   void AnimateOut(ui::CallbackLayerAnimationObserver* observer) override {
@@ -80,7 +79,6 @@
         layer()->GetAnimator(), CreateAnimateOutAnimation(), observer,
         base::BindRepeating<void(const std::string&, int)>(
             base::UmaHistogramPercentage, kAssistantSuggestionChipHistogram));
-    ElementAnimator::view()->SetVisible(false);
   }
 
   void FadeOut(ui::CallbackLayerAnimationObserver* observer) override {
diff --git a/ash/components/attestation/BUILD.gn b/ash/components/attestation/BUILD.gn
index d9ad808..09ddbde 100644
--- a/ash/components/attestation/BUILD.gn
+++ b/ash/components/attestation/BUILD.gn
@@ -12,8 +12,8 @@
   deps = [
     "//ash/components/cryptohome",
     "//base",
-    "//chromeos/dbus/attestation",
-    "//chromeos/dbus/attestation:attestation_proto",
+    "//chromeos/ash/components/dbus/attestation",
+    "//chromeos/ash/components/dbus/attestation:attestation_proto",
     "//chromeos/dbus/common",
     "//components/account_id",
     "//crypto",
@@ -41,7 +41,7 @@
   public_deps = [ ":attestation" ]
   deps = [
     "//base/test:test_support",
-    "//chromeos/dbus/attestation:attestation_proto",
+    "//chromeos/ash/components/dbus/attestation:attestation_proto",
     "//chromeos/dbus/constants:constants",
     "//components/account_id",
     "//net",
@@ -63,9 +63,9 @@
     ":test_support",
     "//ash/components/cryptohome",
     "//base/test:test_support",
+    "//chromeos/ash/components/dbus/attestation",
+    "//chromeos/ash/components/dbus/attestation:attestation_proto",
     "//chromeos/dbus:test_support",
-    "//chromeos/dbus/attestation",
-    "//chromeos/dbus/attestation:attestation_proto",
     "//components/account_id",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/ash/components/attestation/DEPS b/ash/components/attestation/DEPS
index a3fb233..7781e55 100644
--- a/ash/components/attestation/DEPS
+++ b/ash/components/attestation/DEPS
@@ -3,6 +3,7 @@
 include_rules = [
   "+ash/components/cryptohome",
   "+base",
+  "+chromeos/ash/components/dbus/attestation",
   "+chromeos/dbus",
   "+components/account_id",
   "+crypto",
diff --git a/ash/components/attestation/attestation_flow.cc b/ash/components/attestation/attestation_flow.cc
index ec65ff2..1ab6601 100644
--- a/ash/components/attestation/attestation_flow.cc
+++ b/ash/components/attestation/attestation_flow.cc
@@ -15,8 +15,8 @@
 #include "base/memory/ptr_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/timer/timer.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "components/account_id/account_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/ash/components/attestation/attestation_flow.h b/ash/components/attestation/attestation_flow.h
index 1fce7e2..3355e28 100644
--- a/ash/components/attestation/attestation_flow.h
+++ b/ash/components/attestation/attestation_flow.h
@@ -13,9 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-// TODO(https://crbug.com/1164001): forward declare after it moved to ash.
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/common/dbus_method_call_status.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
@@ -23,6 +21,9 @@
 class AccountId;
 
 namespace ash {
+
+class AttestationClient;
+
 namespace attestation {
 
 // Interface for access to the Privacy CA server.
diff --git a/ash/components/attestation/attestation_flow_adaptive.h b/ash/components/attestation/attestation_flow_adaptive.h
index 2ea08d8..dda8f78 100644
--- a/ash/components/attestation/attestation_flow_adaptive.h
+++ b/ash/components/attestation/attestation_flow_adaptive.h
@@ -14,7 +14,7 @@
 #include "ash/components/attestation/attestation_flow_type_decider.h"
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "components/account_id/account_id.h"
 
diff --git a/ash/components/attestation/attestation_flow_factory.h b/ash/components/attestation/attestation_flow_factory.h
index 1ba9ae24..ab1ef17 100644
--- a/ash/components/attestation/attestation_flow_factory.h
+++ b/ash/components/attestation/attestation_flow_factory.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/component_export.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 
 namespace ash {
 namespace attestation {
diff --git a/ash/components/attestation/attestation_flow_integrated.cc b/ash/components/attestation/attestation_flow_integrated.cc
index 8a99b61d..15e5207 100644
--- a/ash/components/attestation/attestation_flow_integrated.cc
+++ b/ash/components/attestation/attestation_flow_integrated.cc
@@ -16,8 +16,8 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/timer/timer.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/dbus_switches.h"
 #include "components/account_id/account_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/ash/components/attestation/attestation_flow_integrated.h b/ash/components/attestation/attestation_flow_integrated.h
index 7a1d509f..5ac9cb0b 100644
--- a/ash/components/attestation/attestation_flow_integrated.h
+++ b/ash/components/attestation/attestation_flow_integrated.h
@@ -14,9 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-// TODO(https://crbug.com/1164001): forward declare after it moved to ash.
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/common/dbus_method_call_status.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
@@ -24,6 +22,9 @@
 class AccountId;
 
 namespace ash {
+
+class AttestationClient;
+
 namespace attestation {
 
 // Implements the message flow for Chrome OS attestation tasks by checking the
diff --git a/ash/components/attestation/attestation_flow_integrated_unittest.cc b/ash/components/attestation/attestation_flow_integrated_unittest.cc
index 74cddfba..f4d6ed6e 100644
--- a/ash/components/attestation/attestation_flow_integrated_unittest.cc
+++ b/ash/components/attestation/attestation_flow_integrated_unittest.cc
@@ -20,8 +20,8 @@
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "base/timer/timer.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "chromeos/dbus/constants/dbus_switches.h"
 #include "components/account_id/account_id.h"
@@ -42,12 +42,8 @@
 
 class AttestationFlowIntegratedTest : public testing::Test {
  public:
-  AttestationFlowIntegratedTest() {
-    chromeos::AttestationClient::InitializeFake();
-  }
-  ~AttestationFlowIntegratedTest() override {
-    chromeos::AttestationClient::Shutdown();
-  }
+  AttestationFlowIntegratedTest() { AttestationClient::InitializeFake(); }
+  ~AttestationFlowIntegratedTest() override { AttestationClient::Shutdown(); }
   void QuitRunLoopCertificateCallback(
       AttestationFlowIntegrated::CertificateCallback callback,
       AttestationStatus status,
@@ -68,9 +64,8 @@
                                    request.certificate_profile()),
                                request.request_origin()));
     }
-    chromeos::AttestationClient::Get()
-        ->GetTestInterface()
-        ->AllowlistCertificateRequest(request);
+    AttestationClient::Get()->GetTestInterface()->AllowlistCertificateRequest(
+        request);
   }
   void Run() {
     base::RunLoop run_loop;
@@ -84,9 +79,8 @@
 };
 
 TEST_F(AttestationFlowIntegratedTest, GetCertificate) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -137,9 +131,8 @@
 // is created by the factory function to make sure that the factory function
 // instantiates an object of the intended type.
 TEST_F(AttestationFlowIntegratedTest, GetCertificateCreatedByFactory) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -192,9 +185,8 @@
 }
 
 TEST_F(AttestationFlowIntegratedTest, GetCertificateFailed) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -225,9 +217,8 @@
 }
 
 TEST_F(AttestationFlowIntegratedTest, GetCertificateFailedInvalidProfile) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -255,7 +246,7 @@
 }
 
 TEST_F(AttestationFlowIntegratedTest, GetCertificateAttestationNotPrepared) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->ConfigureEnrollmentPreparationsSequence({false, true});
 
@@ -290,9 +281,8 @@
 }
 
 TEST_F(AttestationFlowIntegratedTest, GetCertificateAttestationNeverPrepared) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(false);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      false);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -324,9 +314,8 @@
 }
 
 TEST_F(AttestationFlowIntegratedTest, GetCertificateAttestationTestAca) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -361,9 +350,8 @@
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   command_line->AppendSwitchASCII(chromeos::switches::kAttestationServer,
                                   "test");
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -395,9 +383,8 @@
 }
 
 TEST_F(AttestationFlowIntegratedTest, GetMachineCertificate) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -433,9 +420,8 @@
 // TODO(b/179364923): Develop a better API design along with strict assertion
 // instead of silently removing the username.
 TEST_F(AttestationFlowIntegratedTest, GetMachineCertificateWithAccountId) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
@@ -467,9 +453,8 @@
 
 TEST_F(AttestationFlowIntegratedTest,
        GetCertificateAttestationKeyNameFromProfile) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   ::attestation::GetCertificateRequest request;
   request.set_certificate_profile(
diff --git a/ash/components/attestation/attestation_flow_unittest.cc b/ash/components/attestation/attestation_flow_unittest.cc
index 3ae217a..989e8ba 100644
--- a/ash/components/attestation/attestation_flow_unittest.cc
+++ b/ash/components/attestation/attestation_flow_unittest.cc
@@ -18,7 +18,7 @@
 #include "base/test/task_environment.h"
 #include "base/time/tick_clock.h"
 #include "base/timer/timer.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "components/account_id/account_id.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -44,8 +44,8 @@
 
 class AttestationFlowTest : public testing::Test {
  public:
-  AttestationFlowTest() { chromeos::AttestationClient::InitializeFake(); }
-  ~AttestationFlowTest() override { chromeos::AttestationClient::Shutdown(); }
+  AttestationFlowTest() { AttestationClient::InitializeFake(); }
+  ~AttestationFlowTest() override { AttestationClient::Shutdown(); }
   void QuitRunLoopCertificateCallback(
       AttestationFlow::CertificateCallback callback,
       AttestationStatus status,
@@ -79,13 +79,12 @@
 
   // Set the enrollment status as `false` so the full enrollment flow is
   // triggered.
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   // Use StrictMock when we want to verify invocation frequency.
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
@@ -102,7 +101,7 @@
 
   const AccountId account_id = AccountId::FromUserEmail(kFakeUserEmail);
 
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           kFakeUserEmail, "fake_origin",
@@ -156,13 +155,12 @@
 
   // Set the enrollment status as `false` so the full enrollment flow is
   // triggered.
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   // Use StrictMock when we want to verify invocation frequency.
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
@@ -179,7 +177,7 @@
 
   const AccountId account_id = AccountId::FromUserEmail(kFakeUserEmail);
 
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           kFakeUserEmail, "fake_origin",
@@ -233,13 +231,12 @@
 
   // Set the enrollment status as `false` so the full enrollment flow is
   // triggered.
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   // Use StrictMock when we want to verify invocation frequency.
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
@@ -256,7 +253,7 @@
 
   const AccountId account_id = AccountId::FromUserEmail(kFakeUserEmail);
 
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           kFakeUserEmail, "fake_origin",
@@ -309,19 +306,17 @@
 
   // Set the enrollment status as `false` so the full enrollment flow is
   // triggered.
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   // Set the ACA type to test ACA so we can make sure the enroll request and the
   // certificate request has the right ACA type.
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->set_aca_type_for_legacy_flow(::attestation::TEST_ACA);
+  AttestationClient::Get()->GetTestInterface()->set_aca_type_for_legacy_flow(
+      ::attestation::TEST_ACA);
 
   // Use StrictMock when we want to verify invocation frequency.
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
@@ -340,7 +335,7 @@
 
   const AccountId account_id = AccountId::FromUserEmail(kFakeUserEmail);
 
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           kFakeUserEmail, "fake_origin",
@@ -389,11 +384,11 @@
   // Verify the order of calls in a sequence.
   Sequence flow_order;
 
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->ConfigureEnrollmentPreparationsSequence({false, true});
 
@@ -412,7 +407,7 @@
 
   const AccountId account_id = AccountId::FromUserEmail(kFakeUserEmail);
 
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           kFakeUserEmail, "fake_origin",
@@ -463,13 +458,12 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_Attestation_Never_Prepared) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(false);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      false);
 
   // We're not expecting any server calls in this case; StrictMock will verify.
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
@@ -497,11 +491,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_Attestation_Never_Confirm_Prepared) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->ConfigureEnrollmentPreparationsStatus(
           ::attestation::STATUS_NOT_AVAILABLE);
@@ -534,13 +528,12 @@
 TEST_F(AttestationFlowTest, GetCertificate_NoEK) {
   AttestationClient::Get()->GetTestInterface()->set_enroll_request_status(
       ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   // We're not expecting any server calls in this case; StrictMock will verify.
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
@@ -562,13 +555,12 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_EKRejected) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
   proxy->DeferToFake(false);
@@ -595,13 +587,12 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_FailEnroll) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(false);
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(true);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      true);
 
   std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
   proxy->DeferToFake(true);
@@ -631,11 +622,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetMachineCertificateAlreadyEnrolled) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           /*username=*/"", /*request_origin=*/"",
@@ -686,11 +677,11 @@
 // TODO(b/179364923): Develop a better API design along with strict assertion
 // instead of silently removing the username.
 TEST_F(AttestationFlowTest, GetMachineCertificateWithUsername) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           /*username=*/"", /*request_origin=*/"",
@@ -739,11 +730,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetEnrollmentCertificateAlreadyEnrolled) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           /*username=*/"", /*request_origin=*/"",
@@ -790,11 +781,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_FailCreateCertRequest) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           kFakeUserEmail, "fake_origin",
@@ -821,11 +812,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_CertRequestRejected) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           /*username=*/"", /*request_origin=*/"",
@@ -858,11 +849,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_CertRequestBadRequest) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           /*username=*/"", /*request_origin=*/"",
@@ -900,7 +891,7 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_FailIsEnrolled) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_status(::attestation::STATUS_DBUS_ERROR);
@@ -925,11 +916,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_CheckExisting) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistLegacyCreateCertificateRequest(
           /*username=*/"", /*request_origin=*/"",
@@ -975,11 +966,11 @@
 }
 
 TEST_F(AttestationFlowTest, GetCertificate_AlreadyExists) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->GetMutableKeyInfoReply("", kEnterpriseUserKey)
       ->set_certificate("fake_cert");
@@ -1009,11 +1000,11 @@
 // TODO(b/179364923): Develop a better API design along with strict assertion
 // instead of silently removing the username.
 TEST_F(AttestationFlowTest, GetCertificate_LookupMachineKeyWithAccountId) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->mutable_status_reply()
       ->set_enrolled(true);
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->GetMutableKeyInfoReply("", kEnterpriseMachineKey)
       ->set_certificate("fake_cert");
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index da25f47..526d7fbd 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -134,6 +134,11 @@
 const base::Feature kArcAdbSideloadingFeature{
     "ArcAdbSideloading", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Controls whether files shared from ARC apps to Web Apps should be shared
+// through the FuseBox service.
+const base::Feature kArcFuseBoxFileSharing{"ArcFuseBoxFileSharing",
+                                           base::FEATURE_ENABLED_BY_DEFAULT};
+
 // Controls whether to enable support for ARC Input Overlay.
 const base::Feature kArcInputOverlay{"ArcInputOverlay",
                                      base::FEATURE_DISABLED_BY_DEFAULT};
@@ -1697,6 +1702,11 @@
   return base::FeatureList::IsEnabled(kOsSettingsAppNotificationsPage);
 }
 
+bool IsArcFuseBoxFileSharingEnabled() {
+  return IsFileManagerFuseBoxEnabled() &&
+         base::FeatureList::IsEnabled(kArcFuseBoxFileSharing);
+}
+
 bool IsArcInputOverlayEnabled() {
   return base::FeatureList::IsEnabled(kArcInputOverlay);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index c3a72d1..cb63c61 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -68,6 +68,8 @@
 extern const base::Feature kArcAccountRestrictions;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kArcAdbSideloadingFeature;
+COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const base::Feature kArcFuseBoxFileSharing;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kArcInputOverlay;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kArcAndGuestOsFileTasksUseAppService;
@@ -656,6 +658,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAmbientModeEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAmbientModePhotoPreviewEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAppNotificationsPageEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsArcFuseBoxFileSharingEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsArcInputOverlayEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsArcNetworkDiagnosticsButtonEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAssistantNativeIconsEnabled();
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller.h b/ash/public/cpp/wallpaper/wallpaper_controller.h
index f6d12c1..2004e73 100644
--- a/ash/public/cpp/wallpaper/wallpaper_controller.h
+++ b/ash/public/cpp/wallpaper/wallpaper_controller.h
@@ -86,7 +86,8 @@
                                   const std::string& file_name,
                                   WallpaperLayout layout,
                                   const gfx::ImageSkia& image,
-                                  bool preview_mode) = 0;
+                                  bool preview_mode,
+                                  const std::string& file_path) = 0;
 
   // Sets the wallpaper at |params.asset_id|, |params.url| and
   // |params.collection_id| as the active wallpaper for the user at
diff --git a/ash/public/cpp/wallpaper/wallpaper_info.cc b/ash/public/cpp/wallpaper/wallpaper_info.cc
index 8dc0ac025..7bcc62a 100644
--- a/ash/public/cpp/wallpaper/wallpaper_info.cc
+++ b/ash/public/cpp/wallpaper/wallpaper_info.cc
@@ -46,8 +46,13 @@
 WallpaperInfo::WallpaperInfo(const std::string& in_location,
                              WallpaperLayout in_layout,
                              WallpaperType in_type,
-                             const base::Time& in_date)
-    : location(in_location), layout(in_layout), type(in_type), date(in_date) {}
+                             const base::Time& in_date,
+                             const std::string& in_user_file_path)
+    : location(in_location),
+      user_file_path(in_user_file_path),
+      layout(in_layout),
+      type(in_type),
+      date(in_date) {}
 
 WallpaperInfo::WallpaperInfo(const WallpaperInfo& other) = default;
 WallpaperInfo& WallpaperInfo::operator=(const WallpaperInfo& other) = default;
@@ -71,6 +76,9 @@
       return location == other.location && layout == other.layout &&
              collection_id == other.collection_id;
     case WallpaperType::kCustomized:
+      return type == other.type && layout == other.layout &&
+             location == other.location &&
+             user_file_path == other.user_file_path;
     case WallpaperType::kDefault:
     case WallpaperType::kPolicy:
     case WallpaperType::kThirdParty:
@@ -91,6 +99,7 @@
 std::ostream& operator<<(std::ostream& os, const WallpaperInfo& info) {
   os << "WallpaperInfo:" << std::endl;
   os << "  location: " << info.location << std::endl;
+  os << "  user_file_path: " << info.user_file_path << std::endl;
   os << "  layout: " << info.layout << std::endl;
   os << "  type: " << static_cast<int>(info.type) << std::endl;
   os << "  date: " << info.date << std::endl;
diff --git a/ash/public/cpp/wallpaper/wallpaper_info.h b/ash/public/cpp/wallpaper/wallpaper_info.h
index 650cd91..0c7368d 100644
--- a/ash/public/cpp/wallpaper/wallpaper_info.h
+++ b/ash/public/cpp/wallpaper/wallpaper_info.h
@@ -28,7 +28,8 @@
   WallpaperInfo(const std::string& in_location,
                 WallpaperLayout in_layout,
                 WallpaperType in_type,
-                const base::Time& in_date);
+                const base::Time& in_date,
+                const std::string& in_user_file_path = "");
 
   WallpaperInfo(const WallpaperInfo& other);
   WallpaperInfo& operator=(const WallpaperInfo& other);
@@ -46,6 +47,11 @@
   // (corresponding to user wallpaper_files_id), online wallpaper URL, or
   // Google Photos id.
   std::string location;
+  // user_file_path is the full path of the wallpaper file and is used as
+  // the new CurrentWallpaper key. This field is required as the old key which
+  // was set to the filename part made the UI mistakenly highlight multiple
+  // files with the same name as the currently set wallpaper (b/229420564).
+  std::string user_file_path;
   WallpaperLayout layout;
   WallpaperType type;
   base::Time date;
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc
index 7b93cc25..ef4230ee 100644
--- a/ash/wallpaper/wallpaper_controller_impl.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -1023,7 +1023,8 @@
                                                  const std::string& file_name,
                                                  WallpaperLayout layout,
                                                  const gfx::ImageSkia& image,
-                                                 bool preview_mode) {
+                                                 bool preview_mode,
+                                                 const std::string& file_path) {
   DCHECK(Shell::Get()->session_controller()->IsActiveUserSessionStarted());
   if (!CanSetUserWallpaper(account_id))
     return;
@@ -1034,19 +1035,19 @@
     confirm_preview_wallpaper_callback_ =
         base::BindOnce(&WallpaperControllerImpl::SaveAndSetWallpaper,
                        weak_factory_.GetWeakPtr(), account_id, file_name,
-                       WallpaperType::kCustomized, layout,
+                       file_path, WallpaperType::kCustomized, layout,
                        /*show_wallpaper=*/false, image);
     reload_preview_wallpaper_callback_ = base::BindRepeating(
         &WallpaperControllerImpl::ShowWallpaperImage,
         weak_factory_.GetWeakPtr(), image,
         WallpaperInfo{/*in_location=*/std::string(), layout,
-                      WallpaperType::kCustomized, base::Time::Now()},
+                      WallpaperType::kCustomized, base::Time::Now(), file_path},
         /*preview_mode=*/true, /*always_on_top=*/false);
     // Show the preview wallpaper.
     reload_preview_wallpaper_callback_.Run();
   } else {
     SaveAndSetWallpaperWithCompletion(
-        account_id, file_name, WallpaperType::kCustomized, layout,
+        account_id, file_name, file_path, WallpaperType::kCustomized, layout,
         /*show_wallpaper=*/is_active_user, image,
         base::BindOnce(
             &WallpaperControllerImpl::SaveWallpaperToDriveFsAndSyncInfo,
@@ -1300,8 +1301,8 @@
   const bool show_wallpaper = IsActiveUser(account_id);
   image_util::DecodeImageCallback callback = base::BindOnce(
       &WallpaperControllerImpl::SaveAndSetWallpaper, weak_factory_.GetWeakPtr(),
-      account_id, kPolicyWallpaperFile, WallpaperType::kPolicy,
-      WALLPAPER_LAYOUT_CENTER_CROPPED, show_wallpaper);
+      account_id, kPolicyWallpaperFile, /*file_path=*/"",
+      WallpaperType::kPolicy, WALLPAPER_LAYOUT_CENTER_CROPPED, show_wallpaper);
 
   if (bypass_decode_for_testing_) {
     std::move(callback).Run(CreateSolidColorWallpaper(kDefaultWallpaperColor));
@@ -1337,8 +1338,9 @@
   bool allowed_to_show_wallpaper = IsActiveUser(account_id);
 
   if (allowed_to_set_wallpaper) {
-    SaveAndSetWallpaper(account_id, file_name, WallpaperType::kCustomized,
-                        layout, allowed_to_show_wallpaper, image);
+    SaveAndSetWallpaper(account_id, file_name, /*file_path=*/"",
+                        WallpaperType::kCustomized, layout,
+                        allowed_to_show_wallpaper, image);
   }
   return allowed_to_set_wallpaper && allowed_to_show_wallpaper;
 }
@@ -2498,17 +2500,20 @@
 
 void WallpaperControllerImpl::SaveAndSetWallpaper(const AccountId& account_id,
                                                   const std::string& file_name,
+                                                  const std::string& file_path,
                                                   WallpaperType type,
                                                   WallpaperLayout layout,
                                                   bool show_wallpaper,
                                                   const gfx::ImageSkia& image) {
-  SaveAndSetWallpaperWithCompletion(account_id, file_name, type, layout,
-                                    show_wallpaper, image, base::DoNothing());
+  SaveAndSetWallpaperWithCompletion(account_id, file_name, file_path, type,
+                                    layout, show_wallpaper, image,
+                                    base::DoNothing());
 }
 
 void WallpaperControllerImpl::SaveAndSetWallpaperWithCompletion(
     const AccountId& account_id,
     const std::string& file_name,
+    const std::string& file_path,
     WallpaperType type,
     WallpaperLayout layout,
     bool show_wallpaper,
@@ -2519,14 +2524,15 @@
         account_id,
         base::BindOnce(
             &WallpaperControllerImpl::SaveAndSetWallpaperWithCompletionFilesId,
-            weak_factory_.GetWeakPtr(), account_id, file_name, type, layout,
-            show_wallpaper, image, std::move(image_saved_callback)));
+            weak_factory_.GetWeakPtr(), account_id, file_name, file_path, type,
+            layout, show_wallpaper, image, std::move(image_saved_callback)));
   }
 }
 
 void WallpaperControllerImpl::SaveAndSetWallpaperWithCompletionFilesId(
     const AccountId& account_id,
     const std::string& file_name,
+    const std::string& file_path,
     WallpaperType type,
     WallpaperLayout layout,
     bool show_wallpaper,
@@ -2545,7 +2551,8 @@
       base::FilePath(wallpaper_files_id).Append(file_name).value();
   // User's custom wallpaper path is determined by relative path and the
   // appropriate wallpaper resolution.
-  WallpaperInfo info = {relative_path, layout, type, base::Time::Now()};
+  WallpaperInfo info = {relative_path, layout, type, base::Time::Now(),
+                        file_path};
   if (!SetUserWallpaperInfo(account_id, info)) {
     LOG(ERROR) << "Setting user wallpaper info fails. This should never happen "
                   "except in tests.";
@@ -2599,7 +2606,7 @@
   std::move(callback).Run(success);
   if (success) {
     SetCustomWallpaper(account_id, path.BaseName().value(), layout, image,
-                       preview_mode);
+                       preview_mode, path.value());
   }
 }
 
@@ -3196,10 +3203,11 @@
   }
   base::FilePath path_in_prefs = base::FilePath(info.location);
   std::string file_name = path_in_prefs.BaseName().value();
+  std::string file_path = info.user_file_path;
   ReadAndDecodeWallpaper(
       base::BindOnce(&WallpaperControllerImpl::SaveAndSetWallpaper,
                      weak_factory_.GetWeakPtr(), account_id, file_name,
-                     WallpaperType::kCustomized, info.layout,
+                     file_path, WallpaperType::kCustomized, info.layout,
                      /*show_wallpaper=*/true),
       drivefs_path);
 }
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h
index 3ca083a..398cf03 100644
--- a/ash/wallpaper/wallpaper_controller_impl.h
+++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -239,7 +239,8 @@
                           const std::string& file_name,
                           WallpaperLayout layout,
                           const gfx::ImageSkia& image,
-                          bool preview_mode) override;
+                          bool preview_mode,
+                          const std::string& file_path = "") override;
   void SetOnlineWallpaper(const OnlineWallpaperParams& params,
                           SetWallpaperCallback callback) override;
   void SetOnlineWallpaperIfExists(const OnlineWallpaperParams& params,
@@ -546,6 +547,7 @@
   // updates the cache.
   void SaveAndSetWallpaper(const AccountId& account_id,
                            const std::string& file_name,
+                           const std::string& file_path,
                            WallpaperType type,
                            WallpaperLayout layout,
                            bool show_wallpaper,
@@ -555,6 +557,7 @@
   void SaveAndSetWallpaperWithCompletion(
       const AccountId& account_id,
       const std::string& file_name,
+      const std::string& file_path,
       WallpaperType type,
       WallpaperLayout layout,
       bool show_wallpaper,
@@ -564,6 +567,7 @@
   void SaveAndSetWallpaperWithCompletionFilesId(
       const AccountId& account_id,
       const std::string& file_name,
+      const std::string& file_path,
       WallpaperType type,
       WallpaperLayout layout,
       bool show_wallpaper,
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index bfcbdd2..ca549a5 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -307,6 +307,9 @@
       base::NumberToString(info.date.ToInternalValue()));
   wallpaper_info_dict.SetStringKey(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, info.location);
+  wallpaper_info_dict.SetStringKey(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      info.user_file_path);
   wallpaper_info_dict.SetIntKey(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName, info.layout);
   wallpaper_info_dict.SetIntKey(WallpaperPrefManager::kNewWallpaperTypeNodeName,
@@ -3419,6 +3422,9 @@
           base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()));
   wallpaper_info_dict.SetStringPath(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, "location");
+  wallpaper_info_dict.SetStringPath(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      "user_file_path");
   wallpaper_info_dict.SetIntPath(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName,
       WallpaperLayout::WALLPAPER_LAYOUT_CENTER);
diff --git a/ash/wallpaper/wallpaper_pref_manager.cc b/ash/wallpaper/wallpaper_pref_manager.cc
index 9facb8c..ac0ccf4 100644
--- a/ash/wallpaper/wallpaper_pref_manager.cc
+++ b/ash/wallpaper/wallpaper_pref_manager.cc
@@ -120,6 +120,8 @@
   // Use temporary variables to keep |info| untouched in the error case.
   const std::string* location = info_dict->FindStringPath(
       WallpaperPrefManager::kNewWallpaperLocationNodeName);
+  const std::string* file_path = info_dict->FindStringPath(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName);
   absl::optional<int> layout =
       info_dict->FindIntPath(WallpaperPrefManager::kNewWallpaperLayoutNodeName);
   absl::optional<int> type =
@@ -146,6 +148,9 @@
     return false;
 
   info->location = *location;
+  // The old wallpaper didn't include file path information. For migration,
+  // check whether file_path is a null pointer before setting user_file_path.
+  info->user_file_path = file_path ? *file_path : "";
   info->layout = static_cast<WallpaperLayout>(layout.value());
   // TODO(skau): Switch to TimeFromValue
   info->date =
@@ -209,6 +214,9 @@
   }
   wallpaper_info_dict.SetStringPath(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, info.location);
+  wallpaper_info_dict.SetStringPath(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      info.user_file_path);
   wallpaper_info_dict.SetIntPath(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName, info.layout);
   wallpaper_info_dict.SetIntPath(
@@ -545,6 +553,8 @@
 const char WallpaperPrefManager::kNewWallpaperDedupKeyNodeName[] = "dedup_key";
 const char WallpaperPrefManager::kNewWallpaperLayoutNodeName[] = "layout";
 const char WallpaperPrefManager::kNewWallpaperLocationNodeName[] = "file";
+const char WallpaperPrefManager::kNewWallpaperUserFilePathNodeName[] =
+    "file_path";
 const char WallpaperPrefManager::kNewWallpaperTypeNodeName[] = "type";
 const char WallpaperPrefManager::kNewWallpaperUnitIdNodeName[] = "unit_id";
 const char WallpaperPrefManager::kNewWallpaperVariantListNodeName[] =
diff --git a/ash/wallpaper/wallpaper_pref_manager.h b/ash/wallpaper/wallpaper_pref_manager.h
index c6b2fb54..1a3cf54 100644
--- a/ash/wallpaper/wallpaper_pref_manager.h
+++ b/ash/wallpaper/wallpaper_pref_manager.h
@@ -63,6 +63,7 @@
   static const char kNewWallpaperDedupKeyNodeName[];
   static const char kNewWallpaperLayoutNodeName[];
   static const char kNewWallpaperLocationNodeName[];
+  static const char kNewWallpaperUserFilePathNodeName[];
   static const char kNewWallpaperTypeNodeName[];
   static const char kNewWallpaperUnitIdNodeName[];
   static const char kNewWallpaperVariantListNodeName[];
diff --git a/ash/wallpaper/wallpaper_pref_manager_unittest.cc b/ash/wallpaper/wallpaper_pref_manager_unittest.cc
index 6517ef1..15870a6 100644
--- a/ash/wallpaper/wallpaper_pref_manager_unittest.cc
+++ b/ash/wallpaper/wallpaper_pref_manager_unittest.cc
@@ -77,6 +77,9 @@
       base::NumberToString(info.date.ToInternalValue()));
   wallpaper_info_dict.SetStringKey(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, info.location);
+  wallpaper_info_dict.SetStringKey(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      info.user_file_path);
   wallpaper_info_dict.SetIntKey(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName, info.layout);
   wallpaper_info_dict.SetIntKey(WallpaperPrefManager::kNewWallpaperTypeNodeName,
diff --git a/ash/webui/camera_app_ui/resources/utils/cca.py b/ash/webui/camera_app_ui/resources/utils/cca.py
index 894bd326..f60e357 100755
--- a/ash/webui/camera_app_ui/resources/utils/cca.py
+++ b/ash/webui/camera_app_ui/resources/utils/cca.py
@@ -151,6 +151,8 @@
         'typescript/bin/tsc',
         '--outDir',
         js_out_dir,
+        '--noEmit',
+        'false',
         # Makes compilation faster
         '--incremental',
         # For better debugging experience on DUT.
diff --git a/ash/webui/help_app_ui/help_app_ui.cc b/ash/webui/help_app_ui/help_app_ui.cc
index cade9ab..ad85164 100644
--- a/ash/webui/help_app_ui/help_app_ui.cc
+++ b/ash/webui/help_app_ui/help_app_ui.cc
@@ -111,13 +111,15 @@
 }
 
 void HelpAppUI::BindInterface(
-    mojo::PendingReceiver<local_search_service::mojom::Index> index_receiver) {
+    mojo::PendingReceiver<chromeos::local_search_service::mojom::Index>
+        index_receiver) {
   if (base::FeatureList::IsEnabled(features::kEnableLocalSearchService)) {
-    auto* const factory = local_search_service::LocalSearchServiceProxyFactory::
-        GetForBrowserContext(web_ui()->GetWebContents()->GetBrowserContext());
+    auto* const factory = chromeos::local_search_service::
+        LocalSearchServiceProxyFactory::GetForBrowserContext(
+            web_ui()->GetWebContents()->GetBrowserContext());
     factory->SetLocalState(delegate_->GetLocalState());
-    factory->GetIndex(local_search_service::IndexId::kHelpApp,
-                      local_search_service::Backend::kInvertedIndex,
+    factory->GetIndex(chromeos::local_search_service::IndexId::kHelpApp,
+                      chromeos::local_search_service::Backend::kInvertedIndex,
                       std::move(index_receiver));
   }
 }
diff --git a/ash/webui/help_app_ui/help_app_ui.h b/ash/webui/help_app_ui/help_app_ui.h
index f7a7e70e..c673a3c 100644
--- a/ash/webui/help_app_ui/help_app_ui.h
+++ b/ash/webui/help_app_ui/help_app_ui.h
@@ -33,7 +33,8 @@
       mojo::PendingReceiver<help_app::mojom::PageHandlerFactory> receiver);
 
   void BindInterface(
-      mojo::PendingReceiver<local_search_service::mojom::Index> index_receiver);
+      mojo::PendingReceiver<chromeos::local_search_service::mojom::Index>
+          index_receiver);
 
   // The search handler is used to update the search index for launcher search.
   void BindInterface(
diff --git a/ash/webui/help_app_ui/resources/browser_proxy.js b/ash/webui/help_app_ui/resources/browser_proxy.js
index 7e3ed74b..5a385eb 100644
--- a/ash/webui/help_app_ui/resources/browser_proxy.js
+++ b/ash/webui/help_app_ui/resources/browser_proxy.js
@@ -20,8 +20,8 @@
     help_app.handler.$.bindNewPipeAndPassReceiver());
 
 // Set up an index remote to talk to Local Search Service.
-/** @type {!ash.localSearchService.mojom.IndexRemote} */
-const indexRemote = ash.localSearchService.mojom.Index.getRemote();
+/** @type {!chromeos.localSearchService.mojom.IndexRemote} */
+const indexRemote = chromeos.localSearchService.mojom.Index.getRemote();
 
 /**
  * Talks to the search handler. Use for updating the content for launcher
@@ -89,7 +89,7 @@
       const data_from_app =
           /** @type {!Array<!helpApp.SearchableItem>} */ (message);
       const data_to_send = data_from_app.map(searchable_item => {
-        /** @type {!Array<!ash.localSearchService.mojom.Content>} */
+        /** @type {!Array<!chromeos.localSearchService.mojom.Content>} */
         const contents = [
           {
             id: TITLE_ID,
@@ -157,15 +157,15 @@
       // Record the search status in the trusted frame.
       chrome.metricsPrivate.recordEnumerationValue(
           'Discover.Search.SearchStatus', response.status,
-          ash.localSearchService.mojom.ResponseStatus.MAX_VALUE);
+          chromeos.localSearchService.mojom.ResponseStatus.MAX_VALUE);
 
       if (response.status !==
-              ash.localSearchService.mojom.ResponseStatus.kSuccess ||
+              chromeos.localSearchService.mojom.ResponseStatus.kSuccess ||
           !response.results) {
         return {results: null};
       }
       const search_results =
-          /** @type {!Array<!ash.localSearchService.mojom.Result>} */ (
+          /** @type {!Array<!chromeos.localSearchService.mojom.Result>} */ (
               response.results);
       // Sort results by decreasing score.
       search_results.sort((a, b) => b.score - a.score);
diff --git a/ash/webui/help_app_ui/search/search_handler.h b/ash/webui/help_app_ui/search/search_handler.h
index fadd0ca7..f76d43e 100644
--- a/ash/webui/help_app_ui/search/search_handler.h
+++ b/ash/webui/help_app_ui/search/search_handler.h
@@ -72,7 +72,7 @@
       const local_search_service::Result& result) const;
 
   SearchTagRegistry* search_tag_registry_;
-  mojo::Remote<local_search_service::mojom::Index> index_remote_;
+  mojo::Remote<chromeos::local_search_service::mojom::Index> index_remote_;
 
   // Whether or not the first Update has finished yet, which means the Search
   // Handler is ready to search.
diff --git a/ash/webui/help_app_ui/search/search_tag_registry.h b/ash/webui/help_app_ui/search/search_tag_registry.h
index 3b84b11..020964c6 100644
--- a/ash/webui/help_app_ui/search/search_tag_registry.h
+++ b/ash/webui/help_app_ui/search/search_tag_registry.h
@@ -59,7 +59,7 @@
   void NotifyRegistryAdded();
 
   // Index used by the LocalSearchService for string matching.
-  mojo::Remote<local_search_service::mojom::Index> index_remote_;
+  mojo::Remote<chromeos::local_search_service::mojom::Index> index_remote_;
 
   // In-memory cache of all results which have been added to the
   // LocalSearchService. Contents are kept in sync with |index_remote_|.
diff --git a/ash/webui/help_app_ui/search/search_tag_registry_unittest.cc b/ash/webui/help_app_ui/search/search_tag_registry_unittest.cc
index b17b079e..f104506 100644
--- a/ash/webui/help_app_ui/search/search_tag_registry_unittest.cc
+++ b/ash/webui/help_app_ui/search/search_tag_registry_unittest.cc
@@ -10,8 +10,15 @@
 #include "chromeos/ash/components/local_search_service/public/mojom/index.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::help_app {
+namespace ash {
 
+// TODO(https://crbug.com/1164001): Remove if local_service_service::mojom
+// moved to ash.
+namespace local_search_service {
+namespace mojom = ::chromeos::local_search_service::mojom;
+}  // namespace local_search_service
+
+namespace help_app {
 namespace {
 
 class FakeObserver : public SearchTagRegistry::Observer {
@@ -179,4 +186,5 @@
   EXPECT_EQ(result.title, u"Title 3");
 }
 
-}  // namespace ash::help_app
+}  // namespace help_app
+}  // namespace ash
diff --git a/ash/webui/personalization_app/resources/BUILD.gn b/ash/webui/personalization_app/resources/BUILD.gn
index 2af6772..0dcb0a2 100644
--- a/ash/webui/personalization_app/resources/BUILD.gn
+++ b/ash/webui/personalization_app/resources/BUILD.gn
@@ -113,7 +113,6 @@
   "trusted/wallpaper/wallpaper_subpage_element.ts",
 
   "untrusted/collections_grid.ts",
-  "untrusted/images_grid.ts",
 ]
 
 # Files that are passed as input to html_to_wrapper().
diff --git a/ash/webui/personalization_app/resources/common/constants.ts b/ash/webui/personalization_app/resources/common/constants.ts
index b71a25d6..783e204 100644
--- a/ash/webui/personalization_app/resources/common/constants.ts
+++ b/ash/webui/personalization_app/resources/common/constants.ts
@@ -30,13 +30,8 @@
   SELECT_GOOGLE_PHOTOS_COLLECTION = 'select_google_photos_collection',
   SELECT_LOCAL_COLLECTION = 'select_local_collection',
   SEND_IMAGE_COUNTS = 'send_image_counts',
-  SEND_IMAGE_TILES = 'send_image_tiles',
   SEND_LOCAL_IMAGE_DATA = 'send_local_image_data',
   SEND_LOCAL_IMAGES = 'send_local_images',
-  SEND_CURRENT_WALLPAPER_ASSET_ID = 'send_current_wallpaper_asset_id',
-  SEND_PENDING_WALLPAPER_ASSET_ID = 'send_pending_wallpaper_asset_id',
-  SELECT_IMAGE = 'select_image',
-  SELECT_LOCAL_IMAGE = 'select_local_image',
   SEND_VISIBLE = 'send_visible',
 }
 
@@ -78,11 +73,6 @@
   unitId?: bigint, preview: Url[],
 };
 
-export type SendImageTilesEvent = {
-  type: EventType.SEND_IMAGE_TILES,
-  tiles: ImageTile[],
-};
-
 export type SendLocalImagesEvent = {
   type: EventType.SEND_LOCAL_IMAGES,
   images: Array<FilePath|DefaultImageSymbol>,
@@ -96,21 +86,6 @@
   data: Record<string|DefaultImageSymbol, string>,
 };
 
-export type SendCurrentWallpaperAssetIdEvent = {
-  type: EventType.SEND_CURRENT_WALLPAPER_ASSET_ID,
-  assetId?: bigint,
-};
-
-export type SendPendingWallpaperAssetIdEvent = {
-  type: EventType.SEND_PENDING_WALLPAPER_ASSET_ID,
-  assetId?: bigint,
-};
-
-export type SelectImageEvent = {
-  type: EventType.SELECT_IMAGE,
-  assetId: bigint,
-};
-
 /**
  * Notify an iframe if its visible state changes.
  */
@@ -119,9 +94,7 @@
   visible: boolean,
 };
 
-export type Events =
-    SendCollectionsEvent|SendGooglePhotosEnabledEvent|SelectCollectionEvent|
-    SelectGooglePhotosCollectionEvent|SelectLocalCollectionEvent|
-    SendImageCountsEvent|SendImageTilesEvent|SendLocalImagesEvent|
-    SendLocalImageDataEvent|SendCurrentWallpaperAssetIdEvent|
-    SendPendingWallpaperAssetIdEvent|SelectImageEvent|SendVisibleEvent;
+export type Events = SendCollectionsEvent|SendGooglePhotosEnabledEvent|
+    SelectCollectionEvent|SelectGooglePhotosCollectionEvent|
+    SelectLocalCollectionEvent|SendImageCountsEvent|SendLocalImagesEvent|
+    SendLocalImageDataEvent|SendVisibleEvent;
diff --git a/ash/webui/personalization_app/resources/css/common.css b/ash/webui/personalization_app/resources/css/common.css
index a1ed953..7fc2e53 100644
--- a/ash/webui/personalization_app/resources/css/common.css
+++ b/ash/webui/personalization_app/resources/css/common.css
@@ -193,21 +193,12 @@
   width: calc(100% - 4px);
 }
 
-cr-button {
-  border-color: var(--cros-button-stroke-color-secondary);
-  border-radius: 16px;
-}
-
 cr-button[aria-pressed=true],
 cr-button[aria-selected=true] {
   background-color: var(--cros-highlight-color);
   border: 0;
 }
 
-cr-button + cr-button {
-  margin-inline-start: 8px;
-}
-
 .preview-container {
   border: 1px solid var(--cros-separator-color);
   border-radius: 16px;
diff --git a/ash/webui/personalization_app/resources/css/cros_button_style.css b/ash/webui/personalization_app/resources/css/cros_button_style.css
index d9f2578..d50c150 100644
--- a/ash/webui/personalization_app/resources/css/cros_button_style.css
+++ b/ash/webui/personalization_app/resources/css/cros_button_style.css
@@ -6,8 +6,14 @@
  * #type=style
  * #css_wrapper_metadata_end */
 
+cr-button {
+  border-color: var(--cros-button-stroke-color-secondary);
+  border-radius: 16px;
+}
+
 cr-button.primary {
   background-color: var(--cros-button-background-color-primary);
+  border: 0;
   --text-color: var(--cros-button-label-color-primary);
   --ink-color: var(--cros-button-ripple-color-primary);
   --hover-bg-color: var(--cros-button-background-color-primary-hover-preblended);
@@ -15,11 +21,16 @@
   --disabled-text-color: var(--cros-button-label-color-primary-disabled);
 }
 
+cr-button.primary:active {
+  box-shadow: 0 1px 2px rgba(66, 133, 244, 0.3), 0 1px 3px rgba(66, 133, 244, 0.15);
+}
+
 cr-button.primary:hover {
   background-color: var(--cros-button-background-color-primary-hover-preblended);
 }
 
 cr-button.secondary {
+  border: 1px solid var(--cros-button-stroke-color-secondary);
   --text-color: var(--cros-button-label-color-secondary);
   --border-color: var(--cros-button-stroke-color-secondary);
   --ink-color: var(--cros-button-ripple-color-secondary);
@@ -31,6 +42,7 @@
 
 cr-button.secondary:hover {
   background-color: var(--cros-button-background-color-secondary-hover);
+  border-color: var(--cros-button-stroke-color-secondary-hover);
 }
 
 cr-icon-button:focus-visible,
diff --git a/ash/webui/personalization_app/resources/trusted/iframe_api.ts b/ash/webui/personalization_app/resources/trusted/iframe_api.ts
index f5b9144..2f76e95 100644
--- a/ash/webui/personalization_app/resources/trusted/iframe_api.ts
+++ b/ash/webui/personalization_app/resources/trusted/iframe_api.ts
@@ -17,7 +17,6 @@
 import * as constants from '../common/constants.js';
 import {isNonEmptyArray} from '../common/utils.js';
 import {CollectionsGrid} from '../untrusted/collections_grid.js';
-import {ImagesGrid} from '../untrusted/images_grid.js';
 
 import {GooglePhotosEnablementState, WallpaperCollection, WallpaperImage} from './personalization_app.mojom-webui.js';
 
@@ -70,7 +69,7 @@
    * resize event on iron-list when an iframe becomes visible again so that
    * iron-list will run layout with the current size.
    */
-  sendVisible(target: CollectionsGrid|ImagesGrid, visible: boolean) {
+  sendVisible(target: CollectionsGrid, visible: boolean) {
     const event: constants.SendVisibleEvent = {
       type: constants.EventType.SEND_VISIBLE,
       visible
@@ -79,18 +78,6 @@
   }
 
   /**
-   * Send an array of wallpaper images to collections grid.
-   * Will clear the page if images is empty array.
-   */
-  sendImageTiles(target: ImagesGrid, tiles: constants.ImageTile[]) {
-    const event: constants.SendImageTilesEvent = {
-      type: constants.EventType.SEND_IMAGE_TILES,
-      tiles
-    };
-    target.onMessageReceived(event);
-  }
-
-  /**
    * Send an array of local images to collections grid.
    */
   sendLocalImages(
@@ -117,43 +104,12 @@
   }
 
   /**
-   * Send the |assetId| of the currently selected wallpaper to |target|.
-   * Sending null indicates that no image is selected.
-   */
-  sendCurrentWallpaperAssetId(target: ImagesGrid, assetId: bigint|undefined) {
-    const event: constants.SendCurrentWallpaperAssetIdEvent = {
-      type: constants.EventType.SEND_CURRENT_WALLPAPER_ASSET_ID,
-      assetId
-    };
-    target.onMessageReceived(event);
-  }
-
-  /**
-   * Send the |assetId| to the |target| when the user clicks on online wallpaper
-   * image.
-   */
-  sendPendingWallpaperAssetId(target: ImagesGrid, assetId: bigint|undefined) {
-    const event: constants.SendPendingWallpaperAssetIdEvent = {
-      type: constants.EventType.SEND_PENDING_WALLPAPER_ASSET_ID,
-      assetId
-    };
-    target.onMessageReceived(event);
-  }
-
-
-  /**
    * Called from trusted code to validate that a received event contains valid
    * data. Ignores messages that are not of the expected type.
    */
   validateReceivedSelection(
       data: constants.Events,
-      choices: WallpaperCollection[]|null): WallpaperCollection;
-  validateReceivedSelection(
-      data: constants.Events, choices: WallpaperImage[]|null): WallpaperImage;
-  validateReceivedSelection(
-      data: constants.Events,
-      choices: Array<WallpaperCollection|WallpaperImage>|
-      null): WallpaperCollection|WallpaperImage {
+      choices: WallpaperCollection[]|null): WallpaperCollection {
     assert(isNonEmptyArray(choices), 'choices must be a non-empty array');
 
     let selected: WallpaperCollection|WallpaperImage|undefined = undefined;
@@ -164,17 +120,6 @@
                        .find(choice => choice.id === data.collectionId);
         break;
       }
-      case constants.EventType.SELECT_IMAGE: {
-        assert(
-            data.hasOwnProperty('assetId'),
-            'Expected an image assetId parameter');
-        assert(
-            typeof data.assetId === 'bigint',
-            'assetId parameter must be bigint');
-        selected = (choices as WallpaperImage[])
-                       .find(choice => choice.assetId === data.assetId);
-        break;
-      }
       default:
         assertNotReached('Unknown event type');
     }
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_app.ts b/ash/webui/personalization_app/resources/trusted/personalization_app.ts
index be0e3ac..169d290 100644
--- a/ash/webui/personalization_app/resources/trusted/personalization_app.ts
+++ b/ash/webui/personalization_app/resources/trusted/personalization_app.ts
@@ -48,7 +48,6 @@
 export {DefaultImageSymbol, DisplayableImage, kDefaultImageSymbol, kMaximumLocalImagePreviews} from '../common/constants.js';
 export {getCountText, getNumberOfGridItemsPerRow} from '../common/utils.js';
 export {CollectionsGrid} from '../untrusted/collections_grid.js';
-export {ImagesGrid} from '../untrusted/images_grid.js';
 export {AlbumList} from './ambient/album_list_element.js';
 export {AlbumsSubpage} from './ambient/albums_subpage_element.js';
 export {AmbientActionName, AmbientActions, SetAlbumsAction, setAlbumsAction, SetAlbumSelectedAction, setAlbumSelectedAction, SetAmbientModeEnabledAction, setAmbientModeEnabledAction, SetAnimationThemeAction, setAnimationThemeAction, SetGooglePhotosAlbumsPreviewsAction, setGooglePhotosAlbumsPreviewsAction, SetTemperatureUnitAction, setTemperatureUnitAction, SetTopicSourceAction, setTopicSourceAction} from './ambient/ambient_actions.js';
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.html b/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.html
index 7d7abc4..71b34cf 100644
--- a/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.html
+++ b/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.html
@@ -26,7 +26,7 @@
   }
 
   #homeButton {
-    --cr-icon-button-fill-color: var(--cros-text-color-secondary);
+    --cr-icon-button-fill-color: var(--cros-text-color-primary);
     --cr-icon-button-size: 36px;
     margin-inline-end: 6px;
     margin-inline-start: -10px;
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html
index fe5c3e0..840c0f7 100644
--- a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html
+++ b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.html
@@ -7,7 +7,6 @@
   cr-button {
     background-color: var(--cros-tab-slider-track-color);
     border: 0;
-    border-radius: 16px;
     display: flex;
     flex-flow: column nowrap;
     height: 60px;
diff --git a/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.html b/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.html
index 435dc7d..c7be8a9 100644
--- a/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.html
+++ b/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.html
@@ -51,7 +51,6 @@
   }
 
   cr-button {
-    border-radius: 16px;
     display: flex;
     gap: 8px;
     height: 32px;
diff --git a/ash/webui/personalization_app/resources/trusted/utils.ts b/ash/webui/personalization_app/resources/trusted/utils.ts
index d40f621..cc0bad6 100644
--- a/ash/webui/personalization_app/resources/trusted/utils.ts
+++ b/ash/webui/personalization_app/resources/trusted/utils.ts
@@ -43,8 +43,7 @@
     return key === kDefaultImageSymbol;
   }
   if (isFilePath(image)) {
-    // TODO(b/229420564): Update key extraction for local images.
-    return key === image.path.substr(image.path.lastIndexOf('/') + 1);
+    return key === image.path;
   }
   assert(isGooglePhotosPhoto(image));
   // NOTE: Old clients may not support |dedupKey| when setting Google Photos
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.html
index 2055558..0f2abcf0 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.html
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.html
@@ -22,6 +22,11 @@
 
   #tabStrip cr-button {
     border: 0;
+    border-radius: 16px;
+  }
+
+  #tabStrip cr-button + cr-button {
+    margin-inline-start: 8px;
   }
 
   #tabStrip cr-button[aria-pressed='false'] {
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts
index 9ccdf92c..6a59a87 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts
@@ -17,7 +17,6 @@
 import './wallpaper_selected_element.js';
 import './wallpaper_subpage_element.js';
 import '../../untrusted/collections_grid.js';
-import '../../untrusted/images_grid.js';
 import '../../css/wallpaper.css.js';
 
 import {WallpaperObserver} from './wallpaper_observer.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts
index 81ab9dd22..74085561 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts
@@ -175,7 +175,7 @@
     }
     return (isFilePath(pendingSelected) &&
                 image.path === pendingSelected.path ||
-            !!currentSelected && image.path.endsWith(currentSelected.key) &&
+            !!currentSelected && image.path === currentSelected.key &&
                 !pendingSelected)
                .toString() as 'true' |
         'false';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/untrusted_message_handler.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/untrusted_message_handler.ts
index 1a2122ad..92c8f51b 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/untrusted_message_handler.ts
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/untrusted_message_handler.ts
@@ -7,9 +7,6 @@
 import {Paths, PersonalizationRouter} from '../personalization_router_element.js';
 import {PersonalizationStore} from '../personalization_store.js';
 
-import {selectWallpaper} from './wallpaper_controller.js';
-import {getWallpaperProvider} from './wallpaper_interface_provider.js';
-
 /**
  * @fileoverview message handler that receives data from untrusted.
  */
@@ -32,16 +29,5 @@
     case EventType.SELECT_LOCAL_COLLECTION:
       PersonalizationRouter.instance().goToRoute(Paths.LOCAL_COLLECTION);
       break;
-    case EventType.SELECT_IMAGE:
-      const collectionId = PersonalizationRouter.instance().collectionId;
-      if (!collectionId) {
-        console.warn('collectionId is not available when selecting image.');
-        return;
-      }
-      const images = store.data.wallpaper.backdrop.images[collectionId];
-      const selectedImage =
-          IFrameApi.getInstance().validateReceivedSelection(data, images);
-      selectWallpaper(selectedImage, getWallpaperProvider(), store);
-      break;
   }
 }
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.html
index a4117bb..16c4fbb 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.html
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.html
@@ -1,8 +1,44 @@
-<style include="wallpaper"></style>
+<style include="common wallpaper"></style>
 <main id="main" tabindex="-1"
     aria-label$="[[getMainAriaLabel_(collectionId, collections_)]]">
   <iron-media-query query="(prefers-color-scheme: dark)"
     query-matches="{{isDarkModeActive}}">
   </iron-media-query>
-  <images-grid id="imagesGrid"></images-grid>
+  <images-grid id="imagesGrid" tiles="[[tiles_]]" selectedAssetId="[[selectedAssetId_]]" pendingSelectedAssetId="[[pendingSelectedAssetId_]]"></images-grid>
+  <template is="dom-if" if="[[tiles_]]">
+    <iron-list grid items="[[tiles_]]" role="listbox"
+        aria-setsize$="[[tiles_.length]]">
+      <template>
+        <div class="photo-container">
+          <template is="dom-if" if="[[isLoadingTile_(item)]]">
+            <div tabindex$="[[tabIndex]]"
+                role="option"
+                class="photo-inner-container placeholder"
+                style$="[[getLoadingPlaceholderAnimationDelay_(index)]]"
+                aria-posinset$="[[getAriaIndex_(index)]]"
+                aria-label="$i18n{ariaLabelLoading}"
+                aria-disabled="true"></div>
+          </template>
+          <template is="dom-if" if="[[isImageTile_(item)]]">
+            <div class="photo-inner-container" tabindex$="[[tabIndex]]"
+                role="option" data-asset-id$="[[item.assetId]]"
+                data-unit-id$="[[item.unitId]]" on-click="onImageSelected_"
+                on-keypress="onImageSelected_"
+                aria-posinset$="[[getAriaIndex_(index)]]"
+                aria-selected$="[[getAriaSelected_(item, selectedAssetId_, pendingSelectedAssetId_)]]"
+                aria-label$="[[getAriaLabel_(item)]]">
+              <div class="photo-images-container">
+                <div class="photo-images-border"></div>
+                <template is="dom-repeat" items="[[item.preview]]" as="preview">
+                  <img is="cr-auto-img" class$="[[getClassForImg_(index, item)]]"
+                      auto-src="[[preview.url]]" aria-hidden="true" clear-src>
+                </template>
+                <iron-icon icon="personalization:checkmark"></iron-icon>
+              </div>
+            </div>
+          </template>
+        </div>
+      </template>
+    </iron-list>
+  </template>
 </main>
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts
index 9d0d7f41..ec02c5c 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts
@@ -12,36 +12,41 @@
 import 'chrome://resources/polymer/v3_0/iron-media-query/iron-media-query.js';
 import '../../css/wallpaper.css.js';
 
+import {assert} from 'chrome://resources/js/assert_ts.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
-import {DisplayableImage, ImageTile} from '../../common/constants.js';
-import {isNonEmptyArray} from '../../common/utils.js';
-import {ImagesGrid} from '../../untrusted/images_grid.js';
-import {IFrameApi} from '../iframe_api.js';
+import {ImageTile} from '../../common/constants.js';
+import {getLoadingPlaceholderAnimationDelay, getLoadingPlaceholders, isNonEmptyArray, isSelectionEvent} from '../../common/utils.js';
 import {CurrentWallpaper, OnlineImageType, WallpaperCollection, WallpaperImage, WallpaperType} from '../personalization_app.mojom-webui.js';
 import {PersonalizationRouter} from '../personalization_router_element.js';
 import {WithPersonalizationStore} from '../personalization_store.js';
 import {isWallpaperImage} from '../utils.js';
 
+import {selectWallpaper} from './wallpaper_controller.js';
 import {getTemplate} from './wallpaper_images_element.html.js';
+import {getWallpaperProvider} from './wallpaper_interface_provider.js';
+
+(BigInt.prototype as any).toJSON = function() {
+  return this.toString();
+};
 
 /**
  * If |current| is set and is an online wallpaper (include daily refresh
  * wallpaper), return the assetId of that image. Otherwise returns null.
  */
-function getAssetId(current: CurrentWallpaper|null): bigint|undefined {
+function getAssetId(current: CurrentWallpaper|null): bigint|null {
   if (current == null) {
-    return undefined;
+    return null;
   }
   if (current.type !== WallpaperType.kOnline &&
       current.type !== WallpaperType.kDaily) {
-    return undefined;
+    return null;
   }
   try {
     return BigInt(current.key);
   } catch (e) {
     console.warn('Required a BigInt value here', e);
-    return undefined;
+    return null;
   }
 }
 
@@ -90,10 +95,6 @@
   return [...tileMap.values()];
 }
 
-export interface WallpaperImages {
-  $: {imagesGrid: ImagesGrid};
-}
-
 export class WallpaperImages extends WithPersonalizationStore {
   static get is() {
     return 'wallpaper-images';
@@ -106,16 +107,6 @@
   static get properties() {
     return {
       /**
-       * Hidden state of this element. Used to notify iframe of visibility
-       * changes.
-       */
-      hidden: {
-        type: Boolean,
-        reflectToAttribute: true,
-        observer: 'onHiddenChanged_',
-      },
-
-      /**
        * Whether dark mode is the active preferred color scheme.
        */
       isDarkModeActive: {
@@ -139,58 +130,46 @@
        */
       imagesLoading_: Object,
 
-      currentSelected_: {
-        type: Object,
-        observer: 'onCurrentSelectedChanged_',
+      selectedAssetId_: {
+        type: BigInt,
+        value: null,
       },
 
       /**
        * The pending selected image.
        */
-      pendingSelected_: {
-        type: Object,
-        observer: 'onPendingSelectedChanged_',
+      pendingSelectedAssetId_: {
+        type: BigInt,
+        value: null,
       },
 
       hasError_: {
         type: Boolean,
-        // Call computed functions with their dependencies as arguments so that
-        // polymer knows when to re-run the computation.
         computed:
             'computeHasError_(images_, imagesLoading_, collections_, collectionsLoading_, collectionId)',
+        observer: 'onHasErrorChanged_',
       },
 
-      /**
-       * In order to prevent re-sending images every time a collection loads in
-       * the background, calculate this intermediate boolean. That way
-       * |onImagesUpdated_| will re-run whenever this value flips from false to
-       * true, rather than each time a new collection is changed in the
-       * background.
-       */
-      hasImages_: {
-        type: Boolean,
-        computed: 'computeHasImages_(images_, imagesLoading_, collectionId)',
+
+      tiles_: {
+        type: Array,
+        computed:
+            'computeTiles_(images_, imagesLoading_, collectionId, isDarkModeActive)',
       },
+
     };
   }
 
-  override hidden: boolean;
   collectionId: string;
   isDarkModeActive: boolean;
   private collections_: WallpaperCollection[]|null;
   private collectionsLoading_: boolean;
   private images_: Record<string, WallpaperImage[]|null>;
   private imagesLoading_: Record<string, boolean>;
-  private currentSelected_: CurrentWallpaper|null;
-  private pendingSelected_: DisplayableImage|null;
+  private selectedAssetId_: bigint|null;
+  private pendingSelectedAssetId_: bigint|null;
   private hasError_: boolean;
-  private hasImages_: boolean;
-
-  static get observers() {
-    return [
-      'onImagesUpdated_(hasImages_, hasError_, collectionId, isDarkModeActive)',
-    ];
-  }
+  private tiles_: ImageTile[];
 
   override connectedCallback() {
     super.connectedCallback();
@@ -202,37 +181,18 @@
         'collections_', state => state.wallpaper.backdrop.collections);
     this.watch<WallpaperImages['collectionsLoading_']>(
         'collectionsLoading_', state => state.wallpaper.loading.collections);
-    this.watch<WallpaperImages['currentSelected_']>(
-        'currentSelected_', state => state.wallpaper.currentSelected);
-    this.watch<WallpaperImages['pendingSelected_']>(
-        'pendingSelected_', state => state.wallpaper.pendingSelected);
+    this.watch<WallpaperImages['selectedAssetId_']>(
+        'selectedAssetId_',
+        state => getAssetId(state.wallpaper.currentSelected));
+    this.watch<WallpaperImages['pendingSelectedAssetId_']>(
+        'pendingSelectedAssetId_',
+        state => isWallpaperImage(state.wallpaper.pendingSelected) ?
+            state.wallpaper.pendingSelected.assetId :
+            null);
     this.updateFromStore();
   }
 
   /**
-   * Notify iframe that this element visibility has changed.
-   */
-  private onHiddenChanged_(hidden: boolean) {
-    if (!hidden) {
-      this.shadowRoot!.getElementById('main')!.focus();
-    }
-    IFrameApi.getInstance().sendVisible(this.$.imagesGrid, !hidden);
-  }
-
-  private onCurrentSelectedChanged_(selected: CurrentWallpaper|null) {
-    const assetId = getAssetId(selected);
-    IFrameApi.getInstance().sendCurrentWallpaperAssetId(
-        this.$.imagesGrid, assetId);
-  }
-
-  private onPendingSelectedChanged_(pendingSelected: DisplayableImage|null) {
-    IFrameApi.getInstance().sendPendingWallpaperAssetId(
-        this.$.imagesGrid,
-        isWallpaperImage(pendingSelected) ? pendingSelected.assetId :
-                                            undefined);
-  }
-
-  /**
    * Determine whether the current collection failed to load or is not a valid
    * |collectionId|. Check that collections list loaded successfully, and that
    * the collection with id |collectionId| also loaded successfully.
@@ -259,45 +219,40 @@
         !isNonEmptyArray(images[collectionId]);
   }
 
-  private computeHasImages_(
-      images: Record<string, WallpaperImage>,
-      imagesLoading: Record<string, boolean>, collectionId: string): boolean {
-    return !!images && !!imagesLoading &&
-        // Specifically check === false again here.
-        imagesLoading[collectionId] === false &&
-        isNonEmptyArray(images[collectionId]);
+  /** Kick the user back to wallpaper collections page if failed to load. */
+  private onHasErrorChanged_(hasError: boolean) {
+    if (hasError) {
+      console.warn('An error occurred while loading collections or images');
+      // Navigate back to main page and refresh.
+      PersonalizationRouter.reloadAtWallpaper();
+    }
   }
 
   /**
    * Send images if loading is ready and we have some images. Punt back to
    * main page if there is an error viewing this collection.
    */
-  private onImagesUpdated_(
-      hasImages: boolean, hasError: boolean, collectionId: string,
-      isDarkModeActive: boolean) {
-    if (hasError) {
-      console.warn('An error occurred while loading collections or images');
-      // Navigate back to main page and refresh.
-      PersonalizationRouter.reloadAtWallpaper();
-      return;
+  private computeTiles_(
+      images: Record<string, WallpaperImage[]>,
+      imagesLoading: Record<string, boolean>, collectionId: string,
+      isDarkModeActive: boolean): ImageTile[]|number[] {
+    const hasImages = !!images && !!imagesLoading && collectionId &&
+        imagesLoading[collectionId] === false &&
+        isNonEmptyArray(images[collectionId]);
+
+    if (!hasImages) {
+      return getLoadingPlaceholders(() => 1);
     }
 
-    if (hasImages && collectionId) {
-      const imageArr = this.images_[collectionId];
-      const isDarkLightModeEnabled =
-          loadTimeData.getBoolean('isDarkLightModeEnabled');
-      if (isDarkLightModeEnabled) {
-        IFrameApi.getInstance().sendImageTiles(
-            this.$.imagesGrid,
-            getDarkLightImageTiles(isDarkModeActive, imageArr!));
-      } else {
-        IFrameApi.getInstance().sendImageTiles(
-            this.$.imagesGrid, getRegularImageTiles(imageArr!));
-      }
+    const imageArr = images[collectionId]!;
+
+    if (loadTimeData.getBoolean('isDarkLightModeEnabled')) {
+      return getDarkLightImageTiles(isDarkModeActive, imageArr);
+    } else {
+      return getRegularImageTiles(imageArr);
     }
   }
 
-
   private getMainAriaLabel_(
       collectionId: string, collections: WallpaperCollection[]) {
     if (!collectionId || !Array.isArray(collections)) {
@@ -313,6 +268,67 @@
 
     return collection.name;
   }
+
+  private isLoadingTile_(tile: number|ImageTile): tile is number {
+    return typeof tile === 'number';
+  }
+
+  private isImageTile_(tile: number|ImageTile): tile is ImageTile {
+    return tile.hasOwnProperty('preview') &&
+        Array.isArray((tile as any).preview);
+  }
+
+  private getLoadingPlaceholderAnimationDelay_(index: number): string {
+    return getLoadingPlaceholderAnimationDelay(index);
+  }
+
+  private getAriaSelected_(
+      tile: ImageTile, selectedAssetId: bigint|null,
+      pendingSelectedAssetId: bigint|null): string {
+    // Make sure that both are bigint (not undefined) and equal.
+    return (typeof selectedAssetId === 'bigint' && !!tile &&
+                tile.assetId === selectedAssetId && !pendingSelectedAssetId ||
+            typeof pendingSelectedAssetId === 'bigint' && !!tile &&
+                tile.assetId === pendingSelectedAssetId)
+        .toString();
+  }
+
+  private getClassForImg_(index: number, tile: ImageTile): string {
+    if (tile.preview.length < 2) {
+      return '';
+    }
+    switch (index) {
+      case 0:
+        return 'left';
+      case 1:
+        return 'right';
+      default:
+        return '';
+    }
+  }
+
+  private onImageSelected_(e: Event) {
+    if (!isSelectionEvent(e)) {
+      return;
+    }
+    const imgElement = e.currentTarget as HTMLImageElement;
+    const assetId = imgElement.dataset['assetId'];
+    assert(assetId, 'assetId not found');
+    const images = this.images_[this.collectionId]!;
+    assert(isNonEmptyArray(images));
+    const selectedImage =
+        images.find(choice => choice.assetId.toString() === assetId);
+    assert(selectedImage);
+    selectWallpaper(selectedImage, getWallpaperProvider(), this.getStore());
+  }
+
+  private getAriaLabel_(tile: ImageTile): string {
+    return tile.attribution!.join(' ');
+  }
+
+  private getAriaIndex_(i: number): number {
+    return i + 1;
+  }
 }
 
 customElements.define(WallpaperImages.is, WallpaperImages);
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.html
index 3411e348..dee2383 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.html
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.html
@@ -49,6 +49,15 @@
     --iron-icon-height: 20px;
     --iron-icon-width: 20px;
   }
+
+  cr-button {
+    border-color: var(--cros-button-stroke-color-secondary);
+    border-radius: 16px;
+  }
+
+  cr-button + cr-button {
+    margin-inline-start: 8px;
+  }
 </style>
 <header id="container" class$="[[getContainerClass_(isLoading_, showImage_)]]">
   <template is="dom-if" if="[[showPlaceholders_(isLoading_, showImage_)]]">
@@ -97,7 +106,7 @@
               aria-label="$i18n{ariaLabelChangeDaily}"
               aria-pressed$="[[ariaPressed_]]"
               on-click="onClickDailyRefreshToggle_"
-              hidden$="[[!showDailyRefreshButton_]]"">
+              hidden$="[[!showDailyRefreshButton_]]">
             <iron-icon icon="[[dailyRefreshIcon_]]"></iron-icon>
             <div class="text">$i18n{changeDaily}</div>
           </cr-button>
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage_element.html
index 267e36fb..0ee321e 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage_element.html
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_subpage_element.html
@@ -46,8 +46,9 @@
           these elements. -->
   <wallpaper-collections hidden="[[!shouldShowCollections_(path)]]">
   </wallpaper-collections>
-  <wallpaper-images collection-id="[[queryParams.id]]"
-      hidden="[[!shouldShowCollectionImages_(path)]]"></wallpaper-images>
+  <template is="dom-if" if="[[shouldShowCollectionImages_(path)]]" restamp>
+    <wallpaper-images collection-id="[[queryParams.id]]"></wallpaper-images>
+  </template>
   <template is="dom-if" if="[[isGooglePhotosIntegrationEnabled_()]]">
     <google-photos-collection path="[[path]]"
         album-id="[[queryParams.googlePhotosAlbumId]]"
diff --git a/ash/webui/personalization_app/resources/untrusted/iframe_api.ts b/ash/webui/personalization_app/resources/untrusted/iframe_api.ts
index 88a094b9..b1bcb52 100644
--- a/ash/webui/personalization_app/resources/untrusted/iframe_api.ts
+++ b/ash/webui/personalization_app/resources/untrusted/iframe_api.ts
@@ -46,17 +46,6 @@
 }
 
 /**
- * Select an image. Sent from untrusted to trusted.
- */
-export function selectImage(assetId: bigint) {
-  const event: constants.SelectImageEvent = {
-    type: constants.EventType.SELECT_IMAGE,
-    assetId
-  };
-  onMessageReceived(event);
-}
-
-/**
  * Called from untrusted code to validate that a received event is of an
  * expected type and contains the expected data.
  */
@@ -79,14 +68,6 @@
       return Array.isArray(event.images) &&
           event.images.every(
               image => isDefaultImage(image) || isFilePath(image));
-    case constants.EventType.SEND_IMAGE_TILES: {
-      // Images array may be empty.
-      return Array.isArray(event.tiles);
-    }
-    case constants.EventType.SEND_CURRENT_WALLPAPER_ASSET_ID:
-    case constants.EventType.SEND_PENDING_WALLPAPER_ASSET_ID: {
-      return event.assetId === null || typeof event.assetId === 'bigint';
-    }
     case constants.EventType.SEND_VISIBLE: {
       return typeof event.visible === 'boolean';
     }
diff --git a/ash/webui/personalization_app/resources/untrusted/images_grid.html b/ash/webui/personalization_app/resources/untrusted/images_grid.html
deleted file mode 100644
index a90ddab..0000000
--- a/ash/webui/personalization_app/resources/untrusted/images_grid.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<style include="common wallpaper">
-  :host {
-    margin: 12px 0;
-  }
-</style>
-<template is="dom-if" if="[[tiles_]]">
-  <iron-list grid items="[[tiles_]]" role="listbox"
-      aria-setsize$="[[tiles_.length]]">
-    <template>
-      <div class="photo-container">
-        <template is="dom-if" if="[[isLoadingTile_(item)]]">
-          <div tabindex$="[[tabIndex]]"
-              role="option"
-              class="photo-inner-container placeholder"
-              style$="[[getLoadingPlaceholderAnimationDelay_(index)]]"
-              aria-posinset$="[[getAriaIndex_(index)]]"
-              aria-label="$i18n{ariaLabelLoading}"
-              aria-disabled="true"></div>
-        </template>
-        <template is="dom-if" if="[[isImageTile_(item)]]">
-          <div class="photo-inner-container" tabindex$="[[tabIndex]]"
-              role="option" data-asset-id$="[[item.assetId]]"
-              data-unit-id$="[[item.unitId]]" on-click="onImageSelected_"
-              on-keypress="onImageSelected_"
-              aria-posinset$="[[getAriaIndex_(index)]]"
-              aria-selected$="[[getAriaSelected_(item, selectedAssetId_, pendingSelectedAssetId_)]]"
-              aria-label$="[[getAriaLabel_(item)]]">
-            <div class="photo-images-container">
-              <div class="photo-images-border"></div>
-              <template is="dom-repeat" items="[[item.preview]]" as="preview">
-                <img is="cr-auto-img" class$="[[getClassForImg_(index, item)]]"
-                    auto-src="[[preview.url]]" aria-hidden="true" clear-src>
-              </template>
-              <iron-icon icon="personalization:checkmark"></iron-icon>
-            </div>
-          </div>
-        </template>
-      </div>
-    </template>
-  </iron-list>
-</template>
diff --git a/ash/webui/personalization_app/resources/untrusted/images_grid.ts b/ash/webui/personalization_app/resources/untrusted/images_grid.ts
deleted file mode 100644
index 08a186b..0000000
--- a/ash/webui/personalization_app/resources/untrusted/images_grid.ts
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import '//resources/cr_elements/cr_auto_img/cr_auto_img.js';
-import '//resources/polymer/v3_0/iron-list/iron-list.js';
-import './setup.js';
-import '../css/wallpaper.css.js';
-
-import {assertNotReached} from '//resources/js/assert.m.js';
-import {afterNextRender, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {Events, EventType, ImageTile} from '../common/constants.js';
-import {getLoadingPlaceholderAnimationDelay, getLoadingPlaceholders, isSelectionEvent} from '../common/utils.js';
-import {selectImage, validateReceivedData} from '../untrusted/iframe_api.js';
-
-import {getTemplate} from './images_grid.html.js';
-
-/**
- * @fileoverview Responds to |SendImageTilesEvent| from trusted. Handles user
- * input and responds with |SelectImageEvent| when an image is selected.
- */
-
-export class ImagesGrid extends PolymerElement {
-  static get is() {
-    return 'images-grid';
-  }
-
-  static get template() {
-    return getTemplate();
-  }
-
-  static get properties() {
-    return {
-      tiles_: {
-        type: Array,
-        value() {
-          // Fill the view with loading tiles. Will be adjusted to the correct
-          // number of tiles when collections are received.
-          return getLoadingPlaceholders(() => 0);
-        }
-      },
-
-      selectedAssetId_: {
-        type: Object,
-        value: null,
-      },
-
-      pendingSelectedAssetId_: {
-        type: Object,
-        value: null,
-      }
-    };
-  }
-
-  private tiles_: ImageTile[]|number[];
-  private selectedAssetId_: bigint|undefined;
-  private pendingSelectedAssetId_: bigint|undefined;
-
-  /**
-   * Handler for messages from trusted code. Expects only SendImagesEvent and
-   * will error on any other event.
-   */
-  onMessageReceived(event: Events) {
-    switch (event.type) {
-      case EventType.SEND_IMAGE_TILES:
-        this.tiles_ = validateReceivedData(event) ? event.tiles : [];
-        return;
-      case EventType.SEND_CURRENT_WALLPAPER_ASSET_ID:
-        this.selectedAssetId_ =
-            validateReceivedData(event) ? event.assetId : undefined;
-        return;
-      case EventType.SEND_PENDING_WALLPAPER_ASSET_ID:
-        this.pendingSelectedAssetId_ =
-            validateReceivedData(event) ? event.assetId : undefined;
-        return;
-      case EventType.SEND_VISIBLE:
-        let visible = false;
-        if (validateReceivedData(event)) {
-          visible = event.visible;
-        }
-        if (visible) {
-          // If iron-list items were updated while this iron-list was hidden,
-          // the layout will be incorrect. Trigger another layout when iron-list
-          // becomes visible again. Wait until |afterNextRender| completes
-          // otherwise iron-list width may still be 0.
-          afterNextRender(this, () => {
-            // Trigger a layout now that iron-list has the correct width.
-            this.shadowRoot!.querySelector('iron-list')!.fire('iron-resize');
-          });
-        }
-        return;
-      default:
-        throw new Error('unexpected event type');
-    }
-  }
-
-  private isLoadingTile_(tile: number|ImageTile): tile is number {
-    return typeof tile === 'number';
-  }
-
-  private isImageTile_(tile: number|ImageTile): tile is ImageTile {
-    return tile.hasOwnProperty('preview') &&
-        Array.isArray((tile as any).preview);
-  }
-
-  private getLoadingPlaceholderAnimationDelay_(index: number): string {
-    return getLoadingPlaceholderAnimationDelay(index);
-  }
-
-  private getAriaSelected_(
-      tile: ImageTile, selectedAssetId: bigint|undefined,
-      pendingSelectedAssetId: bigint|undefined): string {
-    // Make sure that both are bigint (not undefined) and equal.
-    return (typeof selectedAssetId === 'bigint' && !!tile &&
-                tile.assetId === selectedAssetId && !pendingSelectedAssetId ||
-            typeof pendingSelectedAssetId === 'bigint' && !!tile &&
-                tile.assetId === pendingSelectedAssetId)
-        .toString();
-  }
-
-  private getClassForImg_(index: number, tile: ImageTile): string {
-    if (tile.preview.length < 2) {
-      return '';
-    }
-    switch (index) {
-      case 0:
-        return 'left';
-      case 1:
-        return 'right';
-      default:
-        return '';
-    }
-  }
-
-  /**
-   * Notify trusted code that a user selected an image.
-   */
-  private onImageSelected_(e: Event) {
-    if (!isSelectionEvent(e)) {
-      return;
-    }
-    const imgElement = e.currentTarget as HTMLImageElement;
-    const assetId = imgElement.dataset['assetId'];
-    if (assetId === undefined) {
-      assertNotReached('assetId not found');
-      return;
-    }
-    selectImage(BigInt(assetId));
-  }
-
-  private getAriaLabel_(tile: ImageTile): string {
-    return tile.attribution!.join(' ');
-  }
-
-  private getAriaIndex_(i: number): number {
-    return i + 1;
-  }
-}
-
-customElements.define(ImagesGrid.is, ImagesGrid);
diff --git a/ash/webui/personalization_app/search/search_handler.cc b/ash/webui/personalization_app/search/search_handler.cc
index ee90c72..5c5c77b 100644
--- a/ash/webui/personalization_app/search/search_handler.cc
+++ b/ash/webui/personalization_app/search/search_handler.cc
@@ -40,7 +40,8 @@
 }  // namespace
 
 SearchHandler::SearchHandler(
-    local_search_service::LocalSearchServiceProxy& local_search_service_proxy,
+    ::chromeos::local_search_service::LocalSearchServiceProxy&
+        local_search_service_proxy,
     PrefService* pref_service,
     std::unique_ptr<EnterprisePolicyDelegate> enterprise_policy_delegate)
     : search_tag_registry_(std::make_unique<SearchTagRegistry>(
@@ -91,10 +92,11 @@
 void SearchHandler::OnLocalSearchDone(
     SearchCallback callback,
     uint32_t max_num_results,
-    local_search_service::ResponseStatus response_status,
-    const absl::optional<std::vector<local_search_service::Result>>&
+    ::chromeos::local_search_service::ResponseStatus response_status,
+    const absl::optional<std::vector<::chromeos::local_search_service::Result>>&
         local_search_service_results) {
-  if (response_status != local_search_service::ResponseStatus::kSuccess) {
+  if (response_status !=
+      ::chromeos::local_search_service::ResponseStatus::kSuccess) {
     LOG(ERROR) << "Cannot search; LocalSearchService returned "
                << static_cast<int>(response_status)
                << ". Returning empty results array.";
diff --git a/ash/webui/personalization_app/search/search_handler.h b/ash/webui/personalization_app/search/search_handler.h
index 054db93..6e245bb 100644
--- a/ash/webui/personalization_app/search/search_handler.h
+++ b/ash/webui/personalization_app/search/search_handler.h
@@ -22,14 +22,16 @@
 #include "mojo/public/cpp/bindings/remote_set.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+// TODO(https://crbug.com/1164001): move forward declaration to ash.
+namespace chromeos {
+namespace local_search_service {
+class LocalSearchServiceProxy;
+}  // namespace local_search_service
+}  // namespace chromeos
+
 class PrefService;
 
 namespace ash {
-
-namespace local_search_service {
-class LocalSearchServiceProxy;
-}
-
 namespace personalization_app {
 
 class EnterprisePolicyDelegate;
@@ -38,7 +40,8 @@
                       public SearchTagRegistry::Observer {
  public:
   SearchHandler(
-      local_search_service::LocalSearchServiceProxy& local_search_service_proxy,
+      ::chromeos::local_search_service::LocalSearchServiceProxy&
+          local_search_service_proxy,
       PrefService* pref_service,
       std::unique_ptr<EnterprisePolicyDelegate> enterprise_policy_delegate);
 
@@ -66,14 +69,15 @@
   void OnLocalSearchDone(
       SearchCallback callback,
       uint32_t max_num_results,
-      local_search_service::ResponseStatus response_status,
-      const absl::optional<std::vector<local_search_service::Result>>&
+      ::chromeos::local_search_service::ResponseStatus response_status,
+      const absl::optional<
+          std::vector<::chromeos::local_search_service::Result>>&
           local_search_service_results);
 
   std::unique_ptr<SearchTagRegistry> search_tag_registry_;
   base::ScopedObservation<SearchTagRegistry, SearchTagRegistry::Observer>
       search_tag_registry_observer_{this};
-  mojo::Remote<local_search_service::mojom::Index> index_remote_;
+  mojo::Remote<::chromeos::local_search_service::mojom::Index> index_remote_;
   mojo::ReceiverSet<mojom::SearchHandler> receivers_;
   mojo::RemoteSet<mojom::SearchResultsObserver> observers_;
   base::WeakPtrFactory<SearchHandler> weak_ptr_factory_{this};
diff --git a/ash/webui/personalization_app/search/search_handler_unittest.cc b/ash/webui/personalization_app/search/search_handler_unittest.cc
index 85e2e0a..64a63b7f 100644
--- a/ash/webui/personalization_app/search/search_handler_unittest.cc
+++ b/ash/webui/personalization_app/search/search_handler_unittest.cc
@@ -158,7 +158,7 @@
 
   void SetUp() override {
     local_search_service_proxy_ =
-        std::make_unique<local_search_service::LocalSearchServiceProxy>(
+        std::make_unique<::ash::local_search_service::LocalSearchServiceProxy>(
             /*for_testing=*/true);
     test_pref_service_ = std::make_unique<TestingPrefServiceSimple>();
     test_pref_service_->registry()->RegisterBooleanPref(
@@ -175,8 +175,9 @@
 
   std::vector<mojom::SearchResultPtr> SimulateSearchCompleted(
       uint32_t max_num_results,
-      local_search_service::ResponseStatus response_status,
-      const absl::optional<std::vector<local_search_service::Result>>&
+      ::chromeos::local_search_service::ResponseStatus response_status,
+      const absl::optional<
+          std::vector<::chromeos::local_search_service::Result>>&
           local_search_service_results) {
     std::vector<mojom::SearchResultPtr> result;
     base::RunLoop loop;
@@ -222,7 +223,7 @@
 
   // Remove all existing search concepts saved in the registry.
   void ClearSearchTagRegistry() {
-    local_search_service::mojom::IndexAsyncWaiter(
+    ::chromeos::local_search_service::mojom::IndexAsyncWaiter(
         search_tag_registry()->index_remote_.get())
         .ClearIndex();
     search_tag_registry()->result_id_to_search_concept_.clear();
@@ -231,7 +232,7 @@
  private:
   base::test::TaskEnvironment task_environment_;
   base::test::ScopedFeatureList scoped_feature_list_;
-  std::unique_ptr<local_search_service::LocalSearchServiceProxy>
+  std::unique_ptr<::chromeos::local_search_service::LocalSearchServiceProxy>
       local_search_service_proxy_;
   std::unique_ptr<TestingPrefServiceSimple> test_pref_service_;
   std::unique_ptr<SearchHandler> search_handler_;
@@ -436,9 +437,9 @@
 
   // Scores that correspond to each of the |test_search_concepts|.
   std::vector<double> scores = {0.33, 0.5, 0.1, 0.99};
-  std::vector<local_search_service::Result> fake_local_results;
+  std::vector<::chromeos::local_search_service::Result> fake_local_results;
   for (size_t i = 0; i < scores.size(); i++) {
-    std::vector<local_search_service::Position> positions;
+    std::vector<::chromeos::local_search_service::Position> positions;
     positions.emplace_back(/*content_id=*/base::NumberToString(
                                test_search_concepts.at(i).message_id),
                            /*start=*/0, /*length=*/0);
@@ -450,7 +451,7 @@
   constexpr size_t maxNumResults = 2;
   auto results = SimulateSearchCompleted(
       /*max_num_results=*/maxNumResults,
-      local_search_service::ResponseStatus::kSuccess,
+      ::chromeos::local_search_service::ResponseStatus::kSuccess,
       absl::make_optional(fake_local_results));
 
   // Capped at |maxNumResults|.
diff --git a/ash/webui/personalization_app/search/search_tag_registry.cc b/ash/webui/personalization_app/search/search_tag_registry.cc
index 09443cc..85170cc 100644
--- a/ash/webui/personalization_app/search/search_tag_registry.cc
+++ b/ash/webui/personalization_app/search/search_tag_registry.cc
@@ -56,9 +56,9 @@
   return message_ids;
 }
 
-std::vector<local_search_service::Content> SearchConceptToContentVector(
-    const SearchConcept& search_concept) {
-  std::vector<local_search_service::Content> content_vector;
+std::vector<::chromeos::local_search_service::Content>
+SearchConceptToContentVector(const SearchConcept& search_concept) {
+  std::vector<::chromeos::local_search_service::Content> content_vector;
 
   for (auto message_id : GetMessageIds(search_concept)) {
     content_vector.emplace_back(base::NumberToString(message_id),
@@ -265,7 +265,8 @@
 }  // namespace
 
 SearchTagRegistry::SearchTagRegistry(
-    local_search_service::LocalSearchServiceProxy& local_search_service_proxy,
+    ::chromeos::local_search_service::LocalSearchServiceProxy&
+        local_search_service_proxy,
     PrefService* pref_service,
     std::unique_ptr<EnterprisePolicyDelegate> enterprise_policy_delegate)
     : pref_service_(pref_service),
@@ -274,8 +275,8 @@
   DCHECK(enterprise_policy_delegate_);
 
   local_search_service_proxy.GetIndex(
-      local_search_service::IndexId::kPersonalization,
-      local_search_service::Backend::kLinearMap,
+      ::chromeos::local_search_service::IndexId::kPersonalization,
+      ::chromeos::local_search_service::Backend::kLinearMap,
       index_remote_.BindNewPipeAndPassReceiver());
   DCHECK(index_remote_.is_bound());
 
@@ -309,7 +310,7 @@
 
 void SearchTagRegistry::UpdateSearchConcepts(
     const SearchConceptUpdates& search_concept_updates) {
-  std::vector<local_search_service::Data> data_vec;
+  std::vector<::chromeos::local_search_service::Data> data_vec;
 
   for (auto& [search_concept, add] : search_concept_updates) {
     std::string concept_id = SearchConceptToId(*search_concept);
@@ -325,8 +326,8 @@
 
     if (found && !add) {
       // Removing a search concept that was present.
-      data_vec.emplace_back(concept_id,
-                            std::vector<local_search_service::Content>());
+      data_vec.emplace_back(
+          concept_id, std::vector<::ash::local_search_service::Content>());
       result_id_to_search_concept_.erase(it);
     }
   }
diff --git a/ash/webui/personalization_app/search/search_tag_registry.h b/ash/webui/personalization_app/search/search_tag_registry.h
index cf33512b..ea2348d 100644
--- a/ash/webui/personalization_app/search/search_tag_registry.h
+++ b/ash/webui/personalization_app/search/search_tag_registry.h
@@ -21,14 +21,16 @@
 #include "components/prefs/pref_change_registrar.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
+// TODO(https://crbug.com/1164001): move forward declaration to ash.
+namespace chromeos {
+namespace local_search_service {
+class LocalSearchServiceProxy;
+}  // namespace local_search_service
+}  // namespace chromeos
+
 class PrefService;
 
 namespace ash {
-
-namespace local_search_service {
-class LocalSearchServiceProxy;
-}
-
 namespace personalization_app {
 
 class SearchTagRegistry : public EnterprisePolicyDelegate::Observer {
@@ -42,7 +44,8 @@
   using SearchConceptUpdates = std::map<const SearchConcept*, bool>;
 
   SearchTagRegistry(
-      local_search_service::LocalSearchServiceProxy& local_search_service_proxy,
+      ::chromeos::local_search_service::LocalSearchServiceProxy&
+          local_search_service_proxy,
       PrefService* pref_service,
       std::unique_ptr<EnterprisePolicyDelegate> enterprise_policy_delegate);
 
@@ -75,7 +78,7 @@
       bool is_enterprise_managed) override;
 
   base::ObserverList<Observer> observer_list_;
-  mojo::Remote<local_search_service::mojom::Index> index_remote_;
+  mojo::Remote<::chromeos::local_search_service::mojom::Index> index_remote_;
   std::map<std::string, const SearchConcept*> result_id_to_search_concept_;
   raw_ptr<PrefService> pref_service_;
   std::unique_ptr<EnterprisePolicyDelegate> enterprise_policy_delegate_;
diff --git a/ash/wm/desks/templates/saved_desk_library_view.cc b/ash/wm/desks/templates/saved_desk_library_view.cc
index 1725bf8..acfb063 100644
--- a/ash/wm/desks/templates/saved_desk_library_view.cc
+++ b/ash/wm/desks/templates/saved_desk_library_view.cc
@@ -20,6 +20,8 @@
 #include "ash/wm/desks/templates/saved_desk_name_view.h"
 #include "ash/wm/desks/templates/saved_desk_util.h"
 #include "ash/wm/overview/overview_controller.h"
+#include "ash/wm/overview/overview_grid.h"
+#include "ash/wm/overview/overview_grid_event_handler.h"
 #include "ash/wm/overview/rounded_label.h"
 #include "base/notreached.h"
 #include "ui/aura/window.h"
@@ -116,7 +118,8 @@
 // children.
 class SavedDeskLibraryWindowTargeter : public aura::WindowTargeter {
  public:
-  SavedDeskLibraryWindowTargeter(SavedDeskLibraryView* owner) : owner_(owner) {}
+  explicit SavedDeskLibraryWindowTargeter(SavedDeskLibraryView* owner)
+      : owner_(owner) {}
   SavedDeskLibraryWindowTargeter(const SavedDeskLibraryWindowTargeter&) =
       delete;
   SavedDeskLibraryWindowTargeter& operator=(
@@ -125,19 +128,30 @@
   // aura::WindowTargeter:
   bool SubtreeShouldBeExploredForEvent(aura::Window* window,
                                        const ui::LocatedEvent& event) override {
-    // Process the event it is for scrolling.
-    if (event.IsMouseWheelEvent())
-      return true;
-
-    // Check if the located event intersects with the library's children.
     // Convert to screen coordinate.
     gfx::Point screen_location;
+    gfx::Rect screen_bounds = owner_->GetBoundsInScreen();
     if (event.target()) {
       screen_location = event.target()->GetScreenLocation(event);
     } else {
       screen_location = event.root_location();
       wm::ConvertPointToScreen(window->GetRootWindow(), &screen_location);
     }
+
+    // Do not process if it's not on the library view.
+    if (!screen_bounds.Contains(screen_location))
+      return false;
+
+    // Process the event if it is for scrolling.
+    if (event.IsMouseWheelEvent() || event.IsScrollEvent() ||
+        event.IsScrollGestureEvent()) {
+      return true;
+    }
+
+    // Process the event if it is touch.
+    if (event.IsTouchEvent())
+      return true;
+
     // Process the event if it intersects with grid items.
     if (owner_->IntersectsWithUi(screen_location))
       return true;
@@ -409,6 +423,10 @@
     return;
   }
 
+  const gfx::Point screen_location =
+      event->target() ? event->target()->GetScreenLocation(*event)
+                      : event->root_location();
+
   switch (event->type()) {
     case ui::ET_MOUSE_MOVED:
     case ui::ET_MOUSE_ENTERED:
@@ -416,15 +434,33 @@
     case ui::ET_MOUSE_EXITED:
     case ui::ET_GESTURE_LONG_PRESS:
     case ui::ET_GESTURE_LONG_TAP: {
-      const gfx::Point screen_location =
-          event->target() ? event->target()->GetScreenLocation(*event)
-                          : event->root_location();
       for (auto* grid_view : grid_views()) {
         for (SavedDeskItemView* grid_item : grid_view->grid_items())
           grid_item->UpdateHoverButtonsVisibility(screen_location, is_touch);
       }
       break;
     }
+    case ui::ET_GESTURE_TAP:
+      // When it's a tap outside grid items and the feedback button, it should
+      // either commit the name change or exit the overview mode. Currently
+      // those are handled in `OverviewGrid` for both saved desk library view
+      // and desk bar view. `OverviewGridEventHandler::HandleClickOrTap()` is
+      // explicitly invoked here because `ScrollBar::OnGestureEvent()` would eat
+      // tap event. With this, it would lose the gesture-triggered context menu
+      // in saved desk library view. Please see crbug.com/1339100.
+      // TODO(crbug.com/1341128): Investigate if we can enable the context menu
+      // via long-press in library page.
+      if (!IntersectsWithUi(screen_location)) {
+        Shell::Get()
+            ->overview_controller()
+            ->overview_session()
+            ->GetGridWithRootWindow(widget_window->GetRootWindow())
+            ->grid_event_handler()
+            ->HandleClickOrTap(event);
+        event->StopPropagation();
+        event->SetHandled();
+      }
+      break;
     default:
       break;
   }
diff --git a/ash/wm/overview/overview_grid_event_handler.cc b/ash/wm/overview/overview_grid_event_handler.cc
index 6b9bc93..c2b3b766 100644
--- a/ash/wm/overview/overview_grid_event_handler.cc
+++ b/ash/wm/overview/overview_grid_event_handler.cc
@@ -82,6 +82,14 @@
     return;
   }
 
+  // TODO(crbug.com/1341128): Enable context menu via long-press in library page
+  // `SavedDeskLibraryView` will take over gesture event if it's active. When
+  // it's `ET_GESTURE_TAP`, here it does not set event to handled, and thus
+  // `HandleClickOrTap()` would be executed from
+  // `SavedDeskLibraryView::OnLocatedEvent()`.
+  if (grid_->IsShowingDesksTemplatesGrid())
+    return;
+
   switch (event->type()) {
     case ui::ET_GESTURE_TAP: {
       HandleClickOrTap(event);
diff --git a/ash/wm/overview/overview_grid_event_handler.h b/ash/wm/overview/overview_grid_event_handler.h
index 1b5dcc9..334c15b 100644
--- a/ash/wm/overview/overview_grid_event_handler.h
+++ b/ash/wm/overview/overview_grid_event_handler.h
@@ -33,6 +33,8 @@
   OverviewGridEventHandler& operator=(const OverviewGridEventHandler&) = delete;
   ~OverviewGridEventHandler() override;
 
+  void HandleClickOrTap(ui::Event* event);
+
   // ui::EventHandler:
   void OnMouseEvent(ui::MouseEvent* event) override;
   void OnGestureEvent(ui::GestureEvent* event) override;
@@ -40,8 +42,6 @@
   bool IsFlingInProgressForTesting() const { return !!fling_handler_; }
 
  private:
-  void HandleClickOrTap(ui::Event* event);
-
   void HandleFlingScroll(ui::GestureEvent* event);
 
   bool OnFlingStep(float offset);
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index a664fbfd..7633d34 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -783,7 +783,7 @@
     Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
   if (Shell::Get()->accessibility_controller())
     Shell::Get()->accessibility_controller()->RemoveObserver(this);
-  EndSplitView();
+  EndSplitView(EndReason::kRootWindowDestroyed);
 }
 
 bool SplitViewController::InSplitViewMode() const {
@@ -1316,8 +1316,11 @@
   // the resize. This can happen, for example, on the transition back to
   // clamshell mode or when a task is minimized during a resize. Likewise, if
   // split view is ending during the divider snap animation, then clean that up.
+  // But if the split view is ending due to the destroy of `root_window_`, we
+  // should skip the resize.
   const bool is_divider_animating = IsDividerAnimating();
-  if (is_resizing_ || is_divider_animating) {
+  if ((is_resizing_ || is_divider_animating) &&
+      end_reason != EndReason::kRootWindowDestroyed) {
     is_resizing_ = false;
     if (is_divider_animating) {
       // Don't call StopAndShoveAnimatedDivider as it will call observers.
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h
index b449ba0c..97bf914 100644
--- a/ash/wm/splitview/split_view_controller.h
+++ b/ash/wm/splitview/split_view_controller.h
@@ -78,6 +78,9 @@
     // Splitview is being ended due to a change in Virtual Desks, such as
     // switching desks or removing a desk.
     kDesksChange,
+    // Splitview is being ended due to the `root_window_` is destroyed and the
+    // SplitViewController is being destroyed.
+    kRootWindowDestroyed,
   };
 
   // The behaviors of split view are very different when in tablet mode and in
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index 550f158..f392f3e 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -1038,6 +1038,48 @@
   base::RunLoop().RunUntilIdle();
 }
 
+// Verify that disconnecting a display while dragging the split view divider in
+// it in tablet mode won't lead to a crash. Regression test for
+// https://crbug.com/1316892.
+TEST_F(SplitViewControllerTest,
+       DisplayDisconnectionWhileDraggingSplitDividerInTabletMode) {
+  ui::ScopedAnimationDurationScaleMode animation_scale(
+      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
+
+  UpdateDisplay("800x600,800x600");
+
+  Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
+  EXPECT_TRUE(EnterOverview());
+
+  // Turn off the display mirror mode.
+  Shell::Get()->display_manager()->SetMirrorMode(display::MirrorMode::kOff,
+                                                 absl::nullopt);
+
+  // Create a window on the secondary display.
+  std::unique_ptr<aura::Window> w(
+      CreateTestWindowInShellWithBounds(gfx::Rect(900, 0, 100, 100)));
+
+  // Snap the window on the second display.
+  auto* split_view_controller = SplitViewController::Get(w->GetRootWindow());
+  split_view_controller->SnapWindow(w.get(), SplitViewController::LEFT);
+  auto* split_view_divider = split_view_controller->split_view_divider();
+  ASSERT_TRUE(split_view_divider);
+
+  auto* event_generator = GetEventGenerator();
+  const gfx::Point divider_center_pointer =
+      split_view_divider->GetDividerBoundsInScreen(/*is_dragging=*/false)
+          .CenterPoint();
+  event_generator->PressTouch(divider_center_pointer);
+
+  // Drag the split view divider without releasing the drag.
+  const gfx::Vector2d delta(100, 0);
+  event_generator->MoveTouch(divider_center_pointer + delta);
+
+  // Now disconnect the second display, verify there's no crash.
+  UpdateDisplay("800x600");
+  base::RunLoop().RunUntilIdle();
+}
+
 // Tests that the bounds of the snapped windows and divider are adjusted when
 // the screen display configuration changes.
 TEST_F(SplitViewControllerTest, DisplayConfigurationChangeTest) {
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
index 3f76e094..2b541d1d 100644
--- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc
+++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
@@ -312,6 +312,7 @@
   switch (SplitViewController::Get(primary_root)->end_reason()) {
     case SplitViewController::EndReason::kNormal:
     case SplitViewController::EndReason::kUnsnappableWindowActivated:
+    case SplitViewController::EndReason::kRootWindowDestroyed:
       break;
     case SplitViewController::EndReason::kHomeLauncherPressed:
     case SplitViewController::EndReason::kActiveUserChanged:
diff --git a/base/allocator/partition_allocator/page_allocator.h b/base/allocator/partition_allocator/page_allocator.h
index b21d602..1052335 100644
--- a/base/allocator/partition_allocator/page_allocator.h
+++ b/base/allocator/partition_allocator/page_allocator.h
@@ -329,35 +329,4 @@
 
 }  // namespace partition_alloc
 
-namespace base {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::AllocPages;
-using ::partition_alloc::AllocPagesWithAlignOffset;
-using ::partition_alloc::DecommitAndZeroSystemPages;
-using ::partition_alloc::DecommitSystemPages;
-using ::partition_alloc::DecommittedMemoryIsAlwaysZeroed;
-using ::partition_alloc::DiscardSystemPages;
-using ::partition_alloc::FreePages;
-using ::partition_alloc::GetAllocPageErrorCode;
-using ::partition_alloc::GetTotalMappedSize;
-using ::partition_alloc::HasReservationForTesting;
-using ::partition_alloc::NextAlignedWithOffset;
-using ::partition_alloc::PageAccessibilityConfiguration;
-using ::partition_alloc::PageAccessibilityDisposition;
-using ::partition_alloc::PageTag;
-using ::partition_alloc::RecommitSystemPages;
-using ::partition_alloc::ReleaseReservation;
-using ::partition_alloc::ReserveAddressSpace;
-using ::partition_alloc::RoundDownToPageAllocationGranularity;
-using ::partition_alloc::RoundDownToSystemPage;
-using ::partition_alloc::RoundUpToPageAllocationGranularity;
-using ::partition_alloc::RoundUpToSystemPage;
-using ::partition_alloc::SetSystemPagesAccess;
-using ::partition_alloc::TryRecommitSystemPages;
-using ::partition_alloc::TrySetSystemPagesAccess;
-
-}  // namespace base
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_H_
diff --git a/base/allocator/partition_allocator/partition_alloc_forward.h b/base/allocator/partition_allocator/partition_alloc_forward.h
index 3c573caa..b4b9270 100644
--- a/base/allocator/partition_allocator/partition_alloc_forward.h
+++ b/base/allocator/partition_allocator/partition_alloc_forward.h
@@ -62,14 +62,6 @@
 
 }  // namespace partition_alloc
 
-namespace base {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::PartitionRoot;
-
-}  // namespace base
-
 // From https://clang.llvm.org/docs/AttributeReference.html#malloc:
 //
 // The malloc attribute indicates that the function acts like a system memory
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index a4b02e0..41bcd6e20 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -97,7 +97,7 @@
   //
   // Set to 4GiB, since we have 2GiB Android devices where tests flakily fail
   // (e.g. Nexus 5X, crbug.com/1191195).
-  return base::SysInfo::AmountOfPhysicalMemory() >= 4000ULL * 1024 * 1024;
+  return base::SysInfo::AmountOfPhysicalMemory() >= 4000LL * 1024 * 1024;
 }
 
 bool SetAddressSpaceLimit() {
diff --git a/base/allocator/partition_allocator/partition_oom.h b/base/allocator/partition_allocator/partition_oom.h
index 56f4cf4f..4a521d25 100644
--- a/base/allocator/partition_allocator/partition_oom.h
+++ b/base/allocator/partition_allocator/partition_oom.h
@@ -37,24 +37,4 @@
 
 }  // namespace partition_alloc
 
-namespace base {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::OomFunction;
-
-namespace internal {
-
-using ::partition_alloc::internal::g_oom_handling_function;
-using ::partition_alloc::internal::PartitionExcessiveAllocationSize;
-#if !defined(ARCH_CPU_64_BITS)
-using ::partition_alloc::internal::PartitionOutOfMemoryWithLargeVirtualSize;
-using ::partition_alloc::internal::
-    PartitionOutOfMemoryWithLotsOfUncommitedPages;
-#endif
-
-}  // namespace internal
-
-}  // namespace base
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_OOM_H_
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h
index d28712c..ea21b108 100644
--- a/base/allocator/partition_allocator/partition_page.h
+++ b/base/allocator/partition_allocator/partition_page.h
@@ -902,23 +902,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::AllocationStateMap;
-using ::partition_alloc::internal::CommittedStateBitmapSize;
-using ::partition_alloc::internal::IterateSlotSpans;
-using ::partition_alloc::internal::PartitionPage;
-using ::partition_alloc::internal::PartitionSuperPageExtentEntry;
-using ::partition_alloc::internal::PartitionSuperPageToExtent;
-using ::partition_alloc::internal::PartitionSuperPageToMetadataArea;
-using ::partition_alloc::internal::ReservedStateBitmapSize;
-using ::partition_alloc::internal::SlotSpanMetadata;
-using ::partition_alloc::internal::StateBitmapFromAddr;
-using ::partition_alloc::internal::SuperPageStateBitmap;
-using ::partition_alloc::internal::SuperPageStateBitmapAddr;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_PAGE_H_
diff --git a/base/allocator/partition_allocator/partition_tls.h b/base/allocator/partition_allocator/partition_tls.h
index 5444a32..f086ca6 100644
--- a/base/allocator/partition_allocator/partition_tls.h
+++ b/base/allocator/partition_allocator/partition_tls.h
@@ -140,18 +140,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::PartitionTlsCreate;
-using ::partition_alloc::internal::PartitionTlsGet;
-using ::partition_alloc::internal::PartitionTlsKey;
-using ::partition_alloc::internal::PartitionTlsSet;
-#if BUILDFLAG(IS_WIN)
-using ::partition_alloc::internal::PartitionTlsSetOnDllProcessDetach;
-#endif  // BUILDFLAG(IS_WIN)
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TLS_H_
diff --git a/base/android/thread_instruction_count.cc b/base/android/thread_instruction_count.cc
index 9d3c32e87..79db88c2 100644
--- a/base/android/thread_instruction_count.cc
+++ b/base/android/thread_instruction_count.cc
@@ -65,10 +65,12 @@
 
 }  // namespace
 
+// static
 bool ThreadInstructionCount::IsSupported() {
   return InstructionCounterFdForCurrentThread() > 0;
 }
 
+// static
 ThreadInstructionCount ThreadInstructionCount::Now() {
   DCHECK(IsSupported());
   int fd = InstructionCounterFdForCurrentThread();
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc
index ca2629d..c0a5b6e75 100644
--- a/base/memory/discardable_shared_memory.cc
+++ b/base/memory/discardable_shared_memory.cc
@@ -486,7 +486,7 @@
     DPLOG(ERROR) << "madvise() failed";
   }
 #else   // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)
-  DiscardSystemPages(
+  partition_alloc::DiscardSystemPages(
       static_cast<char*>(shared_memory_mapping_.memory()) + offset, length);
 #endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)
 }
diff --git a/base/memory/mtecheckedptr.md b/base/memory/mtecheckedptr.md
new file mode 100644
index 0000000..5420900
--- /dev/null
+++ b/base/memory/mtecheckedptr.md
@@ -0,0 +1,87 @@
+# MTECheckedPtr Reference
+
+*** note
+**TL;DR** - You don't need to worry about MTECheckedPtr.
+
+For now, this is a matter solely for the Chrome Memory Team to deal
+with. The associated TODOs are informational, not actionable. They
+will eventually go away.
+***
+
+MTECheckedPtr is an alternative implementation of `raw_ptr<T>`.
+The canonical implementation of `raw_ptr<T>` is currently BackupRefPtr.
+MTECheckedPtr is not enabled by default for anybody, so you should
+not be impacted by anything related.
+
+## Description
+
+***aside
+This is the brief version. Googlers can search internally for further
+reading.
+***
+
+MTECheckedPtr is a Chromium-specific implementation of ARM's
+[MTE concept][arm-mte]. When MTECheckedPtr is enabled,
+
+*   each `raw_ptr<T>` is assigned a tag,
+*   each tag is stored in the top bits of each `raw_ptr<T>`
+    and inside PartitionAlloc metadata, and
+*   the tags are compared on each dereference.
+
+When an MTECheckedPtr is `free()`d, PartitionAlloc changes the
+internally associated tag. Subsequent accesses (e.g. from a
+laundered pointer with the old tag value) will not match the new
+tag value, at which point PartitionAlloc triggers an immediate crash.
+
+Subjectively, MTECheckedPtr is less forgiving than BackupRefPtr, and
+work is ongoing to make CQ pass when enabled. (See the long train of CLs
+beginning from https://crbug.com/1298696#c12.)
+
+## Informational TODOs
+
+If you've come to investigate comments like
+
+```
+// TODO(crbug.com/1298696): Breaks foo_unittests.
+```
+
+or
+
+```
+// TODO(crbug.com/1298696): foo_unittests breaks with MTECheckedPtr
+// enabled. Triage.
+```
+
+This just means that there is a potential UaF in the associated
+`raw_ptr<T>`, surfaced by running `foo_unittests`. The Memory Team has
+disabled protection (only when `raw_ptr<T>` is MTECheckedPtr, which is
+not true unless explicitly enabled) on the same (e.g.
+`raw_ptr<T, DegradeToNoOpWhenMTE>`).
+
+When time permits, the Memory Team will look at these issues (but there
+are rather a lot of them), triage them, and see what can be fixed.
+
+In the meantime, code OWNERS need only note that these comments are
+*informational* and *not actionable*. They have a similar standing
+as `DanglingUntriaged` (see
+[dangling_ptr.md](../../docs/dangling_ptr.md)) and co-opt the same
+template parameter.
+
+## Appendix: Degradation Template Parameters
+
+As described in `raw_ptr.h`, we use the following `D`s when given
+a particular `raw_ptr<T, D>`.
+
+When MTECheckedPtr is not enabled (the default):
+
+*   `DegradeToNoOpWhenMTE` - No effect. Uses the default `raw_ptr<T>`
+    implementation (currently BackupRefPtr).
+*   `DanglingUntriagedDegradeToNoOpWhenMTE` - No effect. Uses the
+    default `raw_ptr<T>` implementation (currently BackupRefPtr),
+    but permits dangling pointers.
+
+When MTECheckedPtr *is* enabled (not the default for anybody),
+both of the above degrade the `raw_ptr<T, D>` into the no-op version
+of `raw_ptr`.
+
+[arm-mte]: https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/enhancing-memory-safety
diff --git a/base/memory/platform_shared_memory_mapper_win.cc b/base/memory/platform_shared_memory_mapper_win.cc
index 92808ec8..72156806 100644
--- a/base/memory/platform_shared_memory_mapper_win.cc
+++ b/base/memory/platform_shared_memory_mapper_win.cc
@@ -37,7 +37,7 @@
         static_cast<DWORD>(offset >> 32), static_cast<DWORD>(offset), size);
     if (address)
       break;
-    ReleaseReservation();
+    partition_alloc::ReleaseReservation();
   }
   if (!address) {
     DPLOG(ERROR) << "Failed executing MapViewOfFile";
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc
index 535d784..c0541f59 100644
--- a/base/memory/raw_ptr_unittest.cc
+++ b/base/memory/raw_ptr_unittest.cc
@@ -1660,6 +1660,10 @@
   uint64_t* unwrapped_ptr = new uint64_t[6];
   CountingRawPtr<uint64_t> ptr = unwrapped_ptr;
 
+  // This is a non-fixture test, so we need to unset all
+  // counters manually.
+  RawPtrCountingImpl::ClearCounters();
+
   // This is unwrapped, but still useful for ensuring that the
   // shift is sized in `uint64_t`s.
   auto original_addr = reinterpret_cast<uintptr_t>(ptr.get());
diff --git a/base/process/memory.cc b/base/process/memory.cc
index be6cdfb..4e38617 100644
--- a/base/process/memory.cc
+++ b/base/process/memory.cc
@@ -52,7 +52,7 @@
 namespace internal {
 bool ReleaseAddressSpaceReservation() {
 #if BUILDFLAG(USE_PARTITION_ALLOC)
-  return ReleaseReservation();
+  return partition_alloc::ReleaseReservation();
 #else
   return false;
 #endif
diff --git a/base/process/memory_unittest.cc b/base/process/memory_unittest.cc
index 6de658d..f043c9e9 100644
--- a/base/process/memory_unittest.cc
+++ b/base/process/memory_unittest.cc
@@ -559,17 +559,17 @@
 
 void TestAllocationsReleaseReservation(void* (*alloc_fn)(size_t),
                                        void (*free_fn)(void*)) {
-  base::ReleaseReservation();
+  partition_alloc::ReleaseReservation();
   base::EnableTerminationOnOutOfMemory();
 
   constexpr size_t kMiB = 1 << 20;
   constexpr size_t kReservationSize = 512 * kMiB;  // MiB.
 
   size_t reservation_size = kReservationSize;
-  while (!base::ReserveAddressSpace(reservation_size)) {
+  while (!partition_alloc::ReserveAddressSpace(reservation_size)) {
     reservation_size -= 16 * kMiB;
   }
-  ASSERT_TRUE(base::HasReservationForTesting());
+  ASSERT_TRUE(partition_alloc::HasReservationForTesting());
   ASSERT_GT(reservation_size, 0u);
 
   // Allocate a large area at a time to bump into address space exhaustion
@@ -593,7 +593,7 @@
     // was dropped instead of crashing.
     //
     // Meaning that the test is either successful, or crashes.
-    if (!base::HasReservationForTesting())
+    if (!partition_alloc::HasReservationForTesting())
       break;
   }
 
diff --git a/base/process/process_metrics_unittest.cc b/base/process/process_metrics_unittest.cc
index 4a589f1..8ab3e9b1 100644
--- a/base/process/process_metrics_unittest.cc
+++ b/base/process/process_metrics_unittest.cc
@@ -207,11 +207,11 @@
   EXPECT_EQ(meminfo.shmem, 140204);
   EXPECT_EQ(meminfo.slab, 54212);
 #endif
-  EXPECT_EQ(355725u,
+  EXPECT_EQ(355725,
             base::SysInfo::AmountOfAvailablePhysicalMemory(meminfo) / 1024);
   // Simulate as if there is no MemAvailable.
   meminfo.available = 0;
-  EXPECT_EQ(374448u,
+  EXPECT_EQ(374448,
             base::SysInfo::AmountOfAvailablePhysicalMemory(meminfo) / 1024);
   meminfo = {};
   EXPECT_TRUE(ParseProcMeminfo(valid_input2, &meminfo));
@@ -223,7 +223,7 @@
   EXPECT_EQ(meminfo.swap_total, 524280);
   EXPECT_EQ(meminfo.swap_free, 524200);
   EXPECT_EQ(meminfo.dirty, 4);
-  EXPECT_EQ(69936u,
+  EXPECT_EQ(69936,
             base::SysInfo::AmountOfAvailablePhysicalMemory(meminfo) / 1024);
 }
 
diff --git a/base/profiler/stack_copier_signal.cc b/base/profiler/stack_copier_signal.cc
index bc2ecb0..1cf08fc 100644
--- a/base/profiler/stack_copier_signal.cc
+++ b/base/profiler/stack_copier_signal.cc
@@ -37,7 +37,7 @@
     // futex() can wake up spuriously if this memory address was previously used
     // for a pthread mutex. So, also check the condition.
     while (true) {
-      long res =
+      int res =
           syscall(SYS_futex, futex_int_ptr(), FUTEX_WAIT | FUTEX_PRIVATE_FLAG,
                   0, nullptr, nullptr, 0);
       if (futex_.load(std::memory_order_acquire) != 0)
diff --git a/base/sync_socket_posix.cc b/base/sync_socket_posix.cc
index 1b75de7..92d47fc 100644
--- a/base/sync_socket_posix.cc
+++ b/base/sync_socket_posix.cc
@@ -23,7 +23,6 @@
 #include "base/check_op.h"
 #include "base/containers/span.h"
 #include "base/files/file_util.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "build/build_config.h"
 
@@ -175,7 +174,8 @@
     // If there is an error in ioctl, signal that the channel would block.
     return 0;
   }
-  return checked_cast<size_t>(number_chars);
+  DCHECK_GE(number_chars, 0);
+  return number_chars;
 }
 
 bool SyncSocket::IsValid() const {
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc
index 7b068fb..a4c99975 100644
--- a/base/system/sys_info.cc
+++ b/base/system/sys_info.cc
@@ -23,21 +23,21 @@
 namespace {
 #if BUILDFLAG(IS_IOS)
 // For M99, 45% of devices have 2GB of RAM, and 55% have more.
-constexpr uint64_t kLowMemoryDeviceThresholdMB = 1024;
+constexpr int64_t kLowMemoryDeviceThresholdMB = 1024;
 #else
 // Updated Desktop default threshold to match the Android 2021 definition.
-constexpr uint64_t kLowMemoryDeviceThresholdMB = 2048;
+constexpr int64_t kLowMemoryDeviceThresholdMB = 2048;
 #endif
 }  // namespace
 
 // static
-uint64_t SysInfo::AmountOfPhysicalMemory() {
+int64_t SysInfo::AmountOfPhysicalMemory() {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableLowEndDeviceMode)) {
     // Keep using 512MB as the simulated RAM amount for when users or tests have
     // manually enabled low-end device mode. Note this value is different from
     // the threshold used for low end devices.
-    constexpr uint64_t kSimulatedMemoryForEnableLowEndDeviceMode =
+    constexpr int64_t kSimulatedMemoryForEnableLowEndDeviceMode =
         512 * 1024 * 1024;
     return std::min(kSimulatedMemoryForEnableLowEndDeviceMode,
                     AmountOfPhysicalMemoryImpl());
@@ -47,14 +47,14 @@
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemory() {
+int64_t SysInfo::AmountOfAvailablePhysicalMemory() {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableLowEndDeviceMode)) {
     // Estimate the available memory by subtracting our memory used estimate
     // from the fake |kLowMemoryDeviceThresholdMB| limit.
-    uint64_t memory_used =
+    int64_t memory_used =
         AmountOfPhysicalMemoryImpl() - AmountOfAvailablePhysicalMemoryImpl();
-    uint64_t memory_limit = kLowMemoryDeviceThresholdMB * 1024 * 1024;
+    int64_t memory_limit = kLowMemoryDeviceThresholdMB * 1024 * 1024;
     // std::min ensures no underflow, as |memory_used| can be > |memory_limit|.
     return memory_limit - std::min(memory_used, memory_limit);
   }
@@ -82,8 +82,7 @@
     return false;
 
   int ram_size_mb = SysInfo::AmountOfPhysicalMemoryMB();
-  return ram_size_mb > 0 &&
-         static_cast<uint64_t>(ram_size_mb) <= kLowMemoryDeviceThresholdMB;
+  return (ram_size_mb > 0 && ram_size_mb <= kLowMemoryDeviceThresholdMB);
 }
 
 // static
diff --git a/base/system/sys_info.h b/base/system/sys_info.h
index 963eb48..1cd1231 100644
--- a/base/system/sys_info.h
+++ b/base/system/sys_info.h
@@ -34,19 +34,19 @@
   // Return the number of bytes of physical memory on the current machine.
   // If low-end device mode is manually enabled via command line flag, this
   // will return the lesser of the actual physical memory, or 512MB.
-  static uint64_t AmountOfPhysicalMemory();
+  static int64_t AmountOfPhysicalMemory();
 
   // Return the number of bytes of current available physical memory on the
   // machine.
   // (The amount of memory that can be allocated without any significant
   // impact on the system. It can lead to freeing inactive file-backed
   // and/or speculative file-backed memory).
-  static uint64_t AmountOfAvailablePhysicalMemory();
+  static int64_t AmountOfAvailablePhysicalMemory();
 
   // Return the number of bytes of virtual memory of this process. A return
   // value of zero means that there is no limit on the available virtual
   // memory.
-  static uint64_t AmountOfVirtualMemory();
+  static int64_t AmountOfVirtualMemory();
 
   // Return the number of megabytes of physical memory on the current machine.
   static int AmountOfPhysicalMemoryMB() {
@@ -215,14 +215,14 @@
   FRIEND_TEST_ALL_PREFIXES(SysInfoTest, AmountOfAvailablePhysicalMemory);
   FRIEND_TEST_ALL_PREFIXES(debug::SystemMetricsTest, ParseMeminfo);
 
-  static uint64_t AmountOfPhysicalMemoryImpl();
-  static uint64_t AmountOfAvailablePhysicalMemoryImpl();
+  static int64_t AmountOfPhysicalMemoryImpl();
+  static int64_t AmountOfAvailablePhysicalMemoryImpl();
   static bool IsLowEndDeviceImpl();
   static HardwareInfo GetHardwareInfoSync();
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
     BUILDFLAG(IS_AIX)
-  static uint64_t AmountOfAvailablePhysicalMemory(
+  static int64_t AmountOfAvailablePhysicalMemory(
       const SystemMemoryInfoKB& meminfo);
 #endif
 };
diff --git a/base/system/sys_info_fuchsia.cc b/base/system/sys_info_fuchsia.cc
index c555946..25396a8 100644
--- a/base/system/sys_info_fuchsia.cc
+++ b/base/system/sys_info_fuchsia.cc
@@ -91,12 +91,12 @@
 }  // namespace
 
 // static
-uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
   return zx_system_get_physmem();
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
   // TODO(https://crbug.com/986608): Implement this.
   NOTIMPLEMENTED_LOG_ONCE();
   return 0;
@@ -108,7 +108,7 @@
 }
 
 // static
-uint64_t SysInfo::AmountOfVirtualMemory() {
+int64_t SysInfo::AmountOfVirtualMemory() {
   return 0;
 }
 
diff --git a/base/system/sys_info_ios.mm b/base/system/sys_info_ios.mm
index 2b523e5..e278a18 100644
--- a/base/system/sys_info_ios.mm
+++ b/base/system/sys_info_ios.mm
@@ -14,7 +14,6 @@
 #include "base/check_op.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/notreached.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/process/process_metrics.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -116,7 +115,7 @@
 }
 
 // static
-uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
   struct host_basic_info hostinfo;
   mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
   base::mac::ScopedMachSendRight host(mach_host_self());
@@ -127,17 +126,17 @@
     return 0;
   }
   DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
-  return hostinfo.max_mem;
+  return static_cast<int64_t>(hostinfo.max_mem);
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
   SystemMemoryInfoKB info;
   if (!GetSystemMemoryInfo(&info))
     return 0;
   // We should add inactive file-backed memory also but there is no such
   // information from iOS unfortunately.
-  return checked_cast<uint64_t>(info.free + info.speculative) * 1024;
+  return static_cast<int64_t>(info.free + info.speculative) * 1024;
 }
 
 // static
diff --git a/base/system/sys_info_linux.cc b/base/system/sys_info_linux.cc
index 1b30427..881db6f5 100644
--- a/base/system/sys_info_linux.cc
+++ b/base/system/sys_info_linux.cc
@@ -24,20 +24,22 @@
 
 namespace {
 
-uint64_t AmountOfMemory(int pages_name) {
+int64_t AmountOfMemory(int pages_name) {
   long pages = sysconf(pages_name);
   long page_size = sysconf(_SC_PAGESIZE);
-  if (pages < 0 || page_size < 0)
+  if (pages == -1 || page_size == -1) {
+    NOTREACHED();
     return 0;
-  return static_cast<uint64_t>(pages) * static_cast<uint64_t>(page_size);
+  }
+  return static_cast<int64_t>(pages) * page_size;
 }
 
-uint64_t AmountOfPhysicalMemory() {
+int64_t AmountOfPhysicalMemory() {
   return AmountOfMemory(_SC_PHYS_PAGES);
 }
 
 base::LazyInstance<
-    base::internal::LazySysInfoValue<uint64_t, AmountOfPhysicalMemory>>::Leaky
+    base::internal::LazySysInfoValue<int64_t, AmountOfPhysicalMemory>>::Leaky
     g_lazy_physical_memory = LAZY_INSTANCE_INITIALIZER;
 
 }  // namespace
@@ -45,12 +47,12 @@
 namespace base {
 
 // static
-uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
   return g_lazy_physical_memory.Get().value();
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
   SystemMemoryInfoKB info;
   if (!GetSystemMemoryInfo(&info))
     return 0;
@@ -58,16 +60,16 @@
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemory(
+int64_t SysInfo::AmountOfAvailablePhysicalMemory(
     const SystemMemoryInfoKB& info) {
   // See details here:
   // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
   // The fallback logic (when there is no MemAvailable) would be more precise
   // if we had info about zones watermarks (/proc/zoneinfo).
-  int res_kb = info.available != 0
-                   ? info.available - info.active_file
-                   : info.free + info.reclaimable + info.inactive_file;
-  return checked_cast<uint64_t>(res_kb) * 1024;
+  int64_t res_kb = info.available != 0
+                       ? info.available - info.active_file
+                       : info.free + info.reclaimable + info.inactive_file;
+  return res_kb * 1024;
 }
 
 // static
diff --git a/base/system/sys_info_mac.mm b/base/system/sys_info_mac.mm
index 5cc7636..dc52dea1 100644
--- a/base/system/sys_info_mac.mm
+++ b/base/system/sys_info_mac.mm
@@ -16,7 +16,6 @@
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/notreached.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/process/process_metrics.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -75,7 +74,7 @@
 }
 
 // static
-uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
   struct host_basic_info hostinfo;
   mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
   base::mac::ScopedMachSendRight host(mach_host_self());
@@ -86,17 +85,17 @@
     return 0;
   }
   DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
-  return hostinfo.max_mem;
+  return static_cast<int64_t>(hostinfo.max_mem);
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
   SystemMemoryInfoKB info;
   if (!GetSystemMemoryInfo(&info))
     return 0;
   // We should add inactive file-backed memory also but there is no such
   // information from Mac OS unfortunately.
-  return checked_cast<uint64_t>(info.free + info.speculative) * 1024;
+  return static_cast<int64_t>(info.free + info.speculative) * 1024;
 }
 
 // static
diff --git a/base/system/sys_info_openbsd.cc b/base/system/sys_info_openbsd.cc
index a32f06ee..8849960 100644
--- a/base/system/sys_info_openbsd.cc
+++ b/base/system/sys_info_openbsd.cc
@@ -14,12 +14,14 @@
 
 namespace {
 
-uint64_t AmountOfMemory(int pages_name) {
+int64_t AmountOfMemory(int pages_name) {
   long pages = sysconf(pages_name);
   long page_size = sysconf(_SC_PAGESIZE);
-  if (pages < 0 || page_size < 0)
+  if (pages == -1 || page_size == -1) {
+    NOTREACHED();
     return 0;
-  return static_cast<uint64_t>(pages) * static_cast<uint64_t>(page_size);
+  }
+  return static_cast<int64_t>(pages) * page_size;
 }
 
 }  // namespace
@@ -39,12 +41,12 @@
 }
 
 // static
-uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
   return AmountOfMemory(_SC_PHYS_PAGES);
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
   // We should add inactive file-backed memory also but there is no such
   // information from OpenBSD unfortunately.
   return AmountOfMemory(_SC_AVPHYS_PAGES);
diff --git a/base/system/sys_info_posix.cc b/base/system/sys_info_posix.cc
index 7ae2d021..7495c4c5 100644
--- a/base/system/sys_info_posix.cc
+++ b/base/system/sys_info_posix.cc
@@ -17,7 +17,6 @@
 #include "base/files/file_util.h"
 #include "base/lazy_instance.h"
 #include "base/notreached.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/system/sys_info_internal.h"
 #include "base/threading/scoped_blocking_call.h"
@@ -79,7 +78,7 @@
     Leaky g_lazy_number_of_processors = LAZY_INSTANCE_INITIALIZER;
 #endif  // !BUILDFLAG(IS_OPENBSD)
 
-uint64_t AmountOfVirtualMemory() {
+int64_t AmountOfVirtualMemory() {
   struct rlimit limit;
   int result = getrlimit(RLIMIT_DATA, &limit);
   if (result != 0) {
@@ -90,7 +89,7 @@
 }
 
 base::LazyInstance<
-    base::internal::LazySysInfoValue<uint64_t, AmountOfVirtualMemory>>::Leaky
+    base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky
     g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER;
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
@@ -128,14 +127,13 @@
     *available_bytes =
         zero_size_means_unlimited
             ? std::numeric_limits<int64_t>::max()
-            : base::checked_cast<int64_t>(stats.f_bavail * stats.f_frsize);
+            : static_cast<int64_t>(stats.f_bavail) * stats.f_frsize;
   }
 
   if (total_bytes) {
-    *total_bytes =
-        zero_size_means_unlimited
-            ? std::numeric_limits<int64_t>::max()
-            : base::checked_cast<int64_t>(stats.f_blocks * stats.f_frsize);
+    *total_bytes = zero_size_means_unlimited
+                       ? std::numeric_limits<int64_t>::max()
+                       : static_cast<int64_t>(stats.f_blocks) * stats.f_frsize;
   }
   return true;
 }
@@ -151,7 +149,7 @@
 #endif  // !BUILDFLAG(IS_OPENBSD)
 
 // static
-uint64_t SysInfo::AmountOfVirtualMemory() {
+int64_t SysInfo::AmountOfVirtualMemory() {
   return g_lazy_virtual_memory.Get().value();
 }
 
@@ -247,7 +245,7 @@
 
 // static
 size_t SysInfo::VMAllocationGranularity() {
-  return checked_cast<size_t>(getpagesize());
+  return getpagesize();
 }
 
 }  // namespace base
diff --git a/base/system/sys_info_unittest.cc b/base/system/sys_info_unittest.cc
index 6f10cf04..226ef8c2 100644
--- a/base/system/sys_info_unittest.cc
+++ b/base/system/sys_info_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/bind.h"
 #include "base/environment.h"
 #include "base/files/file_util.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/process/process_metrics.h"
 #include "base/run_loop.h"
 #include "base/strings/pattern.h"
@@ -58,10 +57,10 @@
 
 TEST_F(SysInfoTest, AmountOfMem) {
   // We aren't actually testing that it's correct, just that it's sane.
-  EXPECT_GT(SysInfo::AmountOfPhysicalMemory(), 0u);
+  EXPECT_GT(SysInfo::AmountOfPhysicalMemory(), 0);
   EXPECT_GT(SysInfo::AmountOfPhysicalMemoryMB(), 0);
   // The maxmimal amount of virtual memory can be zero which means unlimited.
-  EXPECT_GE(SysInfo::AmountOfVirtualMemory(), 0u);
+  EXPECT_GE(SysInfo::AmountOfVirtualMemory(), 0);
 }
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
@@ -79,7 +78,7 @@
   if (info.available != 0) {
     // If there is MemAvailable from kernel.
     EXPECT_LT(info.available, info.total);
-    const uint64_t amount = SysInfo::AmountOfAvailablePhysicalMemory(info);
+    const int64_t amount = SysInfo::AmountOfAvailablePhysicalMemory(info);
     // We aren't actually testing that it's correct, just that it's sane.
     // Available memory is |free - reserved + reclaimable (inactive, non-free)|.
     // On some android platforms, reserved is a substantial portion.
@@ -89,17 +88,17 @@
 #else
         info.free;
 #endif  // BUILDFLAG(IS_ANDROID)
-    EXPECT_GT(amount, checked_cast<uint64_t>(available) * 1024);
-    EXPECT_LT(amount / 1024, checked_cast<uint64_t>(info.available));
+    EXPECT_GT(amount, static_cast<int64_t>(available) * 1024);
+    EXPECT_LT(amount / 1024, info.available);
     // Simulate as if there is no MemAvailable.
     info.available = 0;
   }
 
   // There is no MemAvailable. Check the fallback logic.
-  const uint64_t amount = SysInfo::AmountOfAvailablePhysicalMemory(info);
+  const int64_t amount = SysInfo::AmountOfAvailablePhysicalMemory(info);
   // We aren't actually testing that it's correct, just that it's sane.
-  EXPECT_GT(amount, checked_cast<uint64_t>(info.free) * 1024);
-  EXPECT_LT(amount / 1024, checked_cast<uint64_t>(info.total));
+  EXPECT_GT(amount, static_cast<int64_t>(info.free) * 1024);
+  EXPECT_LT(amount / 1024, info.total);
 }
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
         // BUILDFLAG(IS_ANDROID)
diff --git a/base/system/sys_info_win.cc b/base/system/sys_info_win.cc
index c881ca5..dd0cc51 100644
--- a/base/system/sys_info_win.cc
+++ b/base/system/sys_info_win.cc
@@ -13,7 +13,6 @@
 #include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/notreached.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/process/process_metrics.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -25,7 +24,7 @@
 
 namespace {
 
-uint64_t AmountOfMemory(DWORDLONG MEMORYSTATUSEX::*memory_field) {
+int64_t AmountOfMemory(DWORDLONG MEMORYSTATUSEX::*memory_field) {
   MEMORYSTATUSEX memory_info;
   memory_info.dwLength = sizeof(memory_info);
   if (!GlobalMemoryStatusEx(&memory_info)) {
@@ -33,7 +32,8 @@
     return 0;
   }
 
-  return memory_info.*memory_field;
+  int64_t rv = static_cast<int64_t>(memory_info.*memory_field);
+  return rv < 0 ? std::numeric_limits<int64_t>::max() : rv;
 }
 
 bool GetDiskSpaceInfo(const base::FilePath& path,
@@ -68,20 +68,20 @@
 }
 
 // static
-uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
   return AmountOfMemory(&MEMORYSTATUSEX::ullTotalPhys);
 }
 
 // static
-uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
+int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
   SystemMemoryInfoKB info;
   if (!GetSystemMemoryInfo(&info))
     return 0;
-  return checked_cast<uint64_t>(info.avail_phys) * 1024;
+  return static_cast<int64_t>(info.avail_phys) * 1024;
 }
 
 // static
-uint64_t SysInfo::AmountOfVirtualMemory() {
+int64_t SysInfo::AmountOfVirtualMemory() {
   return AmountOfMemory(&MEMORYSTATUSEX::ullTotalVirtual);
 }
 
diff --git a/base/third_party/nspr/prtime.cc b/base/third_party/nspr/prtime.cc
index 5d36b5b..88fe1eba5 100644
--- a/base/third_party/nspr/prtime.cc
+++ b/base/third_party/nspr/prtime.cc
@@ -1165,9 +1165,9 @@
 #endif
                   if (secs != (time_t) -1)
                     {
-                    *result_imploded = secs * (PRTime)PR_USEC_PER_SEC;
-                    *result_imploded += result->tm_usec;
-                    return PR_SUCCESS;
+                      *result_imploded = (PRInt64)secs * PR_USEC_PER_SEC;
+                      *result_imploded += result->tm_usec;
+                      return PR_SUCCESS;
                     }
                 }
 
diff --git a/base/threading/hang_watcher.cc b/base/threading/hang_watcher.cc
index 4d65101..8f38b8a8 100644
--- a/base/threading/hang_watcher.cc
+++ b/base/threading/hang_watcher.cc
@@ -740,7 +740,7 @@
       // Emit trace events for monitored threads.
       if (ThreadTypeLoggingLevelGreaterOrEqual(watch_state.get()->thread_type(),
                                                LoggingLevel::kUmaOnly)) {
-        const PlatformThreadId thread_id = watch_state.get()->GetThreadID();
+        const uint64_t thread_id = watch_state.get()->GetThreadID();
         const auto track = perfetto::Track::FromPointer(
             this, perfetto::ThreadTrack::ForThread(thread_id));
         TRACE_EVENT_BEGIN("base", "HangWatcher::ThreadHung", track, deadline);
@@ -758,8 +758,9 @@
       // the next capture then they'll already be marked and will be included
       // in the capture at that time.
       if (thread_marked && all_threads_marked) {
-        hung_watch_state_copies_.push_back(
-            WatchStateCopy{deadline, watch_state.get()->GetThreadID()});
+        hung_watch_state_copies_.push_back(WatchStateCopy{
+            deadline,
+            static_cast<PlatformThreadId>(watch_state.get()->GetThreadID())});
       } else {
         all_threads_marked = false;
       }
@@ -1171,9 +1172,7 @@
 // provided by PlatformThread. Make sure to use the same for correct
 // attribution.
 #if BUILDFLAG(IS_MAC)
-  uint64_t thread_id;
-  pthread_threadid_np(pthread_self(), &thread_id);
-  thread_id_ = thread_id;
+  pthread_threadid_np(pthread_self(), &thread_id_);
 #else
   thread_id_ = PlatformThread::CurrentId();
 #endif
@@ -1276,7 +1275,7 @@
   return hang_watch_state.get();
 }
 
-PlatformThreadId HangWatchState::GetThreadID() const {
+uint64_t HangWatchState::GetThreadID() const {
   return thread_id_;
 }
 
diff --git a/base/threading/hang_watcher.h b/base/threading/hang_watcher.h
index 4f3bf2b24..a2a557c4 100644
--- a/base/threading/hang_watcher.h
+++ b/base/threading/hang_watcher.h
@@ -625,7 +625,7 @@
   WatchHangsInScope* GetCurrentWatchHangsInScope();
 #endif
 
-  PlatformThreadId GetThreadID() const;
+  uint64_t GetThreadID() const;
 
   // Retrieve the current hang watch deadline directly. For testing only.
   HangWatchDeadline* GetHangWatchDeadlineForTesting();
@@ -652,8 +652,9 @@
   HangWatchDeadline deadline_;
 
   // A unique ID of the thread under watch. Used for logging in crash reports
-  // only.
-  PlatformThreadId thread_id_;
+  // only. Unsigned type is used as it provides a correct behavior for all
+  // platforms for positive thread ids. Any valid thread id should be positive.
+  uint64_t thread_id_;
 
   // Number of active HangWatchScopeEnables on this thread.
   int nesting_level_ = 0;
diff --git a/base/threading/platform_thread_linux.cc b/base/threading/platform_thread_linux.cc
index 27c0fd01..48f2670 100644
--- a/base/threading/platform_thread_linux.cc
+++ b/base/threading/platform_thread_linux.cc
@@ -164,10 +164,8 @@
                      const FilePath& cgroup_directory) {
   FilePath tasks_filepath = cgroup_directory.Append(FILE_PATH_LITERAL("tasks"));
   std::string tid = NumberToString(thread_id);
-  // TODO(crbug.com/1333521): Remove cast.
-  const int size = static_cast<int>(tid.size());
-  int bytes_written = WriteFile(tasks_filepath, tid.data(), size);
-  if (bytes_written != size) {
+  int bytes_written = WriteFile(tasks_filepath, tid.c_str(), tid.size());
+  if (bytes_written != static_cast<int>(tid.size())) {
     DVLOG(1) << "Failed to add " << tid << " to " << tasks_filepath.value();
   }
 }
@@ -414,7 +412,7 @@
 #endif
 
   const int nice_setting = internal::ThreadTypeToNiceValue(thread_type);
-  if (setpriority(PRIO_PROCESS, static_cast<id_t>(thread_id), nice_setting)) {
+  if (setpriority(PRIO_PROCESS, thread_id, nice_setting)) {
     DVPLOG(1) << "Failed to set nice value of thread (" << thread_id << ") to "
               << nice_setting;
   }
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index 418efcb..23e18d1 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -220,7 +220,7 @@
       (g_is_main_thread &&
        !g_main_thread_tid_cache_valid.load(std::memory_order_relaxed))) {
     // Update the cached tid.
-    g_thread_id = static_cast<pid_t>(syscall(__NR_gettid));
+    g_thread_id = syscall(__NR_gettid);
     // If this is the main thread, we can mark the tid_cache as valid.
     // Otherwise, stop the current thread from always entering this slow path.
     if (g_thread_id == getpid()) {
diff --git a/base/time/time_exploded_posix.cc b/base/time/time_exploded_posix.cc
index a2562a9..45327a8 100644
--- a/base/time/time_exploded_posix.cc
+++ b/base/time/time_exploded_posix.cc
@@ -158,7 +158,7 @@
   exploded->hour = timestruct.tm_hour;
   exploded->minute = timestruct.tm_min;
   exploded->second = timestruct.tm_sec;
-  exploded->millisecond = static_cast<int>(millisecond);
+  exploded->millisecond = millisecond;
 }
 
 // static
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc
index 69251d6..7c30c56 100644
--- a/base/trace_event/malloc_dump_provider.cc
+++ b/base/trace_event/malloc_dump_provider.cc
@@ -16,7 +16,6 @@
 #include "base/format_macros.h"
 #include "base/memory/nonscannable_memory.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/process_memory_dump.h"
 #include "base/trace_event/traced_value.h"
@@ -185,7 +184,7 @@
 
 #if (BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(IS_ANDROID)) || \
     (!BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && !BUILDFLAG(IS_WIN) &&    \
-     !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_FUCHSIA))
+     !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_FUCHSIA))
 void ReportMallinfoStats(ProcessMemoryDump* pmd,
                          size_t* total_virtual_size,
                          size_t* resident_size,
@@ -204,19 +203,17 @@
   // In case of Android's jemalloc |arena| is 0 and the outer pages size is
   // reported by |hblkhd|. In case of dlmalloc the total is given by
   // |arena| + |hblkhd|. For more details see link: http://goo.gl/fMR8lF.
-  *total_virtual_size += checked_cast<size_t>(info.arena + info.hblkhd);
-  size_t total_allocated_size = checked_cast<size_t>(info.uordblks);
-  *resident_size += total_allocated_size;
+  *total_virtual_size += info.arena + info.hblkhd;
+  *resident_size += info.uordblks;
 
   // Total allocated space is given by |uordblks|.
-  *allocated_objects_size += total_allocated_size;
+  *allocated_objects_size += info.uordblks;
 
   if (pmd) {
     MemoryAllocatorDump* sys_alloc_dump =
         pmd->CreateAllocatorDump("malloc/sys_malloc");
     sys_alloc_dump->AddScalar(MemoryAllocatorDump::kNameSize,
-                              MemoryAllocatorDump::kUnitsBytes,
-                              total_allocated_size);
+                              MemoryAllocatorDump::kUnitsBytes, info.uordblks);
   }
 }
 #endif
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index fb951928..f9f27c1 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -2208,7 +2208,7 @@
   // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
   const uint64_t kOffsetBasis = 14695981039346656037ull;
   const uint64_t kFnvPrime = 1099511628211ull;
-  const uint64_t pid = static_cast<uint64_t>(process_id_);
+  const uint64_t pid = process_id_;
   process_id_hash_ = (kOffsetBasis ^ pid) * kFnvPrime;
 }
 
diff --git a/build/BUILD.gn b/build/BUILD.gn
index 7ddab80..b1e9f73 100644
--- a/build/BUILD.gn
+++ b/build/BUILD.gn
@@ -7,6 +7,7 @@
 import("//build/config/chromecast_build.gni")
 import("//build/config/chromeos/args.gni")
 import("//build/config/chromeos/ui_mode.gni")
+import("//build/util/process_version.gni")
 
 source_set("buildflag_header_h") {
   sources = [ "buildflag.h" ]
@@ -54,3 +55,13 @@
     "IS_REVEN=$is_reven",
   ]
 }
+
+if (is_chromeos) {
+  process_version("version_metadata") {
+    sources = [ "//chrome/VERSION" ]
+
+    template_file = "metadata.json.in"
+    output = "$root_out_dir/metadata.json"
+    process_only = true
+  }
+}
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 7512fed..7962c3b 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220711.2.1
+8.20220711.3.1
diff --git a/build/fuchsia/qemu_target.py b/build/fuchsia/qemu_target.py
index 0d02f58..2c3c656 100644
--- a/build/fuchsia/qemu_target.py
+++ b/build/fuchsia/qemu_target.py
@@ -116,7 +116,8 @@
     # Configure the machine to emulate, based on the target architecture.
     if self._target_cpu == 'arm64':
       emu_command.extend([
-          '-machine','virt,gic-version=3',
+          '-machine',
+          'virt-2.12,gic-version=host',
       ])
     else:
       emu_command.extend([
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh
index d1da123..d0786b27 100755
--- a/build/install-build-deps.sh
+++ b/build/install-build-deps.sh
@@ -33,8 +33,7 @@
 build_apt_package_list() {
   echo "Building apt package list." >&2
   apt-cache dumpavail | \
-    python3 -c '\
-import re,sys; \
+    python3 -c 'import re,sys; \
 o = sys.stdin.read(); \
 p = {"i386": ":i386"}; \
 f = re.M | re.S; \
diff --git a/build/lacros/BUILD.gn b/build/lacros/BUILD.gn
index d5515fc..cf9b300 100644
--- a/build/lacros/BUILD.gn
+++ b/build/lacros/BUILD.gn
@@ -14,14 +14,6 @@
   ]
 }
 
-process_version("lacros_version_metadata") {
-  sources = [ "//chrome/VERSION" ]
-
-  template_file = "metadata.json.in"
-  output = "$root_out_dir/metadata.json"
-  process_only = true
-}
-
 # Lacros is built with "{arch}-generic" configuration. However, in Chrome
 # OS, it is just "one board variation", so the libraries on the *-generic
 # boards may not be compatible with the ones on the actual DUTs.
diff --git a/build/lacros/metadata.json.in b/build/metadata.json.in
similarity index 100%
rename from build/lacros/metadata.json.in
rename to build/metadata.json.in
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 06e3385..fe4703d 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -298,6 +298,12 @@
         ldflags += [ "-L" + rebase_path(root_out_dir) ]
       }
 
+      # On Chrome OS builds (for both ash-chrome and lacros-chrome), put
+      # a metadata.json file in root directory containing Chrome version.
+      if (is_chromeos) {
+        deps += [ "//build:version_metadata" ]
+      }
+
       # Chrome OS debug builds for arm need to pass --long-plt to the linker.
       # See https://bugs.chromium.org/p/chromium/issues/detail?id=583532
       if (is_chromeos_ash && is_debug && target_cpu == "arm") {
diff --git a/chrome/VERSION b/chrome/VERSION
index 562fdeb..519b0e5 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=105
 MINOR=0
-BUILD=5175
+BUILD=5176
 PATCH=0
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java
index 049cadc..d1823ddb 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java
@@ -45,6 +45,7 @@
 
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
 import android.support.test.InstrumentationRegistry;
@@ -67,6 +68,7 @@
 import org.hamcrest.Matchers;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
@@ -75,6 +77,7 @@
 import org.chromium.base.Callback;
 import org.chromium.base.GarbageCollectionTestUtils;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.test.metrics.HistogramTestRule;
 import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
@@ -123,6 +126,7 @@
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.content_public.browser.test.util.WebContentsUtils;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -171,6 +175,9 @@
                     .setBugComponent(ChromeRenderTestRule.Component.UI_BROWSER_MOBILE_START)
                     .build();
 
+    @Rule
+    public HistogramTestRule mHistogramTester = new HistogramTestRule();
+
     @SuppressWarnings("FieldCanBeLocal")
     private EmbeddedTestServer mTestServer;
     private TabSwitcherAndStartSurfaceLayout mTabSwitcherAndStartSurfaceLayout;
@@ -181,6 +188,12 @@
             (bitmap) -> mAllBitmaps.add(new WeakReference<>(bitmap));
     private TabSwitcher.TabListDelegate mTabListDelegate;
 
+    @BeforeClass
+    public static void beforeClass() {
+        // Only needs to be loaded once and needs to be loaded before HistogramTestRule.
+        NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess();
+    }
+
     @Before
     public void setUp() {
         AccessibilityChecks.enable();
@@ -1142,159 +1155,89 @@
     @MediumTest
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS})
-    @DisabledTest(message = "https://crbug.com/1138739")
-    public void testThumbnailFetchingResult_defaultAspectRatio() throws Exception {
-        prepareTabs(2, 0, mUrl);
-        int oldJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
-        int oldEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
-        int oldNothingCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
-        int oldDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);
+    public void testThumbnailFetchingResult_liveLayer() throws Exception {
+        prepareTabs(1, 0, "about:blank");
+        enterTabSwitcher(mActivityTestRule.getActivity());
+        // There might be an additional one from capturing thumbnail for the live layer.
+        CriteriaHelper.pollUiThread(
+                () -> Criteria.checkThat(mAllBitmaps.size(), Matchers.greaterThanOrEqualTo(1)));
+
+        assertEquals(0,
+                mHistogramTester.getHistogramValueCount(
+                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
+                        TabContentManager.ThumbnailFetchingResult.GOT_JPEG));
+        assertEquals(0,
+                mHistogramTester.getHistogramValueCount(
+                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
+                        TabContentManager.ThumbnailFetchingResult.GOT_ETC1));
+        assertEquals(0,
+                mHistogramTester.getHistogramValueCount(
+                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
+                        TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG));
+        assertEquals(1,
+                mHistogramTester.getHistogramValueCount(
+                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
+                        TabContentManager.ThumbnailFetchingResult.GOT_NOTHING));
+    }
+
+    @Test
+    @MediumTest
+    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
+    @CommandLineFlags.Add({BASE_PARAMS})
+    public void testThumbnailFetchingResult_jpeg() throws Exception {
+        prepareTabs(1, 0, "about:blank");
+        simulateJpegHasCachedWithDefaultAspectRatio();
 
         enterTabSwitcher(mActivityTestRule.getActivity());
-        int currentJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
-        int currentEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
-        int currentNothingCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
-        int currentDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);
+        // There might be an additional one from capturing thumbnail for the live layer.
+        CriteriaHelper.pollUiThread(
+                () -> Criteria.checkThat(mAllBitmaps.size(), Matchers.greaterThanOrEqualTo(1)));
 
-        assertEquals(1, currentJpegCount - oldJpegCount);
-        assertEquals(0, currentEtc1Count - oldEtc1Count);
-        assertEquals(0, currentDifferentAspectRatioJpegCount - oldDifferentAspectRatioJpegCount);
-        // Get thumbnail from a live layer.
-        assertEquals(1, currentNothingCount - oldNothingCount);
-
-        oldJpegCount = currentJpegCount;
-        oldEtc1Count = currentEtc1Count;
-        oldNothingCount = currentNothingCount;
-        oldDifferentAspectRatioJpegCount = currentDifferentAspectRatioJpegCount;
-
-        TabModel currentTabModel =
-                mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
-        for (int i = 0; i < currentTabModel.getCount(); i++) {
-            TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i));
-        }
-
-        TabUiTestHelper.finishActivity(mActivityTestRule.getActivity());
-        mActivityTestRule.startMainActivityFromLauncher();
-
-        enterTabSwitcher(mActivityTestRule.getActivity());
-        assertEquals(2,
-                RecordHistogram.getHistogramValueCountForTesting(
+        assertEquals(1,
+                mHistogramTester.getHistogramValueCount(
                         TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_JPEG)
-                        - oldJpegCount);
+                        TabContentManager.ThumbnailFetchingResult.GOT_JPEG));
         assertEquals(0,
-                RecordHistogram.getHistogramValueCountForTesting(
+                mHistogramTester.getHistogramValueCount(
                         TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_ETC1)
-                        - oldEtc1Count);
+                        TabContentManager.ThumbnailFetchingResult.GOT_ETC1));
         assertEquals(0,
-                RecordHistogram.getHistogramValueCountForTesting(
+                mHistogramTester.getHistogramValueCount(
                         TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_NOTHING)
-                        - oldNothingCount);
+                        TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG));
         assertEquals(0,
-                RecordHistogram.getHistogramValueCountForTesting(
+                mHistogramTester.getHistogramValueCount(
                         TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG)
-                        - oldDifferentAspectRatioJpegCount);
+                        TabContentManager.ThumbnailFetchingResult.GOT_NOTHING));
     }
 
     @Test
     @MediumTest
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"})
-    @DisabledTest(message = "http://crbug/1119527 - Flaky on bots.")
     public void testThumbnailFetchingResult_changingAspectRatio() throws Exception {
-        prepareTabs(2, 0, mUrl);
-        int oldJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
-        int oldEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
-        int oldNothingCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
-        int oldDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);
-
+        prepareTabs(1, 0, "about:blank");
+        // Simulate Jpeg has cached with default aspect ratio.
+        simulateJpegHasCachedWithDefaultAspectRatio();
         enterTabSwitcher(mActivityTestRule.getActivity());
-        int currentJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
-        int currentEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
-        int currentNothingCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
-        int currentDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
-                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);
+        // There might be an additional one from capturing thumbnail for the live layer.
+        CriteriaHelper.pollUiThread(
+                () -> Criteria.checkThat(mAllBitmaps.size(), Matchers.greaterThanOrEqualTo(1)));
 
-        assertEquals(1, currentJpegCount - oldJpegCount);
-        assertEquals(0, currentEtc1Count - oldEtc1Count);
-        assertEquals(0, currentDifferentAspectRatioJpegCount - oldDifferentAspectRatioJpegCount);
-        // Get thumbnail from a live layer.
-        assertEquals(1, currentNothingCount - oldNothingCount);
-
-        oldJpegCount = currentJpegCount;
-        oldEtc1Count = currentEtc1Count;
-        oldNothingCount = currentNothingCount;
-        oldDifferentAspectRatioJpegCount = currentDifferentAspectRatioJpegCount;
-
-        onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
-
-        TabModel currentTabModel =
-                mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
-        for (int i = 0; i < currentTabModel.getCount(); i++) {
-            TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i));
-        }
-        leaveGTSAndVerifyThumbnailsAreReleased();
-
-        simulateAspectRatioChangedToPoint75();
-        verifyAllThumbnailHasAspectRatio(0.75);
-
-        enterTabSwitcher(mActivityTestRule.getActivity());
         assertEquals(0,
-                RecordHistogram.getHistogramValueCountForTesting(
+                mHistogramTester.getHistogramValueCount(
                         TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_JPEG)
-                        - oldJpegCount);
-        assertEquals(2,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG)
-                        - oldDifferentAspectRatioJpegCount);
+                        TabContentManager.ThumbnailFetchingResult.GOT_JPEG));
         assertEquals(0,
-                RecordHistogram.getHistogramValueCountForTesting(
+                mHistogramTester.getHistogramValueCount(
                         TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_ETC1)
-                        - oldEtc1Count);
-        assertEquals(0,
-                RecordHistogram.getHistogramValueCountForTesting(
+                        TabContentManager.ThumbnailFetchingResult.GOT_ETC1));
+        assertEquals(1,
+                mHistogramTester.getHistogramValueCount(
                         TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
-                        TabContentManager.ThumbnailFetchingResult.GOT_NOTHING)
-                        - oldNothingCount);
-        onView(tabSwitcherViewMatcher())
+                        TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG));
+
+        onViewWaiting(tabSwitcherViewMatcher())
                 .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
     }
 
@@ -1971,6 +1914,7 @@
     private void assertThumbnailsAreReleased() {
         // Could not directly assert canAllBeGarbageCollected() because objects can be in Cleaner.
         CriteriaHelper.pollUiThread(() -> canAllBeGarbageCollected(mAllBitmaps));
+        mAllBitmaps.clear();
     }
 
     private boolean canAllBeGarbageCollected(List<WeakReference<Bitmap>> bitmaps) {
@@ -1982,6 +1926,18 @@
         return true;
     }
 
+    private void simulateJpegHasCachedWithDefaultAspectRatio() throws IOException {
+        TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel();
+        int jpegWidth = 125;
+        int jpegHeight = (int) (jpegWidth * 1.0
+                / TabUtils.getTabThumbnailAspectRatio(mActivityTestRule.getActivity()));
+        for (int i = 0; i < currentModel.getCount(); i++) {
+            Tab tab = currentModel.getTabAt(i);
+            Bitmap bitmap = Bitmap.createBitmap(jpegWidth, jpegHeight, Config.ARGB_8888);
+            encodeJpeg(tab, bitmap);
+        }
+    }
+
     private void simulateAspectRatioChangedToPoint75() throws IOException {
         TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel();
         for (int i = 0; i < currentModel.getCount(); i++) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
index a1502bd..6b231c9 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -112,7 +112,6 @@
         } else if (TabProperties.IS_SELECTED == propertyKey) {
             updateColor(view, model.get(TabProperties.IS_INCOGNITO),
                     model.get(TabProperties.IS_SELECTED));
-            updateThumbnail(view, model);
             updateFavicon(view, model);
             if (TabUiFeatureUtilities.ENABLE_SEARCH_CHIP.getValue()) {
                 ChipView pageInfoButton = (ChipView) view.fastFindViewById(R.id.page_info_button);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
index 76ff8c6..5955f92 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -529,6 +529,8 @@
 
     private View.AccessibilityDelegate mAccessibilityDelegate;
 
+    private int mLastSelectedTabListModelIndex = TabList.INVALID_TAB_INDEX;
+
     /**
      * Interface for implementing a {@link Runnable} that takes a tabId for a generic action.
      */
@@ -585,14 +587,24 @@
             public void didSelectTab(Tab tab, int type, int lastId) {
                 mNextTabId = Tab.INVALID_TAB_ID;
                 if (tab.getId() == lastId) return;
+
                 int oldIndex = mModel.indexFromId(lastId);
+                mLastSelectedTabListModelIndex = oldIndex;
                 if (oldIndex != TabModel.INVALID_TAB_INDEX) {
                     mModel.get(oldIndex).model.set(TabProperties.IS_SELECTED, false);
+                    if (mActionsOnAllRelatedTabs && mThumbnailProvider != null && mVisible) {
+                        mModel.get(oldIndex).model.set(TabProperties.THUMBNAIL_FETCHER,
+                                new ThumbnailFetcher(mThumbnailProvider, lastId, true, false));
+                    }
                 }
+
                 int newIndex = mModel.indexFromId(tab.getId());
                 if (newIndex == TabModel.INVALID_TAB_INDEX) return;
-
                 mModel.get(newIndex).model.set(TabProperties.IS_SELECTED, true);
+                if (mThumbnailProvider != null && mVisible) {
+                    mModel.get(newIndex).model.set(TabProperties.THUMBNAIL_FETCHER,
+                            new ThumbnailFetcher(mThumbnailProvider, tab.getId(), true, false));
+                }
             }
 
             @Override
@@ -1066,7 +1078,8 @@
     }
 
     private int getIndexOfTab(Tab tab, boolean onlyShowRelatedTabs) {
-        int index;
+        int index = TabList.INVALID_TAB_INDEX;
+        if (tab == null) return index;
         if (onlyShowRelatedTabs) {
             if (mModel.size() == 0) return TabList.INVALID_TAB_INDEX;
             List<Tab> related = getRelatedTabsForId(mModel.get(0).model.get(TabProperties.TAB_ID));
@@ -1178,6 +1191,8 @@
             return true;
         }
         mModel.set(new ArrayList<>());
+        mLastSelectedTabListModelIndex = TabList.INVALID_TAB_INDEX;
+
         if (tabsList == null) {
             return true;
         }
@@ -1271,12 +1286,15 @@
 
         updateFaviconForTab(pseudoTab, null);
         boolean forceUpdate = isSelected && !quickMode;
+        boolean forceUpdateLastSelected =
+                mActionsOnAllRelatedTabs && index == mLastSelectedTabListModelIndex && !quickMode;
+
         if (mThumbnailProvider != null && mVisible
                 && (mModel.get(index).model.get(TabProperties.THUMBNAIL_FETCHER) == null
-                        || forceUpdate || isUpdatingId)) {
-            ThumbnailFetcher callback =
-                    new ThumbnailFetcher(mThumbnailProvider, pseudoTab.getId(), forceUpdate,
-                            forceUpdate && !TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
+                        || forceUpdate || isUpdatingId || forceUpdateLastSelected)) {
+            ThumbnailFetcher callback = new ThumbnailFetcher(mThumbnailProvider, pseudoTab.getId(),
+                    forceUpdate || forceUpdateLastSelected,
+                    forceUpdate && !TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
             mModel.get(index).model.set(TabProperties.THUMBNAIL_FETCHER, callback);
         }
     }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
index 78e55449..0d029b0 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -113,7 +113,7 @@
 import org.chromium.ui.KeyboardVisibilityDelegate;
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.test.util.NightModeTestUtils;
-import org.chromium.ui.test.util.UiRestriction;
+import org.chromium.ui.test.util.UiDisableIf;
 import org.chromium.ui.util.ColorUtils;
 
 import java.util.concurrent.ExecutionException;
@@ -562,8 +562,8 @@
 
     @Test
     @MediumTest
-    // TODO Enable for Tablets (crbug.com/1342387)
-    @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
+    // TODO(https://crbug.com/1342387): Enable for tablets.
+    @DisableIf.Device(type = UiDisableIf.TABLET)
     // clang-format off
     @EnableFeatures({ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID + "<Study"})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
@@ -698,6 +698,7 @@
     @DisableIf.
     Build(sdk_is_greater_than = VERSION_CODES.N_MR1, message = "https://crbug.com/1124336")
     @DisableIf.Build(supported_abis_includes = "x86", message = "https://crbug.com/1124336")
+    @DisableIf.Device(type = UiDisableIf.TABLET)
     public void testDialogInitialShowFromStrip() throws Exception {
         final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
         prepareTabsWithThumbnail(mActivityTestRule, 2, 0, "about:blank");
@@ -922,7 +923,7 @@
 
     @Test
     @MediumTest
-    @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
+    @DisableIf.Device(type = UiDisableIf.TABLET)
     @Features.EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID + "<Study"})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group", START_SURFACE_BASE_PARAMS + "/single"})
     public void testDialogSetup_WithStartSurface() throws Exception {
@@ -963,10 +964,11 @@
     @MediumTest
     @Features.EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID + "<Study"})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group", START_SURFACE_BASE_PARAMS + "/single"})
-    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.M,
-            message = "crbug.com/1119899, crbug.com/1131545")
-    public void
-    testUndoClosureInDialog_WithStartSurface() throws Exception {
+    @DisableIf.
+    Build(sdk_is_greater_than = VERSION_CODES.M, message = "crbug.com/1119899, crbug.com/1131545")
+    // TODO(https://crbug.com/1342387): Enable for tablets.
+    @DisableIf.Device(type = UiDisableIf.TABLET)
+    public void testUndoClosureInDialog_WithStartSurface() throws Exception {
         // Create a tab group with 2 tabs.
         finishActivity(mActivityTestRule.getActivity());
         createThumbnailBitmapAndWriteToFile(0);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
index 810431e..7b18b4e 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -135,6 +135,7 @@
 import org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator.TabListMode;
 import org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider.TabFavicon;
 import org.chromium.chrome.browser.tasks.tab_management.TabListMediator.ShoppingPersistedTabDataFetcher;
+import org.chromium.chrome.browser.tasks.tab_management.TabListMediator.ThumbnailFetcher;
 import org.chromium.chrome.browser.tasks.tab_management.TabProperties.UiType;
 import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
 import org.chromium.chrome.tab_ui.R;
@@ -368,6 +369,11 @@
 
         doReturn(mTabModelFilterProvider).when(mTabModelSelector).getTabModelFilterProvider();
         doReturn(mTabModelFilter).when(mTabModelFilterProvider).getCurrentTabModelFilter();
+        doReturn(2).when(mTabModelFilter).getCount();
+        doReturn(mTab1).when(mTabModelFilter).getTabAt(POSITION1);
+        doReturn(mTab2).when(mTabModelFilter).getTabAt(POSITION2);
+        doReturn(tabs1).when(mTabModelFilter).getRelatedTabList(TAB1_ID);
+        doReturn(tabs2).when(mTabModelFilter).getRelatedTabList(TAB2_ID);
         doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
         doReturn(TAB1_ID).when(mTabModelSelector).getCurrentTabId();
         doNothing()
@@ -907,12 +913,43 @@
     public void tabSelection() {
         initAndAssertAllProperties();
 
+        ThumbnailFetcher tab1Fetcher = mModel.get(0).model.get(TabProperties.THUMBNAIL_FETCHER);
+        ThumbnailFetcher tab2Fetcher = mModel.get(1).model.get(TabProperties.THUMBNAIL_FETCHER);
+
         mTabModelObserverCaptor.getValue().didSelectTab(
                 mTab2, TabLaunchType.FROM_CHROME_UI, TAB1_ID);
 
         assertThat(mModel.size(), equalTo(2));
         assertThat(mModel.get(0).model.get(TabProperties.IS_SELECTED), equalTo(false));
+        assertThat(mModel.get(0).model.get(TabProperties.THUMBNAIL_FETCHER), equalTo(tab1Fetcher));
         assertThat(mModel.get(1).model.get(TabProperties.IS_SELECTED), equalTo(true));
+        assertNotEquals(tab2Fetcher, mModel.get(1).model.get(TabProperties.THUMBNAIL_FETCHER));
+    }
+
+    @Test
+    public void tabSelection_updatePreviousSelectedTabThumbnailFetcher() {
+        mMediator = new TabListMediator(mActivity, mModel, TabListMode.GRID, mTabModelSelector,
+                mTabContentManager::getTabThumbnailWithCallback, mTitleProvider,
+                mTabListFaviconProvider, true, null, mGridCardOnClickListenerProvider, null, null,
+                getClass().getSimpleName(), UiType.CLOSABLE);
+        mMediator.initWithNative(mProfile);
+        // mTabModelObserverCaptor captures on every initWithNative calls. There is one
+        // initWithNative call in the setup already.
+        verify(mTabModelFilterProvider, times(2))
+                .addTabModelFilterObserver(mTabModelObserverCaptor.capture());
+        initAndAssertAllProperties();
+
+        ThumbnailFetcher tab1Fetcher = mModel.get(0).model.get(TabProperties.THUMBNAIL_FETCHER);
+        ThumbnailFetcher tab2Fetcher = mModel.get(1).model.get(TabProperties.THUMBNAIL_FETCHER);
+
+        mTabModelObserverCaptor.getValue().didSelectTab(
+                mTab2, TabLaunchType.FROM_CHROME_UI, TAB1_ID);
+
+        assertThat(mModel.size(), equalTo(2));
+        assertThat(mModel.get(0).model.get(TabProperties.IS_SELECTED), equalTo(false));
+        assertNotEquals(tab1Fetcher, mModel.get(0).model.get(TabProperties.THUMBNAIL_FETCHER));
+        assertThat(mModel.get(1).model.get(TabProperties.IS_SELECTED), equalTo(true));
+        assertNotEquals(tab2Fetcher, mModel.get(1).model.get(TabProperties.THUMBNAIL_FETCHER));
     }
 
     @Test
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
index d301b73c..3c79fb4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -143,7 +143,8 @@
 
     @Override
     public void showLayout(int layoutType, boolean animate) {
-        if (layoutType == LayoutType.TAB_SWITCHER && mOverviewLayout == null) {
+        if (layoutType == LayoutType.TAB_SWITCHER && mOverviewLayout == null
+                && TabUiFeatureUtilities.isTabletGridTabSwitcherEnabled(mHost.getContext())) {
             try {
                 if (!mStartSurfaceSupplier.hasValue()) {
                     final ViewGroup containerView = mCreateStartSurfaceCallable.call();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDownloadObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDownloadObserver.java
index 65358a4..3a499dd9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDownloadObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDownloadObserver.java
@@ -6,6 +6,7 @@
 
 import android.app.Activity;
 
+import org.chromium.chrome.browser.DeferredStartupHandler;
 import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
 import org.chromium.chrome.browser.download.DownloadManagerService;
@@ -56,10 +57,13 @@
             DownloadInterstitialCoordinator coordinator =
                     DownloadInterstitialCoordinatorFactory.create(tab::getContext,
                             tab.getOriginalUrl().getSpec(), tab.getWindowAndroid());
-            // Register the download's original URL to prevent messages UI showing in interstitial.
-            DownloadManagerService.getDownloadManagerService()
-                    .getMessageUiController(/* otrProfileId */ null)
-                    .addDownloadInterstitialSource(tab.getOriginalUrl());
+            // Register the download's original URL to prevent messages UI showing in
+            // interstitial.
+            DeferredStartupHandler.getInstance().addDeferredTask(
+                    ()
+                            -> DownloadManagerService.getDownloadManagerService()
+                                       .getMessageUiController(/* otrProfileId */ null)
+                                       .addDownloadInterstitialSource(tab.getOriginalUrl()));
             NewDownloadTab.from(tab, coordinator, mActivity).show();
         }
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrArCameraAccessTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrArCameraAccessTest.java
index 50eb0aa2..6eae928 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrArCameraAccessTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrArCameraAccessTest.java
@@ -140,4 +140,24 @@
         mWebXrArTestFramework.waitOnJavaScriptStep();
         mWebXrArTestFramework.endTest();
     }
+
+    /**
+     * Test whether opaque texture enforcements work fine.
+     */
+    @Test
+    @MediumTest
+    @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
+    @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+            "enable-features=WebXRIncubations,LogJsConsoleMessages"})
+    @ArPlaybackFile("chrome/test/data/xr/ar_playback_datasets/floor_session_12s_30fps.mp4")
+    public void
+    testOpaqueTextures() {
+        mWebXrArTestFramework.loadFileAndAwaitInitialization(
+                "webxr_test_camera_access", PAGE_LOAD_TIMEOUT_S);
+        mWebXrArTestFramework.enterSessionWithUserGestureOrFail(/*needsCameraPermission=*/true);
+        mWebXrArTestFramework.runJavaScriptOrFail(
+                "stepCheckOpaqueTextures()", POLL_TIMEOUT_SHORT_MS);
+        mWebXrArTestFramework.waitOnJavaScriptStep();
+        mWebXrArTestFramework.endTest();
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
index 3784d3d7..292ea20 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
@@ -7,15 +7,18 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.net.Uri;
+import android.os.Build;
 import android.os.IBinder;
 import android.support.test.InstrumentationRegistry;
 
 import androidx.test.filters.LargeTest;
 
+import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -29,6 +32,7 @@
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.FlakyTest;
+import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.flags.ActivityType;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
@@ -93,6 +97,37 @@
     }
 
     /**
+     * Tests that Chrome will trampoline out to WebAPKs if they exist but are not verified.
+     * See https://crbug.com/1232514
+     */
+    @Test
+    @LargeTest
+    @Feature({"Webapps"})
+    @MinAndroidSdkLevel(Build.VERSION_CODES.S)
+    public void testWebApkTrampoline() {
+        Context targetContext = InstrumentationRegistry.getTargetContext();
+        String pageUrl = "https://pwa-directory.appspot.com/defaultresponse";
+
+        // Make a standard browsable Intent to a page within the WebAPK's scope.
+        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(pageUrl));
+        intent.addCategory(Intent.CATEGORY_BROWSABLE);
+
+        // FLAG_ACTIVITY_NEW_TASK required because we're launching from a non-Activity context.
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        // We need to set the component name to make sure the Intent ends up in the Chrome build
+        // that we're testing. We can't set the package name, because our launch code has special
+        // handling if the package name is set and is equal to Chrome
+        // (see RedirectHandler#updateIntent).
+        intent.setComponent(new ComponentName(targetContext, ChromeLauncherActivity.class));
+
+        targetContext.startActivity(intent);
+
+        // Check we end up in the WebAPK.
+        ChromeActivityTestRule.waitFor(WebappActivity.class, STARTUP_TIMEOUT);
+    }
+
+    /**
      * Tests launching WebAPK via POST share intent.
      */
     @Test
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index caa0631c..e0dc377 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-105.0.5171.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-105.0.5173.0_rc-r2-merged.afdo.bz2
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index be2c284..99b370a 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4019,6 +4019,8 @@
       "performance_manager/policies/page_discarding_helper.h",
       "performance_manager/policies/urgent_page_discarding_policy.cc",
       "performance_manager/policies/urgent_page_discarding_policy.h",
+      "performance_manager/user_tuning/profile_discard_opt_out_list_helper.cc",
+      "performance_manager/user_tuning/profile_discard_opt_out_list_helper.h",
       "permissions/attestation_permission_request.cc",
       "permissions/attestation_permission_request.h",
       "policy/device_account_initializer.cc",
@@ -5142,6 +5144,8 @@
       "//chrome/services/sharing/public/proto",
       "//chrome/services/speech:lib",
       "//chromeos/ash/components/assistant:buildflags",
+      "//chromeos/ash/components/dbus/attestation",
+      "//chromeos/ash/components/dbus/attestation:attestation_proto",
       "//chromeos/ash/components/dbus/concierge",
       "//chromeos/ash/components/dbus/image_loader",
       "//chromeos/ash/components/dbus/session_manager",
@@ -5163,8 +5167,6 @@
       "//chromeos/crosapi/cpp:crosapi_constants",
       "//chromeos/crosapi/mojom",
       "//chromeos/dbus",
-      "//chromeos/dbus/attestation",
-      "//chromeos/dbus/attestation:attestation_proto",
       "//chromeos/dbus/cros_disks",
       "//chromeos/dbus/cryptohome",
       "//chromeos/dbus/power",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 6fff244..4000b20d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -5097,10 +5097,6 @@
      flag_descriptions::kOmniboxDisableCGIParamMatchingName,
      flag_descriptions::kOmniboxDisableCGIParamMatchingDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(omnibox::kDisableCGIParamMatching)},
-    {"omnibox-active-search-engines",
-     flag_descriptions::kOmniboxActiveSearchEnginesName,
-     flag_descriptions::kOmniboxActiveSearchEnginesDescription, kOsDesktop,
-     FEATURE_VALUE_TYPE(omnibox::kActiveSearchEngines)},
     {"omnibox-document-provider-aso",
      flag_descriptions::kOmniboxDocumentProviderAsoName,
      flag_descriptions::kOmniboxDocumentProviderAsoDescription, kOsDesktop,
diff --git a/chrome/browser/apps/app_service/app_service_proxy_lacros_unittest.cc b/chrome/browser/apps/app_service/app_service_proxy_lacros_unittest.cc
index 64270fd..527397a2 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_lacros_unittest.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_lacros_unittest.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
 #include "chrome/browser/apps/app_service/mock_crosapi_app_service_proxy.h"
+#include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -19,8 +20,7 @@
 const char kAppId[] = "test_app";
 const char kUrl[] = "https://www.google.com";
 const int32_t event_flag = ui::EF_NONE;
-const apps::mojom::LaunchSource launch_source =
-    apps::mojom::LaunchSource::kFromTest;
+const apps::LaunchSource launch_source = apps::LaunchSource::kFromTest;
 
 // Expected container and disposition for ui::EF_NONE event flag;
 const crosapi::mojom::LaunchContainer expected_container =
@@ -39,7 +39,8 @@
   MockCrosapiAppServiceProxy mock_proxy;
   proxy.SetCrosapiAppServiceProxyForTesting(&mock_proxy);
 
-  proxy.LaunchAppWithUrl(kAppId, event_flag, GURL(kUrl), launch_source,
+  proxy.LaunchAppWithUrl(kAppId, event_flag, GURL(kUrl),
+                         ConvertLaunchSourceToMojomLaunchSource(launch_source),
                          apps::MakeWindowInfo(display::kDefaultDisplayId));
   mock_proxy.Wait();
   ASSERT_EQ(mock_proxy.launched_apps().size(), 1U);
diff --git a/chrome/browser/apps/app_service/launch_utils.cc b/chrome/browser/apps/app_service/launch_utils.cc
index 2b1314ce..752635bb 100644
--- a/chrome/browser/apps/app_service/launch_utils.cc
+++ b/chrome/browser/apps/app_service/launch_utils.cc
@@ -405,7 +405,8 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
   crosapi_params->app_id = id;
-  crosapi_params->launch_source = params.launch_source;
+  crosapi_params->launch_source =
+      ConvertMojomLaunchSourceToLaunchSource(params.launch_source);
 
   // Both launch_files and override_url will be represent by intent in crosapi
   // launch params. These info will normally represent in the intent field in
@@ -438,7 +439,8 @@
       crosapi_params->app_id,
       ConvertCrosapiToAppServiceLaunchContainer(crosapi_params->container),
       ConvertWindowOpenDispositionFromCrosapi(crosapi_params->disposition),
-      crosapi_params->launch_source, crosapi_params->display_id);
+      ConvertLaunchSourceToMojomLaunchSource(crosapi_params->launch_source),
+      crosapi_params->display_id);
   if (!crosapi_params->intent) {
     return params;
   }
diff --git a/chrome/browser/apps/app_service/launch_utils_unittest.cc b/chrome/browser/apps/app_service/launch_utils_unittest.cc
index 7cf035d7..1ee713872 100644
--- a/chrome/browser/apps/app_service/launch_utils_unittest.cc
+++ b/chrome/browser/apps/app_service/launch_utils_unittest.cc
@@ -281,7 +281,7 @@
 TEST_F(LaunchUtilsTest, FromCrosapiIncomplete) {
   auto params = crosapi::mojom::LaunchParams::New();
   params->app_id = "aaaa";
-  params->launch_source = apps::mojom::LaunchSource::kFromIntentUrl;
+  params->launch_source = apps::LaunchSource::kFromIntentUrl;
 
   auto converted_params = apps::ConvertCrosapiToLaunchParams(params, &profile_);
 
@@ -307,7 +307,7 @@
       crosapi::mojom::LaunchContainer::kLaunchContainerWindow;
   crosapi_params->disposition =
       crosapi::mojom::WindowOpenDisposition::kNewForegroundTab;
-  crosapi_params->launch_source = apps::mojom::LaunchSource::kFromSharesheet;
+  crosapi_params->launch_source = apps::LaunchSource::kFromSharesheet;
   const int64_t kDisplayId = 5;
   crosapi_params->display_id = kDisplayId;
   crosapi_params->intent = crosapi::mojom::Intent::New();
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
index b62f434..223a41e 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
@@ -219,7 +219,8 @@
 
   auto launch_params = crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id;
-  launch_params->launch_source = launch_source;
+  launch_params->launch_source =
+      ConvertMojomLaunchSourceToLaunchSource(launch_source);
   launch_params->intent = apps_util::ConvertAppServiceToCrosapiIntent(
       intent, ProfileManager::GetPrimaryUserProfile());
   controller_->Launch(std::move(launch_params),
@@ -249,7 +250,8 @@
 
   auto launch_params = crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id;
-  launch_params->launch_source = launch_source;
+  launch_params->launch_source =
+      ConvertMojomLaunchSourceToLaunchSource(launch_source);
   launch_params->intent =
       apps_util::CreateCrosapiIntentForViewFiles(file_paths);
   controller_->Launch(std::move(launch_params),
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 761a6d93..fc74571 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -130,6 +130,8 @@
     "app_mode/kiosk_mode_idle_app_name_notification.h",
     "app_mode/kiosk_profile_loader.cc",
     "app_mode/kiosk_profile_loader.h",
+    "app_mode/metrics/low_disk_metrics_service.cc",
+    "app_mode/metrics/low_disk_metrics_service.h",
     "app_mode/metrics/network_connectivity_metrics_service.cc",
     "app_mode/metrics/network_connectivity_metrics_service.h",
     "app_mode/pref_names.cc",
@@ -658,6 +660,8 @@
     "bruschetta/bruschetta_features.h",
     "bruschetta/bruschetta_launcher.cc",
     "bruschetta/bruschetta_launcher.h",
+    "bruschetta/bruschetta_mount_provider.cc",
+    "bruschetta/bruschetta_mount_provider.h",
     "bruschetta/bruschetta_service.cc",
     "bruschetta/bruschetta_service.h",
     "bruschetta/bruschetta_service_factory.cc",
@@ -1561,6 +1565,8 @@
     "//chrome/services/printing/public/mojom",
     "//chromeos/ash/components/dbus/anomaly_detector",
     "//chromeos/ash/components/dbus/anomaly_detector:proto",
+    "//chromeos/ash/components/dbus/attestation",
+    "//chromeos/ash/components/dbus/attestation:attestation_proto",
     "//chromeos/ash/components/dbus/authpolicy",
     "//chromeos/ash/components/dbus/authpolicy:authpolicy_proto",
     "//chromeos/ash/components/dbus/chunneld",
@@ -1594,8 +1600,6 @@
     "//chromeos/dbus:metrics_event_proto",
     "//chromeos/dbus:vm_applications_apps_proto",
     "//chromeos/dbus:vm_launch_proto",
-    "//chromeos/dbus/attestation",
-    "//chromeos/dbus/attestation:attestation_proto",
     "//chromeos/dbus/common",
     "//chromeos/dbus/constants",
     "//chromeos/dbus/cros_disks",
diff --git a/chrome/browser/ash/app_mode/app_session_ash.h b/chrome/browser/ash/app_mode/app_session_ash.h
index cb0a9b8..161835d 100644
--- a/chrome/browser/ash/app_mode/app_session_ash.h
+++ b/chrome/browser/ash/app_mode/app_session_ash.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_ASH_APP_MODE_APP_SESSION_ASH_H_
 #define CHROME_BROWSER_ASH_APP_MODE_APP_SESSION_ASH_H_
 
+#include "chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.h"
 #include "chrome/browser/chromeos/app_mode/app_session.h"
 
 namespace ash {
@@ -42,6 +43,9 @@
   // Tracks network connectivity drops.
   // Init in ctor and destroyed while ShuttingDown.
   std::unique_ptr<NetworkConnectivityMetricsService> network_metrics_service_;
+
+  // Tracks low disk notifications.
+  LowDiskMetricsService low_disk_metrics_service_;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.cc b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.cc
new file mode 100644
index 0000000..3fcf5eb
--- /dev/null
+++ b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.cc
@@ -0,0 +1,113 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.h"
+
+#include <algorithm>
+
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
+#include "components/prefs/pref_service.h"
+#include "services/preferences/public/cpp/dictionary_value_update.h"
+#include "services/preferences/public/cpp/scoped_pref_update.h"
+
+namespace ash {
+
+namespace {
+
+KioskLowDiskSeverity GetSeverity(uint64_t free_disk_bytes) {
+  if (free_disk_bytes < kLowDiskSevereThreshold) {
+    return KioskLowDiskSeverity::kHigh;
+  }
+  if (free_disk_bytes < kLowDiskMediumThreshold) {
+    return KioskLowDiskSeverity::kMedium;
+  }
+  return KioskLowDiskSeverity::kNone;
+}
+
+}  // namespace
+
+const char kKioskSessionLowDiskSeverityHistogram[] =
+    "Kiosk.Session.LowDiskSeverity";
+const char kKioskSessionLowDiskHighestSeverityHistogram[] =
+    "Kiosk.Session.LowDiskHighestSeverity";
+const char kKioskLowDiskSeverity[] = "low-disk";
+
+const uint64_t kLowDiskSevereThreshold = 512 << 20;  // 512MB
+const uint64_t kLowDiskMediumThreshold = 1 << 30;    // 1GB
+
+LowDiskMetricsService::LowDiskMetricsService()
+    : LowDiskMetricsService(g_browser_process->local_state()) {}
+
+// static
+std::unique_ptr<LowDiskMetricsService> LowDiskMetricsService::CreateForTesting(
+    PrefService* pref) {
+  return base::WrapUnique(new LowDiskMetricsService(pref));
+}
+
+LowDiskMetricsService::LowDiskMetricsService(PrefService* prefs)
+    : prefs_(prefs) {
+  if (!chromeos::UserDataAuthClient::Get())
+    return;
+  chromeos::UserDataAuthClient::Get()->AddObserver(this);
+  ReportPreviousSessionLowDiskSeverity();
+}
+
+LowDiskMetricsService::~LowDiskMetricsService() {
+  if (!chromeos::UserDataAuthClient::Get())
+    return;
+  chromeos::UserDataAuthClient::Get()->RemoveObserver(this);
+}
+
+void LowDiskMetricsService::LowDiskSpace(
+    const ::user_data_auth::LowDiskSpace& status) {
+  auto severity = GetSeverity(status.disk_free_bytes());
+  base::UmaHistogramEnumeration(kKioskSessionLowDiskSeverityHistogram,
+                                severity);
+
+  if (severity > low_disk_severity_) {
+    low_disk_severity_ = severity;
+    UpdateCurrentSessionLowDiskSeverity(severity);
+  }
+}
+
+void LowDiskMetricsService::UpdateCurrentSessionLowDiskSeverity(
+    KioskLowDiskSeverity severity) {
+  if (!prefs_->GetDictionary(prefs::kKioskMetrics)) {
+    prefs_->SetDict(prefs::kKioskMetrics, base::Value::Dict());
+  }
+  prefs::ScopedDictionaryPrefUpdate update(prefs_, prefs::kKioskMetrics);
+  update->SetInteger(kKioskLowDiskSeverity, static_cast<int>(severity));
+}
+
+void LowDiskMetricsService::ReportPreviousSessionLowDiskSeverity() {
+  const auto* metrics_value = prefs_->GetDictionary(prefs::kKioskMetrics);
+  if (!metrics_value) {
+    UpdateCurrentSessionLowDiskSeverity(low_disk_severity_);
+    return;
+  }
+  const auto* metrics_dict = metrics_value->GetIfDict();
+  DCHECK(metrics_dict);
+
+  const auto* severity_value = metrics_dict->Find(kKioskLowDiskSeverity);
+  if (!severity_value) {
+    UpdateCurrentSessionLowDiskSeverity(low_disk_severity_);
+    return;
+  }
+
+  auto severity = severity_value->GetIfInt();
+  if (!severity.has_value()) {
+    UpdateCurrentSessionLowDiskSeverity(low_disk_severity_);
+    return;
+  }
+  base::UmaHistogramEnumeration(
+      kKioskSessionLowDiskHighestSeverityHistogram,
+      static_cast<KioskLowDiskSeverity>(severity.value()));
+  UpdateCurrentSessionLowDiskSeverity(low_disk_severity_);
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.h b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.h
new file mode 100644
index 0000000..13babce2
--- /dev/null
+++ b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.h
@@ -0,0 +1,63 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_APP_MODE_METRICS_LOW_DISK_METRICS_SERVICE_H_
+#define CHROME_BROWSER_ASH_APP_MODE_METRICS_LOW_DISK_METRICS_SERVICE_H_
+
+#include <utility>
+
+#include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
+#include "components/prefs/pref_service.h"
+
+namespace ash {
+
+extern const char kKioskLowDiskSeverity[];
+extern const char kKioskSessionLowDiskSeverityHistogram[];
+extern const char kKioskSessionLowDiskHighestSeverityHistogram[];
+
+extern const uint64_t kLowDiskMediumThreshold;
+extern const uint64_t kLowDiskSevereThreshold;
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+// Keep in sync with respective enum in tools/metrics/histograms/enums.xml
+enum class KioskLowDiskSeverity {
+  kNone = 0,
+  kMedium = 1,
+  kHigh = 2,
+  kMaxValue = kHigh,
+};
+
+// LowDiskMetricsService tracks and reports severity of low disk notifications.
+class LowDiskMetricsService : public chromeos::UserDataAuthClient::Observer {
+ public:
+  LowDiskMetricsService();
+  LowDiskMetricsService(LowDiskMetricsService&) = delete;
+  LowDiskMetricsService& operator=(const LowDiskMetricsService&) = delete;
+  ~LowDiskMetricsService() override;
+
+  static std::unique_ptr<LowDiskMetricsService> CreateForTesting(
+      PrefService* pref);
+
+ private:
+  explicit LowDiskMetricsService(PrefService* prefs);
+
+  // Called when the device is running low on disk space.
+  // This is responsible for tracking the severity metrics.
+  void LowDiskSpace(const ::user_data_auth::LowDiskSpace& status) override;
+
+  // Update a low disk severity for the current session.
+  void UpdateCurrentSessionLowDiskSeverity(KioskLowDiskSeverity severity);
+
+  // Report a highest severity of the previous session.
+  void ReportPreviousSessionLowDiskSeverity();
+
+  PrefService* prefs_;
+  // The highest low disk notification severity during the session.
+  KioskLowDiskSeverity low_disk_severity_{KioskLowDiskSeverity::kNone};
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_APP_MODE_METRICS_LOW_DISK_METRICS_SERVICE_H_
diff --git a/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service_unittest.cc b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service_unittest.cc
new file mode 100644
index 0000000..09af339
--- /dev/null
+++ b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service_unittest.cc
@@ -0,0 +1,144 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/app_mode/metrics/low_disk_metrics_service.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/task_environment.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.h"
+#include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ash {
+
+class LowDiskMetricsServiceTest
+    : public testing::TestWithParam<
+          std::tuple<KioskLowDiskSeverity, uint64_t>> {
+ public:
+  LowDiskMetricsServiceTest()
+      : local_state_(std::make_unique<ScopedTestingLocalState>(
+            TestingBrowserProcess::GetGlobal())) {
+    UserDataAuthClient::InitializeFake();
+  }
+
+  LowDiskMetricsServiceTest(const LowDiskMetricsServiceTest&) = delete;
+  LowDiskMetricsServiceTest& operator=(const LowDiskMetricsServiceTest&) =
+      delete;
+
+  KioskLowDiskSeverity severity() const { return std::get<0>(GetParam()); }
+  uint64_t disk_free_bytes() const { return std::get<1>(GetParam()); }
+
+  TestingPrefServiceSimple* local_state() { return local_state_->Get(); }
+
+  void SetUp() override {
+    histogram_tester_ = std::make_unique<base::HistogramTester>();
+  }
+
+  void TearDown() override {
+    local_state()->RemoveUserPref(prefs::kKioskMetrics);
+  }
+  base::HistogramTester* histogram_tester() { return histogram_tester_.get(); }
+
+  absl::optional<KioskLowDiskSeverity> GetLowDiskSeverityFromLocalState() {
+    const auto* metrics_value =
+        local_state()->GetDictionary(prefs::kKioskMetrics);
+    if (!metrics_value)
+      return absl::nullopt;
+    const auto* metrics_dict = metrics_value->GetIfDict();
+    if (!metrics_dict)
+      return absl::nullopt;
+    const auto* severity_value = metrics_dict->Find(kKioskLowDiskSeverity);
+    if (!severity_value || !severity_value->is_int()) {
+      return absl::nullopt;
+    }
+
+    return static_cast<KioskLowDiskSeverity>(
+        severity_value->GetIfInt().value());
+  }
+
+  void SendLowDiskSpaceEvent(uint64_t disk_free_bytes) {
+    FakeUserDataAuthClient::Get()->NotifyLowDiskSpace(disk_free_bytes);
+    task_environment_.RunUntilIdle();
+  }
+
+ private:
+  base::test::SingleThreadTaskEnvironment task_environment_;
+  std::unique_ptr<base::HistogramTester> histogram_tester_;
+  std::unique_ptr<ScopedTestingLocalState> local_state_;
+};
+
+TEST_P(LowDiskMetricsServiceTest, Severity) {
+  auto service = LowDiskMetricsService::CreateForTesting(local_state());
+
+  histogram_tester()->ExpectTotalCount(kKioskSessionLowDiskSeverityHistogram,
+                                       0);
+  histogram_tester()->ExpectTotalCount(
+      kKioskSessionLowDiskHighestSeverityHistogram, 0);
+
+  SendLowDiskSpaceEvent(disk_free_bytes());
+  histogram_tester()->ExpectBucketCount(kKioskSessionLowDiskSeverityHistogram,
+                                        severity(), 1);
+  histogram_tester()->ExpectTotalCount(kKioskSessionLowDiskSeverityHistogram,
+                                       1);
+  EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(), severity());
+
+  service = LowDiskMetricsService::CreateForTesting(local_state());
+  histogram_tester()->ExpectBucketCount(
+      kKioskSessionLowDiskHighestSeverityHistogram, severity(), 1);
+  EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(),
+            KioskLowDiskSeverity::kNone);
+}
+
+TEST_F(LowDiskMetricsServiceTest, Update) {
+  auto service = LowDiskMetricsService::CreateForTesting(local_state());
+
+  SendLowDiskSpaceEvent(kLowDiskMediumThreshold + 1);
+  histogram_tester()->ExpectBucketCount(kKioskSessionLowDiskSeverityHistogram,
+                                        KioskLowDiskSeverity::kNone, 1);
+  histogram_tester()->ExpectTotalCount(kKioskSessionLowDiskSeverityHistogram,
+                                       1);
+  EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(),
+            KioskLowDiskSeverity::kNone);
+
+  // Update to higher severity.
+  SendLowDiskSpaceEvent(kLowDiskMediumThreshold - 1);
+  histogram_tester()->ExpectBucketCount(kKioskSessionLowDiskSeverityHistogram,
+                                        KioskLowDiskSeverity::kMedium, 1);
+  histogram_tester()->ExpectTotalCount(kKioskSessionLowDiskSeverityHistogram,
+                                       2);
+  EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(),
+            KioskLowDiskSeverity::kMedium);
+
+  // Update to higher severity.
+  SendLowDiskSpaceEvent(kLowDiskSevereThreshold - 1);
+  histogram_tester()->ExpectBucketCount(kKioskSessionLowDiskSeverityHistogram,
+                                        KioskLowDiskSeverity::kHigh, 1);
+  histogram_tester()->ExpectTotalCount(kKioskSessionLowDiskSeverityHistogram,
+                                       3);
+  EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(),
+            KioskLowDiskSeverity::kHigh);
+
+  // Do not update to higher severity.
+  SendLowDiskSpaceEvent(kLowDiskSevereThreshold + 1);
+  histogram_tester()->ExpectBucketCount(kKioskSessionLowDiskSeverityHistogram,
+                                        KioskLowDiskSeverity::kMedium, 2);
+  histogram_tester()->ExpectTotalCount(kKioskSessionLowDiskSeverityHistogram,
+                                       4);
+  EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(),
+            KioskLowDiskSeverity::kHigh);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    LowDiskMetricsServiceTest,
+    LowDiskMetricsServiceTest,
+    testing::Values(
+        std::tuple(KioskLowDiskSeverity::kNone, kLowDiskMediumThreshold + 1),
+        std::tuple(KioskLowDiskSeverity::kMedium, kLowDiskMediumThreshold - 1),
+        std::tuple(KioskLowDiskSeverity::kHigh, kLowDiskSevereThreshold - 1)));
+
+}  // namespace ash
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action.cc b/chrome/browser/ash/arc/input_overlay/actions/action.cc
index cac74e5..1d3f234 100644
--- a/chrome/browser/ash/arc/input_overlay/actions/action.cc
+++ b/chrome/browser/ash/arc/input_overlay/actions/action.cc
@@ -273,7 +273,8 @@
 }
 
 absl::optional<gfx::PointF> Action::CalculateTouchPosition(
-    const gfx::RectF& content_bounds) {
+    const gfx::RectF& content_bounds,
+    const gfx::Transform* rotation_transform) {
   if (locations_.empty())
     return absl::nullopt;
   DCHECK(current_position_index_ < locations_.size());
@@ -288,6 +289,8 @@
 
   gfx::PointF root_location = gfx::PointF(root_point);
   root_location.Scale(scale);
+  if (rotation_transform)
+    rotation_transform->TransformPoint(&root_location);
 
   VLOG(1) << "Calculate touch position: local position {" << point.ToString()
           << "}, root location {" << root_point.ToString()
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action.h b/chrome/browser/ash/arc/input_overlay/actions/action.h
index e3bd5d0..72c642b 100644
--- a/chrome/browser/ash/arc/input_overlay/actions/action.h
+++ b/chrome/browser/ash/arc/input_overlay/actions/action.h
@@ -74,6 +74,7 @@
   virtual bool RewriteEvent(const ui::Event& origin,
                             const gfx::RectF& content_bounds,
                             const bool is_mouse_locked,
+                            const gfx::Transform* rotation_transform,
                             std::list<ui::TouchEvent>& touch_events,
                             bool& keep_original_event) = 0;
   // Get the UI location in the content view.
@@ -135,7 +136,8 @@
   explicit Action(aura::Window* window);
 
   absl::optional<gfx::PointF> CalculateTouchPosition(
-      const gfx::RectF& content_bounds);
+      const gfx::RectF& content_bounds,
+      const gfx::Transform* rotation_transform);
   bool IsRepeatedKeyEvent(const ui::KeyEvent& key_event);
   // Verify the key release event. If it is verified, it continues to simulate
   // the touch event. Otherwise, consider it as discard.
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_move.cc b/chrome/browser/ash/arc/input_overlay/actions/action_move.cc
index f5719ad..265dabd9 100644
--- a/chrome/browser/ash/arc/input_overlay/actions/action_move.cc
+++ b/chrome/browser/ash/arc/input_overlay/actions/action_move.cc
@@ -346,6 +346,7 @@
 bool ActionMove::RewriteEvent(const ui::Event& origin,
                               const gfx::RectF& content_bounds,
                               const bool is_mouse_locked,
+                              const gfx::Transform* rotation_transform,
                               std::list<ui::TouchEvent>& touch_events,
                               bool& keep_original_event) {
   if (!IsBound(*current_binding_) ||
@@ -361,7 +362,8 @@
   // Rewrite for key event.
   if (IsKeyboardBound(*current_binding_)) {
     auto* key_event = origin.AsKeyEvent();
-    bool rewritten = RewriteKeyEvent(key_event, content_bounds, touch_events);
+    bool rewritten = RewriteKeyEvent(key_event, content_bounds,
+                                     rotation_transform, touch_events);
     LogTouchEvents(touch_events);
     return rewritten;
   }
@@ -370,7 +372,8 @@
   if (!is_mouse_locked)
     return false;
   auto* mouse_event = origin.AsMouseEvent();
-  auto rewritten = RewriteMouseEvent(mouse_event, content_bounds, touch_events);
+  bool rewritten = RewriteMouseEvent(mouse_event, content_bounds,
+                                     rotation_transform, touch_events);
   LogTouchEvents(touch_events);
 
   return rewritten;
@@ -424,6 +427,7 @@
 
 bool ActionMove::RewriteKeyEvent(const ui::KeyEvent* key_event,
                                  const gfx::RectF& content_bounds,
+                                 const gfx::Transform* rotation_transform,
                                  std::list<ui::TouchEvent>& rewritten_events) {
   auto keys = current_binding_->keys();
   auto it = std::find(keys.begin(), keys.end(), key_event->code());
@@ -437,7 +441,7 @@
   int index = it - keys.begin();
   DCHECK(index >= 0 && index < kActionMoveKeysSize);
 
-  auto pos = CalculateTouchPosition(content_bounds);
+  auto pos = CalculateTouchPosition(content_bounds, rotation_transform);
   DCHECK(pos);
 
   if (key_event->type() == ui::ET_KEY_PRESSED) {
@@ -445,10 +449,10 @@
       // First key press generates touch press.
       touch_id_ = TouchIdManager::GetInstance()->ObtainTouchID();
       last_touch_root_location_ = *pos;
-      rewritten_events.emplace_back(ui::TouchEvent(
+      rewritten_events.emplace_back(
           ui::EventType::ET_TOUCH_PRESSED, last_touch_root_location_,
           last_touch_root_location_, key_event->time_stamp(),
-          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
       ui::Event::DispatcherApi(&(rewritten_events.back()))
           .set_target(target_window_);
     }
@@ -457,11 +461,12 @@
       return false;
 
     // Generate touch move.
-    CalculateMoveVector(*pos, index, /* key_press */ true, content_bounds);
-    rewritten_events.emplace_back(ui::TouchEvent(
+    CalculateMoveVector(*pos, index, /*key_press=*/true, content_bounds,
+                        rotation_transform);
+    rewritten_events.emplace_back(
         ui::EventType::ET_TOUCH_MOVED, last_touch_root_location_,
         last_touch_root_location_, key_event->time_stamp(),
-        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
     ui::Event::DispatcherApi(&(rewritten_events.back()))
         .set_target(target_window_);
     keys_pressed_.emplace(key_event->code());
@@ -471,19 +476,20 @@
 
     if (keys_pressed_.size() > 1) {
       // Generate new move.
-      CalculateMoveVector(*pos, index, /* key_press */ false, content_bounds);
-      rewritten_events.emplace_back(ui::TouchEvent(
+      CalculateMoveVector(*pos, index, /*key_press=*/false, content_bounds,
+                          rotation_transform);
+      rewritten_events.emplace_back(
           ui::EventType::ET_TOUCH_MOVED, last_touch_root_location_,
           last_touch_root_location_, key_event->time_stamp(),
-          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
       ui::Event::DispatcherApi(&(rewritten_events.back()))
           .set_target(target_window_);
     } else {
       // Generate touch release.
-      rewritten_events.emplace_back(ui::TouchEvent(
+      rewritten_events.emplace_back(
           ui::EventType::ET_TOUCH_RELEASED, last_touch_root_location_,
           last_touch_root_location_, key_event->time_stamp(),
-          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
       ui::Event::DispatcherApi(&(rewritten_events.back()))
           .set_target(target_window_);
       OnTouchReleased();
@@ -498,6 +504,7 @@
 bool ActionMove::RewriteMouseEvent(
     const ui::MouseEvent* mouse_event,
     const gfx::RectF& content_bounds,
+    const gfx::Transform* rotation_transform,
     std::list<ui::TouchEvent>& rewritten_events) {
   DCHECK(mouse_event);
 
@@ -526,7 +533,8 @@
     DCHECK(touch_id_);
   if (!touch_id_) {
     touch_id_ = TouchIdManager::GetInstance()->ObtainTouchID();
-    auto touch_down_pos = CalculateTouchPosition(content_bounds);
+    auto touch_down_pos =
+        CalculateTouchPosition(content_bounds, rotation_transform);
     if (touch_down_pos)
       last_touch_root_location_ = *touch_down_pos;
     rewritten_events.emplace_back(
@@ -554,7 +562,8 @@
 void ActionMove::CalculateMoveVector(gfx::PointF& touch_press_pos,
                                      int direction_index,
                                      bool key_press,
-                                     const gfx::RectF& content_bounds) {
+                                     const gfx::RectF& content_bounds,
+                                     const gfx::Transform* rotation_transform) {
   DCHECK(direction_index >= 0 && direction_index < kActionMoveKeysSize);
   auto new_move = gfx::Vector2dF(kDirection[direction_index][0],
                                  kDirection[direction_index][1]);
@@ -566,7 +575,13 @@
   } else {
     move_vector_ -= new_move;
   }
-  last_touch_root_location_ = touch_press_pos + move_vector_;
+
+  auto location =
+      gfx::Point((int)touch_press_pos.x(), (int)touch_press_pos.y());
+  if (rotation_transform)
+    rotation_transform->TransformPointReverse(&location);
+  last_touch_root_location_ = gfx::PointF(location) + move_vector_;
+
   float x = last_touch_root_location_.x();
   float y = last_touch_root_location_.y();
   last_touch_root_location_.set_x(
@@ -575,6 +590,8 @@
   last_touch_root_location_.set_y(
       base::clamp(y, content_bounds.y() * display_scale_factor,
                   content_bounds.bottom() * display_scale_factor));
+  if (rotation_transform)
+    rotation_transform->TransformPoint(&last_touch_root_location_);
 }
 
 absl::optional<gfx::RectF> ActionMove::CalculateApplyArea(
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_move.h b/chrome/browser/ash/arc/input_overlay/actions/action_move.h
index 1b84057..ec9abe1 100644
--- a/chrome/browser/ash/arc/input_overlay/actions/action_move.h
+++ b/chrome/browser/ash/arc/input_overlay/actions/action_move.h
@@ -29,6 +29,7 @@
   bool RewriteEvent(const ui::Event& origin,
                     const gfx::RectF& content_bounds,
                     const bool is_mouse_locked,
+                    const gfx::Transform* rotation_transform,
                     std::list<ui::TouchEvent>& touch_events,
                     bool& keep_original_event) override;
   gfx::PointF GetUICenterPosition(const gfx::RectF& content_bounds) override;
@@ -87,16 +88,19 @@
   bool ParseJsonFromMouse(const base::Value& value);
   bool RewriteKeyEvent(const ui::KeyEvent* key_event,
                        const gfx::RectF& content_bounds,
+                       const gfx::Transform* rotation_transform,
                        std::list<ui::TouchEvent>& rewritten_events);
   bool RewriteMouseEvent(const ui::MouseEvent* mouse_event,
                          const gfx::RectF& content_bounds,
+                         const gfx::Transform* rotation_transform,
                          std::list<ui::TouchEvent>& rewritten_events);
 
   // For key-bound move.
   void CalculateMoveVector(gfx::PointF& touch_press_pos,
                            int direction_index,
                            bool key_press,
-                           const gfx::RectF& content_bounds);
+                           const gfx::RectF& content_bounds,
+                           const gfx::Transform* rotation_transform);
 
   // For mouse-bound move.
   // Return the bounds in the root window.
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc b/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc
index e6449cbc..015c921 100644
--- a/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc
+++ b/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc
@@ -225,6 +225,7 @@
 bool ActionTap::RewriteEvent(const ui::Event& origin,
                              const gfx::RectF& content_bounds,
                              const bool is_mouse_locked,
+                             const gfx::Transform* rotation_transform,
                              std::list<ui::TouchEvent>& touch_events,
                              bool& keep_original_event) {
   if (!IsBound(*current_binding_) ||
@@ -240,8 +241,9 @@
   // Rewrite for key event.
   if (IsKeyboardBound(*current_binding())) {
     auto* key_event = origin.AsKeyEvent();
-    bool rewritten = RewriteKeyEvent(key_event, content_bounds, touch_events,
-                                     keep_original_event);
+    bool rewritten =
+        RewriteKeyEvent(key_event, content_bounds, rotation_transform,
+                        touch_events, keep_original_event);
     LogTouchEvents(touch_events);
     return rewritten;
   }
@@ -249,7 +251,8 @@
   if (!is_mouse_locked)
     return false;
   auto* mouse_event = origin.AsMouseEvent();
-  auto rewritten = RewriteMouseEvent(mouse_event, touch_events, content_bounds);
+  bool rewritten = RewriteMouseEvent(mouse_event, content_bounds,
+                                     rotation_transform, touch_events);
   LogTouchEvents(touch_events);
   return rewritten;
 }
@@ -280,6 +283,7 @@
 
 bool ActionTap::RewriteKeyEvent(const ui::KeyEvent* key_event,
                                 const gfx::RectF& content_bounds,
+                                const gfx::Transform* rotation_transform,
                                 std::list<ui::TouchEvent>& rewritten_events,
                                 bool& keep_original_event) {
   DCHECK(key_event);
@@ -302,15 +306,15 @@
     DCHECK(touch_id_);
     if (!touch_id_)
       return false;
-    auto pos = CalculateTouchPosition(content_bounds);
+    auto pos = CalculateTouchPosition(content_bounds, rotation_transform);
     if (!pos)
       return false;
     last_touch_root_location_ = *pos;
 
-    rewritten_events.emplace_back(ui::TouchEvent(
+    rewritten_events.emplace_back(
         ui::EventType::ET_TOUCH_PRESSED, last_touch_root_location_,
         last_touch_root_location_, key_event->time_stamp(),
-        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
     ui::Event::DispatcherApi(&(rewritten_events.back()))
         .set_target(target_window_);
     if (!current_binding_->is_modifier_key()) {
@@ -321,10 +325,10 @@
       // can still receive the release event. To avoid error in
       // AcceleratorHistory, original press event is still sent.
       keep_original_event = true;
-      rewritten_events.emplace_back(ui::TouchEvent(
+      rewritten_events.emplace_back(
           ui::EventType::ET_TOUCH_RELEASED, last_touch_root_location_,
           last_touch_root_location_, key_event->time_stamp(),
-          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+          ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
       ui::Event::DispatcherApi(&(rewritten_events.back()));
       OnTouchReleased();
     }
@@ -332,10 +336,10 @@
     if (!VerifyOnKeyRelease(key_event->code()))
       return true;
 
-    rewritten_events.emplace_back(ui::TouchEvent(
+    rewritten_events.emplace_back(
         ui::EventType::ET_TOUCH_RELEASED, last_touch_root_location_,
         last_touch_root_location_, key_event->time_stamp(),
-        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
     ui::Event::DispatcherApi(&(rewritten_events.back()))
         .set_target(target_window_);
 
@@ -348,8 +352,9 @@
 }
 
 bool ActionTap::RewriteMouseEvent(const ui::MouseEvent* mouse_event,
-                                  std::list<ui::TouchEvent>& rewritten_events,
-                                  const gfx::RectF& content_bounds) {
+                                  const gfx::RectF& content_bounds,
+                                  const gfx::Transform* rotation_transform,
+                                  std::list<ui::TouchEvent>& rewritten_events) {
   DCHECK(mouse_event);
 
   auto type = mouse_event->type();
@@ -366,7 +371,8 @@
 
   if (!touch_id_) {
     touch_id_ = TouchIdManager::GetInstance()->ObtainTouchID();
-    auto touch_down_pos = CalculateTouchPosition(content_bounds);
+    auto touch_down_pos =
+        CalculateTouchPosition(content_bounds, rotation_transform);
     if (touch_down_pos) {
       last_touch_root_location_ = *touch_down_pos;
     } else {
@@ -376,15 +382,15 @@
       float scale = target_window_->GetHost()->device_scale_factor();
       last_touch_root_location_.Scale(scale);
     }
-    rewritten_events.emplace_back(ui::TouchEvent(
+    rewritten_events.emplace_back(
         ui::EventType::ET_TOUCH_PRESSED, last_touch_root_location_,
         last_touch_root_location_, mouse_event->time_stamp(),
-        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
   } else {
-    rewritten_events.emplace_back(ui::TouchEvent(
+    rewritten_events.emplace_back(
         ui::EventType::ET_TOUCH_RELEASED, last_touch_root_location_,
         last_touch_root_location_, mouse_event->time_stamp(),
-        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_)));
+        ui::PointerDetails(ui::EventPointerType::kTouch, *touch_id_));
     OnTouchReleased();
   }
   ui::Event::DispatcherApi(&(rewritten_events.back()))
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_tap.h b/chrome/browser/ash/arc/input_overlay/actions/action_tap.h
index 2f08360..4a3d6610 100644
--- a/chrome/browser/ash/arc/input_overlay/actions/action_tap.h
+++ b/chrome/browser/ash/arc/input_overlay/actions/action_tap.h
@@ -24,6 +24,7 @@
   bool RewriteEvent(const ui::Event& origin,
                     const gfx::RectF& content_bounds,
                     const bool is_mouse_locked,
+                    const gfx::Transform* rotation_transform,
                     std::list<ui::TouchEvent>& touch_events,
                     bool& keep_original_event) override;
   gfx::PointF GetUICenterPosition(const gfx::RectF& content_bounds) override;
@@ -70,11 +71,13 @@
   bool ParseJsonFromMouse(const base::Value& value);
   bool RewriteKeyEvent(const ui::KeyEvent* key_event,
                        const gfx::RectF& content_bounds,
+                       const gfx::Transform* rotation_transform,
                        std::list<ui::TouchEvent>& rewritten_events,
                        bool& keep_original_event);
   bool RewriteMouseEvent(const ui::MouseEvent* mouse_event,
-                         std::list<ui::TouchEvent>& rewritten_events,
-                         const gfx::RectF& content_bounds);
+                         const gfx::RectF& content_bounds,
+                         const gfx::Transform* rotation_transform,
+                         std::list<ui::TouchEvent>& rewritten_events);
 };
 
 }  // namespace input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc
index 9d6217a0..447ec25 100644
--- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc
+++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc
@@ -20,6 +20,7 @@
 #include "ui/base/ime/input_method_observer.h"
 #include "ui/base/ime/text_input_client.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/display/manager/display_manager.h"
 
 namespace arc {
 namespace {
@@ -82,15 +83,18 @@
     : input_method_observer_(std::make_unique<InputMethodObserver>(this)) {
   if (aura::Env::HasInstance())
     env_observation_.Observe(aura::Env::GetInstance());
-  if (ash::Shell::HasInstance() &&
-      ash::Shell::Get()->tablet_mode_controller()) {
-    ash::Shell::Get()->tablet_mode_controller()->AddObserver(this);
-  }
-  if (ash::Shell::HasInstance() && ash::Shell::GetPrimaryRootWindow()) {
-    aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow())
-        ->AddObserver(this);
-  }
+  if (ash::Shell::HasInstance()) {
+    if (ash::Shell::Get()->tablet_mode_controller())
+      ash::Shell::Get()->tablet_mode_controller()->AddObserver(this);
 
+    if (ash::Shell::Get()->display_manager())
+      ash::Shell::Get()->display_manager()->AddObserver(this);
+
+    if (ash::Shell::GetPrimaryRootWindow()) {
+      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow())
+          ->AddObserver(this);
+    }
+  }
   task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
       {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
        // Should not block shutdown.
@@ -357,20 +361,31 @@
     return;
   if (display_overlay_controller_)
     display_overlay_controller_->OnWindowBoundsChanged();
+
+  auto it = input_overlay_enabled_windows_.find(window);
+  if (it == input_overlay_enabled_windows_.end())
+    return;
+
+  it->second->Update();
 }
 
 void ArcInputOverlayManager::Shutdown() {
   UnRegisterWindow(registered_top_level_window_);
   window_observations_.RemoveAllObservations();
-  if (ash::Shell::HasInstance() && ash::Shell::GetPrimaryRootWindow()) {
-    aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow())
-        ->RemoveObserver(this);
+  if (ash::Shell::HasInstance()) {
+    if (ash::Shell::GetPrimaryRootWindow()) {
+      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow())
+          ->RemoveObserver(this);
+    }
+
+    if (ash::Shell::Get()->tablet_mode_controller())
+      ash::Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
+
+    if (ash::Shell::Get()->display_manager())
+      ash::Shell::Get()->display_manager()->RemoveObserver(this);
   }
-  if (ash::Shell::HasInstance() &&
-      ash::Shell::Get()->tablet_mode_controller()) {
-    ash::Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
-  }
-  env_observation_.Reset();
+  if (aura::Env::HasInstance())
+    env_observation_.Reset();
 }
 
 void ArcInputOverlayManager::OnWindowFocused(aura::Window* gained_focus,
@@ -402,4 +417,17 @@
   RegisterFocusedWindow();
 }
 
+void ArcInputOverlayManager::OnDisplayMetricsChanged(
+    const display::Display& display,
+    uint32_t metrics) {
+  if (!registered_top_level_window_)
+    return;
+
+  auto it = input_overlay_enabled_windows_.find(registered_top_level_window_);
+  if (it == input_overlay_enabled_windows_.end())
+    return;
+
+  it->second->Update();
+}
+
 }  // namespace arc
diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h
index 0d4ef4f2..ebea286 100644
--- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h
+++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h
@@ -25,6 +25,7 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
 #include "ui/base/ime/input_method.h"
+#include "ui/display/display_observer.h"
 
 namespace content {
 class BrowserContext;
@@ -40,7 +41,8 @@
                                public aura::EnvObserver,
                                public aura::WindowObserver,
                                public aura::client::FocusChangeObserver,
-                               public ash::TabletModeObserver {
+                               public ash::TabletModeObserver,
+                               public display::DisplayObserver {
  public:
   // Returns singleton instance for the given BrowserContext,
   // or nullptr if the browser |context| is not allowed to use ARC.
@@ -79,6 +81,10 @@
   void OnTabletModeStarting() override;
   void OnTabletModeEnded() override;
 
+  // display::DisplayObserver:
+  void OnDisplayMetricsChanged(const display::Display& display,
+                               uint32_t metrics) override;
+
  private:
   friend class ArcInputOverlayManagerTest;
 
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
index b931cc8..cd0d2e1 100644
--- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
+++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
@@ -17,7 +17,6 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/layout/layout_types.h"
-#include "ui/views/widget/widget_observer.h"
 
 namespace views {
 class Widget;
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.cc b/chrome/browser/ash/arc/input_overlay/touch_injector.cc
index d427a891..7196c42 100644
--- a/chrome/browser/ash/arc/input_overlay/touch_injector.cc
+++ b/chrome/browser/ash/arc/input_overlay/touch_injector.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "ash/public/cpp/window_properties.h"
+#include "ash/utility/transformer_util.h"
 #include "base/bind.h"
 #include "base/containers/flat_set.h"
 #include "base/task/thread_pool.h"
@@ -16,6 +17,8 @@
 #include "chrome/browser/ash/arc/input_overlay/arc_input_overlay_uma.h"
 #include "chrome/browser/ash/arc/input_overlay/touch_id_manager.h"
 #include "ui/aura/window.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/events/base_event_utils.h"
 #include "ui/events/event_constants.h"
 #include "ui/views/controls/label.h"
@@ -166,6 +169,7 @@
   if (observation_.IsObserving())
     return;
   observation_.Observe(target_window_->GetHost()->GetEventSource());
+  Update();
 }
 
 void TouchInjector::UnRegisterEventRewriter() {
@@ -175,6 +179,22 @@
   observation_.Reset();
 }
 
+void TouchInjector::Update() {
+  if (rotation_transform_)
+    rotation_transform_.reset();
+
+  auto display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(target_window_);
+  // No need to transform if there is no rotation.
+  if (display.panel_rotation() == display::Display::ROTATE_0)
+    return;
+
+  rotation_transform_ =
+      std::make_unique<gfx::Transform>(ash::CreateRotationTransform(
+          display::Display::ROTATE_0, display.panel_rotation(),
+          gfx::SizeF(display.GetSizeInPixel())));
+}
+
 void TouchInjector::OnBindingChange(
     Action* target_action,
     std::unique_ptr<InputElement> input_element) {
@@ -508,6 +528,7 @@
   for (auto& action : actions_) {
     bool keep_original_event = false;
     bool rewritten = action->RewriteEvent(event, bounds, is_mouse_locked_,
+                                          rotation_transform_.get(),
                                           touch_events, keep_original_event);
     if (!rewritten)
       continue;
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.h b/chrome/browser/ash/arc/input_overlay/touch_injector.h
index 8da18a9..396c10f 100644
--- a/chrome/browser/ash/arc/input_overlay/touch_injector.h
+++ b/chrome/browser/ash/arc/input_overlay/touch_injector.h
@@ -101,6 +101,9 @@
   void RegisterEventRewriter();
   // Unregister the EventRewriter.
   void UnRegisterEventRewriter();
+  // Update info for touch injector. For example, update transform information
+  // if there is screen rotation.
+  void Update();
   // Change bindings. This could be from user editing from display overlay
   // (|mode| = DisplayMode::kEdit) or from customized protobuf data (|mode| =
   // DisplayMode::kView).
@@ -205,6 +208,7 @@
                           &ui::EventSource::RemoveEventRewriter>
       observation_{this};
   std::unique_ptr<KeyCommand> mouse_lock_;
+  std::unique_ptr<gfx::Transform> rotation_transform_;
   bool text_input_active_ = false;
   // The mouse is unlocked by default.
   bool is_mouse_locked_ = false;
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_label.cc b/chrome/browser/ash/arc/input_overlay/ui/action_label.cc
index 5b938a40..2189bc8 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/action_label.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/action_label.cc
@@ -265,10 +265,11 @@
   LabelButton::OnFocus();
   if (IsUnbound()) {
     static_cast<ActionView*>(parent())->ShowErrorMsg(
-        l10n_util::GetStringUTF8(IDS_INPUT_OVERLAY_EDIT_MISSING_BINDING), this);
+        l10n_util::GetStringUTF8(IDS_INPUT_OVERLAY_EDIT_MISSING_BINDING), this,
+        /*ax_annouce=*/false);
   } else {
     static_cast<ActionView*>(parent())->ShowLabelFocusInfoMsg(
-        l10n_util::GetStringUTF8(IDS_INPUT_OVERLAY_EDIT_FOCUSED_KEY));
+        l10n_util::GetStringUTF8(IDS_INPUT_OVERLAY_EDIT_FOCUSED_KEY), this);
   }
 }
 
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_view.cc b/chrome/browser/ash/arc/input_overlay/ui/action_view.cc
index d4c28795..1d88680 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/action_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/action_view.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_piece.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/views/accessibility/view_accessibility.h"
 
 namespace arc {
 namespace input_overlay {
@@ -99,9 +100,16 @@
 }
 
 void ActionView::ShowErrorMsg(const base::StringPiece& message,
-                              ActionLabel* editing_label) {
+                              ActionLabel* editing_label,
+                              bool ax_annouce) {
   display_overlay_controller_->AddEditMessage(message, MessageType::kError);
   SetDisplayMode(DisplayMode::kEditedError, editing_label);
+  if (ax_annouce) {
+    GetViewAccessibility().AnnounceText(base::UTF8ToUTF16(message));
+  } else {
+    editing_label->GetViewAccessibility().OverrideDescription(
+        base::UTF8ToUTF16(message));
+  }
 }
 
 void ActionView::ShowInfoMsg(const base::StringPiece& message,
@@ -109,9 +117,12 @@
   display_overlay_controller_->AddEditMessage(message, MessageType::kInfo);
 }
 
-void ActionView::ShowLabelFocusInfoMsg(const base::StringPiece& message) {
+void ActionView::ShowLabelFocusInfoMsg(const base::StringPiece& message,
+                                       ActionLabel* editing_label) {
   display_overlay_controller_->AddEditMessage(message,
                                               MessageType::kInfoLabelFocus);
+  editing_label->GetViewAccessibility().OverrideDescription(
+      base::UTF8ToUTF16(message));
 }
 
 void ActionView::RemoveMessage() {
@@ -143,7 +154,7 @@
        ModifierDomCodeToEventFlag(code) != ui::EF_NONE) ||
       IsReservedDomCode(code)) {
     ShowErrorMsg(l10n_util::GetStringUTF8(IDS_INPUT_OVERLAY_EDIT_RESERVED_KEYS),
-                 editing_label);
+                 editing_label, /*ax_annouce=*/true);
     return true;
   }
 
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_view.h b/chrome/browser/ash/arc/input_overlay/ui/action_view.h
index 49d3740..30caaed 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/action_view.h
+++ b/chrome/browser/ash/arc/input_overlay/ui/action_view.h
@@ -59,13 +59,17 @@
   // Get edit menu position in parent's bounds.
   gfx::Point GetEditMenuPosition(gfx::Size menu_size);
   void RemoveEditMenu();
-  // Show error message for action.
+  // Show error message for action. If |ax_annouce| is true, ChromeVox
+  // annouces the |message| directly. Otherwise, |message| is added as the
+  // description of |editing_label|.
   void ShowErrorMsg(const base::StringPiece& message,
-                    ActionLabel* editing_label);
+                    ActionLabel* editing_label,
+                    bool ax_annouce);
   // Show info/edu message.
   void ShowInfoMsg(const base::StringPiece& message,
                    ActionLabel* editing_label);
-  void ShowLabelFocusInfoMsg(const base::StringPiece& message);
+  void ShowLabelFocusInfoMsg(const base::StringPiece& message,
+                             ActionLabel* editing_label);
   void RemoveMessage();
   // Change binding for |action| binding to |input_element| and set
   // |kEditedSuccess| on |action_label| if |action_label| is not nullptr.
diff --git a/chrome/browser/ash/attestation/enrollment_id_upload_manager.cc b/chrome/browser/ash/attestation/enrollment_id_upload_manager.cc
index 2371052..807825b 100644
--- a/chrome/browser/ash/attestation/enrollment_id_upload_manager.cc
+++ b/chrome/browser/ash/attestation/enrollment_id_upload_manager.cc
@@ -16,8 +16,8 @@
 #include "chrome/browser/ash/attestation/attestation_ca_client.h"
 #include "chrome/browser/ash/attestation/attestation_key_payload.pb.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/common/dbus_method_call_status.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/account_id/account_id.h"
diff --git a/chrome/browser/ash/attestation/enrollment_id_upload_manager.h b/chrome/browser/ash/attestation/enrollment_id_upload_manager.h
index 255bff3..8551107 100644
--- a/chrome/browser/ash/attestation/enrollment_id_upload_manager.h
+++ b/chrome/browser/ash/attestation/enrollment_id_upload_manager.h
@@ -13,7 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ash/attestation/enrollment_certificate_uploader.h"
 #include "chrome/browser/ash/settings/device_settings_service.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 
 namespace policy {
diff --git a/chrome/browser/ash/attestation/enrollment_id_upload_manager_unittest.cc b/chrome/browser/ash/attestation/enrollment_id_upload_manager_unittest.cc
index 9aa594ec..217bec9 100644
--- a/chrome/browser/ash/attestation/enrollment_id_upload_manager_unittest.cc
+++ b/chrome/browser/ash/attestation/enrollment_id_upload_manager_unittest.cc
@@ -21,7 +21,7 @@
 #include "chrome/browser/ash/attestation/enrollment_id_upload_manager.h"
 #include "chrome/browser/ash/attestation/mock_enrollment_certificate_uploader.h"
 #include "chrome/browser/ash/settings/device_settings_test_helper.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/ash/attestation/machine_certificate_uploader_impl.cc b/chrome/browser/ash/attestation/machine_certificate_uploader_impl.cc
index 1f3fb5be..fcbcda7f 100644
--- a/chrome/browser/ash/attestation/machine_certificate_uploader_impl.cc
+++ b/chrome/browser/ash/attestation/machine_certificate_uploader_impl.cc
@@ -17,8 +17,8 @@
 #include "chrome/browser/ash/attestation/attestation_ca_client.h"
 #include "chrome/browser/ash/attestation/attestation_key_payload.pb.h"
 #include "chrome/browser/ash/attestation/certificate_util.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/common/dbus_method_call_status.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/account_id/account_id.h"
diff --git a/chrome/browser/ash/attestation/machine_certificate_uploader_impl.h b/chrome/browser/ash/attestation/machine_certificate_uploader_impl.h
index b4d35d6..0635c9f 100644
--- a/chrome/browser/ash/attestation/machine_certificate_uploader_impl.h
+++ b/chrome/browser/ash/attestation/machine_certificate_uploader_impl.h
@@ -12,7 +12,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/attestation/machine_certificate_uploader.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/chrome/browser/ash/attestation/machine_certificate_uploader_impl_unittest.cc b/chrome/browser/ash/attestation/machine_certificate_uploader_impl_unittest.cc
index 2994a76..a358c51 100644
--- a/chrome/browser/ash/attestation/machine_certificate_uploader_impl_unittest.cc
+++ b/chrome/browser/ash/attestation/machine_certificate_uploader_impl_unittest.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/ash/attestation/attestation_key_payload.pb.h"
 #include "chrome/browser/ash/attestation/machine_certificate_uploader_impl.h"
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ash/attestation/platform_verification_flow.cc b/chrome/browser/ash/attestation/platform_verification_flow.cc
index 3bbd108..0d889887 100644
--- a/chrome/browser/ash/attestation/platform_verification_flow.cc
+++ b/chrome/browser/ash/attestation/platform_verification_flow.cc
@@ -23,9 +23,9 @@
 #include "chrome/browser/ash/settings/cros_settings.h"
 #include "chrome/browser/permissions/permission_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/attestation/attestation.pb.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/dbus_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
diff --git a/chrome/browser/ash/attestation/platform_verification_flow.h b/chrome/browser/ash/attestation/platform_verification_flow.h
index ed082bd..25bfc22 100644
--- a/chrome/browser/ash/attestation/platform_verification_flow.h
+++ b/chrome/browser/ash/attestation/platform_verification_flow.h
@@ -13,10 +13,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-// TODO(https://crbug.com/1164001): forward declare AttestationClient
-// before ChromeOS source migration.
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "components/account_id/account_id.h"
 #include "url/gurl.h"
@@ -32,6 +29,9 @@
 }  // namespace user_manager
 
 namespace ash {
+
+class AttestationClient;
+
 namespace attestation {
 
 class AttestationFlow;
diff --git a/chrome/browser/ash/attestation/platform_verification_flow_unittest.cc b/chrome/browser/ash/attestation/platform_verification_flow_unittest.cc
index f8c712d..7fb4a90 100644
--- a/chrome/browser/ash/attestation/platform_verification_flow_unittest.cc
+++ b/chrome/browser/ash/attestation/platform_verification_flow_unittest.cc
@@ -18,9 +18,9 @@
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/attestation/attestation.pb.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -69,11 +69,9 @@
       : certificate_status_(ATTESTATION_SUCCESS),
         fake_certificate_index_(0),
         result_(PlatformVerificationFlow::INTERNAL_ERROR) {
-    ::chromeos::AttestationClient::InitializeFake();
+    AttestationClient::InitializeFake();
   }
-  ~PlatformVerificationFlowTest() override {
-    ::chromeos::AttestationClient::Shutdown();
-  }
+  ~PlatformVerificationFlowTest() override { AttestationClient::Shutdown(); }
 
   void SetUp() {
     // Create a verifier for tests to call.
@@ -212,7 +210,7 @@
 }
 
 TEST_F(PlatformVerificationFlowTest, DBusFailure) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->ConfigureEnrollmentPreparationsStatus(::attestation::STATUS_DBUS_ERROR);
   verifier_->ChallengePlatformKey(mock_user_manager_.GetActiveUser(), kTestID,
@@ -222,7 +220,7 @@
 }
 
 TEST_F(PlatformVerificationFlowTest, AttestationServiceInternalError) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->ConfigureEnrollmentPreparationsStatus(
           ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
@@ -343,9 +341,8 @@
 }
 
 TEST_F(PlatformVerificationFlowTest, AttestationNotPrepared) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(false);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      false);
   verifier_->ChallengePlatformKey(mock_user_manager_.GetActiveUser(), kTestID,
                                   kTestChallenge, CreateChallengeCallback());
   base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc b/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
index 935c65d3..4de92d3 100644
--- a/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
@@ -11,7 +11,7 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/ash/attestation/attestation_ca_client.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "content/public/browser/browser_thread.h"
 #include "crypto/openssl_util.h"
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow.h b/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
index 44cb4a5..393853da 100644
--- a/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
@@ -11,7 +11,7 @@
 #include "base/callback.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/ash/attestation/certificate_util.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "components/account_id/account_id.h"
 #include "third_party/boringssl/src/include/openssl/evp.h"
 
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc b/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
index 0a62c0a..af3057b 100644
--- a/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
@@ -17,9 +17,9 @@
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/attestation/attestation.pb.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
 #include "content/public/test/browser_task_environment.h"
 #include "crypto/rsa_private_key.h"
 #include "net/cert/x509_certificate.h"
@@ -55,12 +55,10 @@
         fake_cert_chains_({}),
         fake_cert_chain_read_index_(0),
         result_cert_chain_({}) {
-    ::chromeos::AttestationClient::InitializeFake();
+    AttestationClient::InitializeFake();
   }
 
-  ~SoftBindAttestationFlowTest() override {
-    ::chromeos::AttestationClient::Shutdown();
-  }
+  ~SoftBindAttestationFlowTest() override { AttestationClient::Shutdown(); }
 
   void SetUp() override {
     auto mock_attestation_flow =
diff --git a/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc b/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc
index fbb2ef5..2cc591dd 100644
--- a/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc
+++ b/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc
@@ -27,8 +27,8 @@
 #include "chrome/browser/extensions/chrome_extension_function_details.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager.pb.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager_client.h"
diff --git a/chrome/browser/ash/attestation/tpm_challenge_key_subtle.h b/chrome/browser/ash/attestation/tpm_challenge_key_subtle.h
index 2db644f..624dde0 100644
--- a/chrome/browser/ash/attestation/tpm_challenge_key_subtle.h
+++ b/chrome/browser/ash/attestation/tpm_challenge_key_subtle.h
@@ -14,9 +14,9 @@
 #include "base/sequence_checker.h"
 #include "chrome/browser/ash/attestation/tpm_challenge_key_result.h"
 #include "chrome/browser/platform_keys/platform_keys.h"
-#include "chromeos/dbus/attestation/attestation_ca.pb.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_ca.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager.pb.h"
 #include "components/account_id/account_id.h"
diff --git a/chrome/browser/ash/attestation/tpm_challenge_key_subtle_unittest.cc b/chrome/browser/ash/attestation/tpm_challenge_key_subtle_unittest.cc
index b633b569..dbad62f3a 100644
--- a/chrome/browser/ash/attestation/tpm_challenge_key_subtle_unittest.cc
+++ b/chrome/browser/ash/attestation/tpm_challenge_key_subtle_unittest.cc
@@ -24,8 +24,8 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager_client.h"
 #include "components/prefs/pref_service.h"
@@ -225,7 +225,7 @@
     : test_profile_choice_(test_profile_choice),
       testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {
   ::chromeos::TpmManagerClient::InitializeFake();
-  ::chromeos::AttestationClient::InitializeFake();
+  AttestationClient::InitializeFake();
   CHECK(testing_profile_manager_.SetUp());
 
   challenge_key_subtle_ = std::make_unique<TpmChallengeKeySubtleImpl>(
@@ -237,7 +237,7 @@
 }
 
 TpmChallengeKeySubtleTestBase::~TpmChallengeKeySubtleTestBase() {
-  ::chromeos::AttestationClient::Shutdown();
+  AttestationClient::Shutdown();
   ::chromeos::TpmManagerClient::Shutdown();
 }
 
@@ -511,9 +511,8 @@
 }
 
 TEST_P(DeviceKeysAccessTpmChallengeKeySubtleTest, AttestationNotPrepared) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(false);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      false);
 
   RunOneStepAndExpect(KEY_DEVICE,
                       /*will_register_key=*/false, kEmptyKeyName,
@@ -523,9 +522,8 @@
 
 // Test that we get a proper error message in case we don't have a TPM.
 TEST_P(DeviceKeysAccessTpmChallengeKeySubtleTest, AttestationUnsupported) {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ConfigureEnrollmentPreparations(false);
+  AttestationClient::Get()->GetTestInterface()->ConfigureEnrollmentPreparations(
+      false);
   chromeos::TpmManagerClient::Get()
       ->GetTestInterface()
       ->mutable_nonsensitive_status_reply()
@@ -539,7 +537,7 @@
 
 TEST_P(DeviceKeysAccessTpmChallengeKeySubtleTest,
        AttestationPreparedDbusFailed) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->ConfigureEnrollmentPreparationsStatus(::attestation::STATUS_DBUS_ERROR);
 
@@ -550,7 +548,7 @@
 
 TEST_P(DeviceKeysAccessTpmChallengeKeySubtleTest,
        AttestationPreparedServiceInternalError) {
-  chromeos::AttestationClient::Get()
+  AttestationClient::Get()
       ->GetTestInterface()
       ->ConfigureEnrollmentPreparationsStatus(
           ::attestation::STATUS_NOT_AVAILABLE);
diff --git a/chrome/browser/ash/borealis/borealis_features.cc b/chrome/browser/ash/borealis/borealis_features.cc
index 3b2a62e..bef4048 100644
--- a/chrome/browser/ash/borealis/borealis_features.cc
+++ b/chrome/browser/ash/borealis/borealis_features.cc
@@ -35,7 +35,7 @@
 
 namespace {
 
-constexpr uint64_t kGibi = 1024ull * 1024 * 1024;
+constexpr int64_t kGibi = 1024 * 1024 * 1024;
 
 // Used to make it difficult to tell what someone's token is based on their
 // prefs.
diff --git a/chrome/browser/ash/borealis/borealis_features_unittest.cc b/chrome/browser/ash/borealis/borealis_features_unittest.cc
index 98c05e76..28b2c75 100644
--- a/chrome/browser/ash/borealis/borealis_features_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_features_unittest.cc
@@ -135,11 +135,11 @@
   EXPECT_TRUE(checker.CpuRegexMatches("cp"));
   EXPECT_TRUE(checker.CpuRegexMatches("^[a-z]*$"));
 
-  EXPECT_TRUE(checker.HasMemory(0));
+  EXPECT_TRUE(checker.HasMemory(-1));
   EXPECT_TRUE(checker.HasMemory(41));
   EXPECT_TRUE(checker.HasMemory(42));
   EXPECT_FALSE(checker.HasMemory(43));
-  EXPECT_FALSE(checker.HasMemory(std::numeric_limits<uint64_t>::max()));
+  EXPECT_FALSE(checker.HasMemory(std::numeric_limits<int64_t>::max()));
 }
 
 TEST(BorealisFeaturesUtilTest, DataCanBeBuilt) {
@@ -160,7 +160,7 @@
         // Faking CPU and RAM are not supported, so just assert they have some
         // trivial values.
         EXPECT_NE(data.cpu, "");
-        EXPECT_GT(data.memory, 0u);
+        EXPECT_GT(data.memory, 0);
         loop.Quit();
       }));
   loop.Run();
diff --git a/chrome/browser/ash/borealis/borealis_features_util.cc b/chrome/browser/ash/borealis/borealis_features_util.cc
index 2e9b9cc9..6ae51eec 100644
--- a/chrome/browser/ash/borealis/borealis_features_util.cc
+++ b/chrome/browser/ash/borealis/borealis_features_util.cc
@@ -91,7 +91,7 @@
                                  std::string board,
                                  std::string model,
                                  std::string cpu,
-                                 uint64_t memory)
+                                 int64_t memory)
     : token_hash(std::move(token_hash)),
       board(std::move(board)),
       model(std::move(model)),
@@ -176,7 +176,7 @@
   return RE2::PartialMatch(token_hardware_.cpu, cpu_regex);
 }
 
-bool TokenHardwareChecker::HasMemory(uint64_t mem_bytes) const {
+bool TokenHardwareChecker::HasMemory(int64_t mem_bytes) const {
   return token_hardware_.memory >= mem_bytes;
 }
 
diff --git a/chrome/browser/ash/borealis/borealis_features_util.h b/chrome/browser/ash/borealis/borealis_features_util.h
index d0311b8f..1bd73fb 100644
--- a/chrome/browser/ash/borealis/borealis_features_util.h
+++ b/chrome/browser/ash/borealis/borealis_features_util.h
@@ -23,7 +23,7 @@
          std::string board,
          std::string model,
          std::string cpu,
-         uint64_t memory);
+         int64_t memory);
     Data(const Data& other);
     ~Data();
 
@@ -31,7 +31,7 @@
     std::string board;
     std::string model;
     std::string cpu;
-    uint64_t memory;
+    int64_t memory;
   };
 
   // A hashing function used for creating tokens.
@@ -53,7 +53,7 @@
   bool IsModel(const std::string& model) const;
   bool ModelIn(base::flat_set<std::string> models) const;
   bool CpuRegexMatches(const std::string& cpu_regex) const;
-  bool HasMemory(uint64_t mem_bytes) const;
+  bool HasMemory(int64_t mem_bytes) const;
 
  private:
   const Data token_hardware_;
diff --git a/chrome/browser/ash/bruschetta/bruschetta_launcher.cc b/chrome/browser/ash/bruschetta/bruschetta_launcher.cc
index 34b6d79..b508a334 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_launcher.cc
+++ b/chrome/browser/ash/bruschetta/bruschetta_launcher.cc
@@ -9,6 +9,7 @@
 #include "base/files/file_path.h"
 #include "base/strings/strcat.h"
 #include "base/task/thread_pool.h"
+#include "base/time/time.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
 #include "chrome/browser/ash/guest_os/guest_os_session_tracker.h"
 #include "chrome/browser/ash/guest_os/public/types.h"
@@ -51,6 +52,12 @@
   callbacks_.AddUnsafe(std::move(callback));
   if (!launch_in_progress) {
     EnsureDlcInstalled();
+    // If we're not complete after 4 minutes time out the entire launch.
+    base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&BruschettaLauncher::OnTimeout,
+                       weak_factory_.GetWeakPtr()),
+        base::Seconds(240));
   }
 }
 
@@ -136,18 +143,26 @@
   }
 
   auto* tracker = guest_os::GuestOsSessionTracker::GetForProfile(profile_);
-  tracker->RunOnceContainerStarted(
+  subscription_ = tracker->RunOnceContainerStarted(
       guest_os::GuestId{guest_os::VmType::BRUSCHETTA, vm_name_, "penguin"},
       base::BindOnce(&BruschettaLauncher::OnContainerRunning,
                      weak_factory_.GetWeakPtr()));
 }
 
 void BruschettaLauncher::OnContainerRunning(guest_os::GuestInfo info) {
-  // TODO(b/231390254): There's no way for Garcon to signal errors, we just hang
-  // forever. At the least we should have some timeouts.
   callbacks_.Notify(BruschettaResult::kSuccess);
 }
 
+void BruschettaLauncher::OnTimeout() {
+  // These are no-ops if empty so safe to always call.
+  subscription_.reset();
+  callbacks_.Notify(BruschettaResult::kTimeout);
+
+  // We don't actually abort or cancel the launch, let it keep going in the
+  // background in case it's really slow for some reason then the next time they
+  // try it might succeed.
+}
+
 base::WeakPtr<BruschettaLauncher> BruschettaLauncher::GetWeakPtr() {
   return weak_factory_.GetWeakPtr();
 }
diff --git a/chrome/browser/ash/bruschetta/bruschetta_launcher.h b/chrome/browser/ash/bruschetta/bruschetta_launcher.h
index 8efbbd3c..14cec25b 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_launcher.h
+++ b/chrome/browser/ash/bruschetta/bruschetta_launcher.h
@@ -25,20 +25,22 @@
   kDlcInstallError,
   kBiosNotAccessible,
   kStartVmFailed,
+  kTimeout,
 };
 
 // Launches Bruschetta. One instance per VM.
 class BruschettaLauncher {
  public:
   BruschettaLauncher(std::string vm_name, Profile* profile);
-  ~BruschettaLauncher();
+  virtual ~BruschettaLauncher();
   BruschettaLauncher(const BruschettaLauncher&) = delete;
   BruschettaLauncher& operator=(const BruschettaLauncher&) = delete;
 
   // Launches the Bruschetta instance this launcher controls if it's not already
   // running. Calls `callback` once Bruschetta is running or upon failure with
   // the result of the launch. Must be called on the UI thread.
-  void EnsureRunning(base::OnceCallback<void(BruschettaResult)> callback);
+  virtual void EnsureRunning(
+      base::OnceCallback<void(BruschettaResult)> callback);
 
   // Gets a weak pointer to self.
   base::WeakPtr<BruschettaLauncher> GetWeakPtr();
@@ -55,11 +57,14 @@
 
   void OnContainerRunning(guest_os::GuestInfo info);
 
+  void OnTimeout();
+
   std::string vm_name_;
   Profile* profile_;
 
   // Callbacks to run once an in-progress launch finishes.
   base::OnceCallbackList<void(BruschettaResult)> callbacks_;
+  absl::optional<base::CallbackListSubscription> subscription_;
 
   // Must be last.
   base::WeakPtrFactory<BruschettaLauncher> weak_factory_{this};
diff --git a/chrome/browser/ash/bruschetta/bruschetta_launcher_unittest.cc b/chrome/browser/ash/bruschetta/bruschetta_launcher_unittest.cc
index e085457..37df1f0 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_launcher_unittest.cc
+++ b/chrome/browser/ash/bruschetta/bruschetta_launcher_unittest.cc
@@ -11,6 +11,8 @@
 #include "base/files/file_util.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
 #include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 #include "chrome/browser/ash/guest_os/guest_os_session_tracker.h"
 #include "chrome/browser/ash/guest_os/public/types.h"
@@ -73,7 +75,8 @@
     return base::WriteFile(bios_path_, "");
   }
 
-  content::BrowserTaskEnvironment task_environment_;
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
   base::RunLoop run_loop_;
   TestingProfile profile_;
   base::FilePath bios_path_;
@@ -169,4 +172,21 @@
   ASSERT_EQ(FakeConciergeClient()->start_vm_call_count(), num_repeats);
 }
 
+// We should timeout if launch takes too long.
+TEST_F(BruschettaLauncherTest, LaunchTimeout) {
+  vm_tools::concierge::VmStoppedSignal signal;
+  signal.set_name("vm_name");
+  FakeConciergeClient()->NotifyVmStopped(
+      signal);  // Notify stopped to clear the session tracker.
+
+  BruschettaResult last_result = BruschettaResult::kUnknown;
+  launcher_->EnsureRunning(StoreResultThenQuitRunLoop(&last_result));
+  // Run until we're idle, rather than all the way until the run loop is
+  // killed, so we can still run things next time through the loop.
+  this->task_environment_.FastForwardBy(base::Minutes(3));
+  ASSERT_EQ(last_result, BruschettaResult::kUnknown);  // No result yet.
+  this->task_environment_.FastForwardBy(base::Minutes(2));
+  ASSERT_EQ(last_result, BruschettaResult::kTimeout);  // Timed out.
+}
+
 }  // namespace bruschetta
diff --git a/chrome/browser/ash/bruschetta/bruschetta_mount_provider.cc b/chrome/browser/ash/bruschetta/bruschetta_mount_provider.cc
new file mode 100644
index 0000000..6f87efd1
--- /dev/null
+++ b/chrome/browser/ash/bruschetta/bruschetta_mount_provider.cc
@@ -0,0 +1,77 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/bruschetta/bruschetta_mount_provider.h"
+
+#include "base/logging.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_launcher.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_service.h"
+#include "chrome/browser/ash/guest_os/guest_os_session_tracker.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+
+namespace bruschetta {
+
+BruschettaMountProvider::BruschettaMountProvider(Profile* profile,
+                                                 guest_os::GuestId guest_id)
+    : profile_(profile), guest_id_(guest_id) {}
+BruschettaMountProvider::~BruschettaMountProvider() = default;
+
+// guest_os::GuestOsMountProvider overrides.
+Profile* BruschettaMountProvider::profile() {
+  return profile_;
+}
+
+std::string BruschettaMountProvider::DisplayName() {
+  return "Bruschetta";
+}
+
+guest_os::GuestId BruschettaMountProvider::GuestId() {
+  return guest_id_;
+}
+
+guest_os::VmType BruschettaMountProvider::vm_type() {
+  return guest_os::VmType::BRUSCHETTA;
+}
+
+std::unique_ptr<guest_os::GuestOsFileWatcher>
+BruschettaMountProvider::CreateFileWatcher(base::FilePath mount_path,
+                                           base::FilePath relative_path) {
+  return std::make_unique<guest_os::GuestOsFileWatcher>(
+      ash::ProfileHelper::GetUserIdHashFromProfile(profile_), guest_id_,
+      std::move(mount_path), std::move(relative_path));
+}
+
+// guest_os::GuestOsMountProvider override.
+void BruschettaMountProvider::Prepare(PrepareCallback callback) {
+  auto* service = BruschettaService::GetForProfile(profile_);
+  auto launcher = service->GetLauncher(guest_id_.vm_name);
+  launcher->EnsureRunning(base::BindOnce(&BruschettaMountProvider::OnRunning,
+                                         weak_ptr_factory_.GetWeakPtr(),
+                                         std::move(callback)));
+}
+
+void BruschettaMountProvider::OnRunning(PrepareCallback callback,
+                                        BruschettaResult result) {
+  if (result != BruschettaResult::kSuccess) {
+    LOG(ERROR) << "Error launching Bruschetta: " << static_cast<int>(result);
+    std::move(callback).Run(false, 0, 0, base::FilePath());
+    return;
+  }
+
+  auto info = guest_os::GuestOsSessionTracker::GetForProfile(profile_)->GetInfo(
+      guest_id_);
+  if (!info) {
+    // Shouldn't happen unless you managed to shutdown the VM at the same
+    // instant as you booted it.
+    LOG(WARNING) << "Unrecognised/not running guest, unable to mount";
+    std::move(callback).Run(false, 0, 0, base::FilePath());
+    return;
+  }
+
+  // TODO(b/217469540): Once the sftp changes in garcon land, change the port
+  // from hardcoded 1234 to the real value.
+  std::move(callback).Run(true, info->cid, 1234, info->homedir);
+}
+
+}  // namespace bruschetta
diff --git a/chrome/browser/ash/bruschetta/bruschetta_mount_provider.h b/chrome/browser/ash/bruschetta/bruschetta_mount_provider.h
new file mode 100644
index 0000000..808daa7
--- /dev/null
+++ b/chrome/browser/ash/bruschetta/bruschetta_mount_provider.h
@@ -0,0 +1,47 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_BRUSCHETTA_BRUSCHETTA_MOUNT_PROVIDER_H_
+#define CHROME_BROWSER_ASH_BRUSCHETTA_BRUSCHETTA_MOUNT_PROVIDER_H_
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_launcher.h"
+#include "chrome/browser/ash/guest_os/public/guest_os_mount_provider.h"
+
+class Profile;
+
+namespace bruschetta {
+
+class BruschettaMountProvider : public guest_os::GuestOsMountProvider {
+ public:
+  BruschettaMountProvider(Profile* profile, guest_os::GuestId guest_id);
+  ~BruschettaMountProvider() override;
+
+  // guest_os::GuestOsMountProvider overrides.
+  Profile* profile() override;
+  std::string DisplayName() override;
+  guest_os::GuestId GuestId() override;
+  guest_os::VmType vm_type() override;
+  std::unique_ptr<guest_os::GuestOsFileWatcher> CreateFileWatcher(
+      base::FilePath mount_path,
+      base::FilePath relative_path) override;
+
+ protected:
+  // guest_os::GuestOsMountProvider override.
+  void Prepare(PrepareCallback callback) override;
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(BruschettaMountProviderTest, TestPrepare);
+  FRIEND_TEST_ALL_PREFIXES(BruschettaMountProviderTest,
+                           TestPrepareLaunchFailure);
+  void OnRunning(PrepareCallback callback, BruschettaResult result);
+  Profile* profile_;
+  guest_os::GuestId guest_id_;
+  base::WeakPtrFactory<BruschettaMountProvider> weak_ptr_factory_{this};
+};
+
+}  // namespace bruschetta
+
+#endif  // CHROME_BROWSER_ASH_BRUSCHETTA_BRUSCHETTA_MOUNT_PROVIDER_H_
diff --git a/chrome/browser/ash/bruschetta/bruschetta_mount_provider_unittest.cc b/chrome/browser/ash/bruschetta/bruschetta_mount_provider_unittest.cc
new file mode 100644
index 0000000..a6da64b0
--- /dev/null
+++ b/chrome/browser/ash/bruschetta/bruschetta_mount_provider_unittest.cc
@@ -0,0 +1,69 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/bruschetta/bruschetta_mount_provider.h"
+
+#include "base/files/file_path.h"
+#include "base/test/bind.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_launcher.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_service.h"
+#include "chrome/browser/ash/bruschetta/fake_bruschetta_launcher.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
+#include "chrome/browser/ash/guest_os/guest_os_session_tracker.h"
+#include "chrome/browser/ash/guest_os/public/types.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace bruschetta {
+
+class BruschettaMountProviderTest : public testing::Test {
+ protected:
+  BruschettaMountProviderTest() {
+    BruschettaMountProvider provider{&profile_, id_};
+
+    guest_os::GuestOsSessionTracker::GetForProfile(&profile_)
+        ->AddGuestForTesting(id_, info_);
+    std::unique_ptr<FakeBruschettaLauncher> launcher =
+        std::make_unique<FakeBruschettaLauncher>();
+    launcher_ = launcher.get();
+    BruschettaService::GetForProfile(&profile_)->SetLauncherForTesting(
+        id_.vm_name, std::move(launcher));
+  }
+
+  content::BrowserTaskEnvironment task_environment_;
+  TestingProfile profile_;
+  guest_os::GuestId id_{guest_os::VmType::BRUSCHETTA, "vm_name", ""};
+  guest_os::GuestInfo info_{id_, 32, "username", base::FilePath("/home/dir"),
+                            ""};
+  FakeBruschettaLauncher* launcher_;
+  BruschettaMountProvider provider_{&profile_, id_};
+};
+
+TEST_F(BruschettaMountProviderTest, TestPrepareLaunchFailure) {
+  launcher_->set_ensure_running_result(BruschettaResult::kStartVmFailed);
+  bool called = false;
+  provider_.Prepare(base::BindLambdaForTesting(
+      [&called](bool result, int cid, int port, base::FilePath path) {
+        EXPECT_FALSE(result);
+        called = true;
+      }));
+  EXPECT_TRUE(called);
+}
+
+TEST_F(BruschettaMountProviderTest, TestPrepare) {
+  launcher_->set_ensure_running_result(BruschettaResult::kSuccess);
+  bool called = false;
+  provider_.Prepare(base::BindLambdaForTesting(
+      [this, &called](bool result, int cid, int port, base::FilePath path) {
+        EXPECT_TRUE(result);
+        EXPECT_EQ(cid, info_.cid);
+        EXPECT_EQ(port, 1234);
+        EXPECT_EQ(path, info_.homedir);
+        called = true;
+      }));
+  EXPECT_TRUE(called);
+}
+
+}  // namespace bruschetta
diff --git a/chrome/browser/ash/bruschetta/bruschetta_service.cc b/chrome/browser/ash/bruschetta/bruschetta_service.cc
index 7b0897e..12324bb3 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_service.cc
+++ b/chrome/browser/ash/bruschetta/bruschetta_service.cc
@@ -7,7 +7,10 @@
 #include <memory>
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ash/bruschetta/bruschetta_launcher.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_mount_provider.h"
 #include "chrome/browser/ash/bruschetta/bruschetta_service_factory.h"
+#include "chrome/browser/ash/guest_os/public/guest_os_service.h"
+#include "chrome/browser/ash/guest_os/public/types.h"
 
 namespace bruschetta {
 
@@ -15,9 +18,14 @@
   // TODO(b/233289313): Once we have an installer we need to do this
   // dynamically, but in the alpha people have VMs they created via vmc called
   // "bru" so hardcode this to get them working while we work on the full
-  // installer.
+  // installer. Similarly, Bruschetta doesn't have a container but it runs a
+  // garcon that identifies itself as in a penguin container, so use that name.
+  guest_os::GuestId alpha_id{guest_os::VmType::BRUSCHETTA, "bru", "penguin"};
   launchers_.insert(
-      {"bru", std::make_unique<BruschettaLauncher>("bru", profile)});
+      {alpha_id.vm_name, std::make_unique<BruschettaLauncher>("bru", profile)});
+  guest_os::GuestOsService::GetForProfile(profile)
+      ->MountProviderRegistry()
+      ->Register(std::make_unique<BruschettaMountProvider>(profile, alpha_id));
 }
 
 BruschettaService::~BruschettaService() = default;
@@ -35,4 +43,10 @@
   return it->second->GetWeakPtr();
 }
 
+void BruschettaService::SetLauncherForTesting(
+    std::string vm_name,
+    std::unique_ptr<BruschettaLauncher> launcher) {
+  launchers_.insert({vm_name, std::move(launcher)});
+}
+
 }  // namespace bruschetta
diff --git a/chrome/browser/ash/bruschetta/bruschetta_service.h b/chrome/browser/ash/bruschetta/bruschetta_service.h
index 91081ba6..953d91d 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_service.h
+++ b/chrome/browser/ash/bruschetta/bruschetta_service.h
@@ -30,6 +30,9 @@
   // return a null pointer if the name isn't recognised.
   base::WeakPtr<BruschettaLauncher> GetLauncher(std::string vm_name);
 
+  void SetLauncherForTesting(std::string vm_name,
+                             std::unique_ptr<BruschettaLauncher> launcher);
+
  private:
   base::flat_map<std::string, std::unique_ptr<BruschettaLauncher>> launchers_;
 };
diff --git a/chrome/browser/ash/bruschetta/bruschetta_util.cc b/chrome/browser/ash/bruschetta/bruschetta_util.cc
index e923956..6e890aec 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_util.cc
+++ b/chrome/browser/ash/bruschetta/bruschetta_util.cc
@@ -8,4 +8,4 @@
 
 const char kBruschettaVmName[] = "bru";
 
-}
+}  // namespace bruschetta
diff --git a/chrome/browser/ash/bruschetta/bruschetta_util.h b/chrome/browser/ash/bruschetta/bruschetta_util.h
index ca912a6a..20d9acc2 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_util.h
+++ b/chrome/browser/ash/bruschetta/bruschetta_util.h
@@ -9,6 +9,6 @@
 
 extern const char kBruschettaVmName[];
 
-}
+}  // namespace bruschetta
 
 #endif  // CHROME_BROWSER_ASH_BRUSCHETTA_BRUSCHETTA_UTIL_H_
diff --git a/chrome/browser/ash/bruschetta/fake_bruschetta_launcher.cc b/chrome/browser/ash/bruschetta/fake_bruschetta_launcher.cc
new file mode 100644
index 0000000..4d028c7
--- /dev/null
+++ b/chrome/browser/ash/bruschetta/fake_bruschetta_launcher.cc
@@ -0,0 +1,19 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/bruschetta/fake_bruschetta_launcher.h"
+
+#include "base/callback_forward.h"
+
+namespace bruschetta {
+FakeBruschettaLauncher::FakeBruschettaLauncher()
+    : BruschettaLauncher("vm_name", nullptr) {}
+
+FakeBruschettaLauncher::~FakeBruschettaLauncher() = default;
+
+void FakeBruschettaLauncher::EnsureRunning(
+    base::OnceCallback<void(BruschettaResult)> callback) {
+  std::move(callback).Run(result_);
+}
+}  // namespace bruschetta
diff --git a/chrome/browser/ash/bruschetta/fake_bruschetta_launcher.h b/chrome/browser/ash/bruschetta/fake_bruschetta_launcher.h
new file mode 100644
index 0000000..e43714d
--- /dev/null
+++ b/chrome/browser/ash/bruschetta/fake_bruschetta_launcher.h
@@ -0,0 +1,29 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_BRUSCHETTA_FAKE_BRUSCHETTA_LAUNCHER_H_
+#define CHROME_BROWSER_ASH_BRUSCHETTA_FAKE_BRUSCHETTA_LAUNCHER_H_
+
+#include "base/callback_forward.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_launcher.h"
+
+namespace bruschetta {
+
+class FakeBruschettaLauncher : public BruschettaLauncher {
+ public:
+  FakeBruschettaLauncher();
+  ~FakeBruschettaLauncher() override;
+
+  void EnsureRunning(
+      base::OnceCallback<void(BruschettaResult)> callback) override;
+
+  void set_ensure_running_result(BruschettaResult result) { result_ = result; }
+
+ private:
+  BruschettaResult result_;
+};
+
+}  // namespace bruschetta
+
+#endif  // CHROME_BROWSER_ASH_BRUSCHETTA_FAKE_BRUSCHETTA_LAUNCHER_H_
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc
index ecf0578..21bb361 100644
--- a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc
+++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc
@@ -18,8 +18,8 @@
 #include "chrome/browser/platform_keys/platform_keys.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "components/account_id/account_id.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h
index cea240b3..e8c6e8d4 100644
--- a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h
+++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h
@@ -12,7 +12,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/platform_keys/platform_keys.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "net/cert/x509_certificate.h"
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler_unittest.cc b/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler_unittest.cc
index 0946d586..b2f223f51 100644
--- a/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler_unittest.cc
+++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_scheduler_unittest.cc
@@ -17,9 +17,9 @@
 #include "chrome/browser/ash/platform_keys/platform_keys_service.h"
 #include "chrome/browser/platform_keys/platform_keys.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/ash/components/network/network_state_test_helper.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "components/prefs/testing_pref_service.h"
 #include "content/public/test/browser_task_environment.h"
@@ -50,9 +50,7 @@
 
 void VerifyDeleteKeysByPrefixCalledOnce(CertScope cert_scope) {
   const std::vector<::attestation::DeleteKeysRequest> delete_keys_history =
-      chromeos::AttestationClient::Get()
-          ->GetTestInterface()
-          ->delete_keys_history();
+      AttestationClient::Get()->GetTestInterface()->delete_keys_history();
   // Use `ASSERT_EQ()` so the checks that follows don't crash.
   ASSERT_EQ(delete_keys_history.size(), 1U);
   EXPECT_EQ(delete_keys_history[0].username().empty(),
@@ -64,9 +62,7 @@
 
 void ExpectDeleteKeysByPrefixNeverCalled() {
   const std::vector<::attestation::DeleteKeysRequest> delete_keys_history =
-      chromeos::AttestationClient::Get()
-          ->GetTestInterface()
-          ->delete_keys_history();
+      AttestationClient::Get()->GetTestInterface()->delete_keys_history();
   EXPECT_TRUE(delete_keys_history.empty());
 }
 
@@ -143,13 +139,13 @@
   }
 
   void SetUp() override {
-    chromeos::AttestationClient::InitializeFake();
+    AttestationClient::InitializeFake();
     CertProvisioningWorkerFactory::SetFactoryForTesting(&mock_factory_);
   }
 
   void TearDown() override {
     CertProvisioningWorkerFactory::SetFactoryForTesting(nullptr);
-    chromeos::AttestationClient::Shutdown();
+    AttestationClient::Shutdown();
   }
 
   void AddOnlineWifiNetwork() {
@@ -780,9 +776,7 @@
     VerifyDeleteKeysByPrefixCalledOnce(kCertScope);
   }
 
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->ClearDeleteKeysHistory();
+  AttestationClient::Get()->GetTestInterface()->ClearDeleteKeysHistory();
 
   {
     CertProfile cert_profile(kCertProfileId, kCertProfileName,
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_worker_unittest.cc b/chrome/browser/ash/cert_provisioning/cert_provisioning_worker_unittest.cc
index a1c217ce..81e12d97 100644
--- a/chrome/browser/ash/cert_provisioning/cert_provisioning_worker_unittest.cc
+++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_worker_unittest.cc
@@ -31,7 +31,7 @@
 #include "chrome/browser/ash/platform_keys/platform_keys_service.h"
 #include "chrome/browser/ash/platform_keys/platform_keys_service_factory.h"
 #include "chrome/browser/platform_keys/platform_keys.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_service.h"
@@ -117,9 +117,7 @@
 
 void VerifyDeleteKeyCalledOnce(CertScope cert_scope) {
   const std::vector<::attestation::DeleteKeysRequest> delete_keys_history =
-      chromeos::AttestationClient::Get()
-          ->GetTestInterface()
-          ->delete_keys_history();
+      AttestationClient::Get()->GetTestInterface()->delete_keys_history();
   EXPECT_EQ(delete_keys_history.size(), 1u);
   EXPECT_EQ(delete_keys_history[0].username().empty(),
             cert_scope != CertScope::kUser);
@@ -397,7 +395,7 @@
   ~CertProvisioningWorkerTest() override = default;
 
   void SetUp() override {
-    ::chromeos::AttestationClient::InitializeFake();
+    AttestationClient::InitializeFake();
     // There should not be any calls to callback before this expect is
     // overridden.
     EXPECT_CALL(callback_observer_, Callback).Times(0);
@@ -409,7 +407,7 @@
   void TearDown() override {
     EXPECT_FALSE(
         attestation::TpmChallengeKeySubtleFactory::WillReturnTestingInstance());
-    ::chromeos::AttestationClient::Shutdown();
+    AttestationClient::Shutdown();
   }
 
  protected:
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc
index 387f618..92da74e5 100644
--- a/chrome/browser/ash/crostini/crostini_manager.cc
+++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -3992,8 +3992,8 @@
                                 ->TerminalProviderRegistry();
   for (const auto& pair : terminal_provider_ids_) {
     terminal_registry->Unregister(pair.second);
-    terminal_provider_ids_.erase(pair.first);
   }
+  terminal_provider_ids_.clear();
 }
 
 }  // namespace crostini
diff --git a/chrome/browser/ash/dbus/ash_dbus_helper.cc b/chrome/browser/ash/dbus/ash_dbus_helper.cc
index 54950af..1c33b09 100644
--- a/chrome/browser/ash/dbus/ash_dbus_helper.cc
+++ b/chrome/browser/ash/dbus/ash_dbus_helper.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_client.h"
 #include "chrome/common/chrome_paths.h"
 #include "chromeos/ash/components/dbus/anomaly_detector/anomaly_detector_client.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/ash/components/dbus/audio/cras_audio_client.h"
 #include "chromeos/ash/components/dbus/authpolicy/authpolicy_client.h"
 #include "chromeos/ash/components/dbus/biod/biod_client.h"
@@ -66,7 +67,6 @@
 #include "chromeos/dbus/arc/arc_midis_client.h"
 #include "chromeos/dbus/arc/arc_obb_mounter_client.h"
 #include "chromeos/dbus/arc/arc_sensor_service_client.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/cdm_factory_daemon/cdm_factory_daemon_client.h"
 #include "chromeos/dbus/constants/dbus_paths.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -135,7 +135,7 @@
   InitializeDBusClient<chromeos::ArcObbMounterClient>(bus);
   InitializeDBusClient<ArcQuotaClient>(bus);
   InitializeDBusClient<chromeos::ArcSensorServiceClient>(bus);
-  InitializeDBusClient<chromeos::AttestationClient>(bus);
+  InitializeDBusClient<AttestationClient>(bus);
   InitializeDBusClient<AuthPolicyClient>(bus);
   InitializeDBusClient<BiodClient>(bus);  // For device::Fingerprint.
   InitializeDBusClient<chromeos::CdmFactoryDaemonClient>(bus);
@@ -300,7 +300,7 @@
   chromeos::CdmFactoryDaemonClient::Shutdown();
   BiodClient::Shutdown();
   AuthPolicyClient::Shutdown();
-  chromeos::AttestationClient::Shutdown();
+  AttestationClient::Shutdown();
   ArcQuotaClient::Shutdown();
   chromeos::ArcObbMounterClient::Shutdown();
   chromeos::ArcMidisClient::Shutdown();
diff --git a/chrome/browser/ash/file_manager/file_tasks.cc b/chrome/browser/ash/file_manager/file_tasks.cc
index d623abe..ed34958 100644
--- a/chrome/browser/ash/file_manager/file_tasks.cc
+++ b/chrome/browser/ash/file_manager/file_tasks.cc
@@ -134,13 +134,13 @@
 }
 
 // Returns True if the `app_id` belongs to Files app either extension or SWA.
-inline bool isFilesAppId(const std::string& app_id) {
+inline bool IsFilesAppId(const std::string& app_id) {
   return app_id == kFileManagerAppId || app_id == kFileManagerSwaAppId;
 }
 
 // The SWA actionId is prefixed with chrome://file-manager/?ACTION_ID, just the
 // sub-string compatible with the extension/legacy e.g.: "view-pdf".
-std::string parseFilesAppActionId(const std::string& action_id) {
+std::string ParseFilesAppActionId(const std::string& action_id) {
   if (base::StartsWith(action_id, kChromeUIFileManagerURL)) {
     std::string result(action_id);
     base::ReplaceFirstSubstringAfterOffset(
@@ -155,28 +155,28 @@
 // Returns true if the `task` is the office handling task.
 bool IsHandleOfficeTask(const FullTaskDescriptor& task) {
   const std::string action_id =
-      parseFilesAppActionId(task.task_descriptor.action_id);
-  return isFilesAppId(task.task_descriptor.app_id) &&
+      ParseFilesAppActionId(task.task_descriptor.action_id);
+  return IsFilesAppId(task.task_descriptor.app_id) &&
          action_id == kActionIdHandleOffice;
 }
 
 // Returns true if the `task` is a Web Drive Office task.
 bool IsWebDriveOfficeTask(const FullTaskDescriptor& task) {
   const std::string action_id =
-      parseFilesAppActionId(task.task_descriptor.action_id);
+      ParseFilesAppActionId(task.task_descriptor.action_id);
   bool is_web_drive_office_action_id =
       action_id == kActionIdWebDriveOfficeWord ||
       action_id == kActionIdWebDriveOfficeExcel ||
       action_id == kActionIdWebDriveOfficePowerPoint;
-  return isFilesAppId(task.task_descriptor.app_id) &&
+  return IsFilesAppId(task.task_descriptor.app_id) &&
          is_web_drive_office_action_id;
 }
 
 // Returns true if the `task` is the "upload to Drive" workflow.
 bool IsUploadOfficeToDriveTask(const FullTaskDescriptor& task) {
   const std::string action_id =
-      parseFilesAppActionId(task.task_descriptor.action_id);
-  return isFilesAppId(task.task_descriptor.app_id) &&
+      ParseFilesAppActionId(task.task_descriptor.action_id);
+  return IsFilesAppId(task.task_descriptor.app_id) &&
          action_id == kActionIdUploadOfficeToDrive;
 }
 
@@ -193,7 +193,7 @@
 void KeepOnlyFileManagerInternalTasks(std::vector<FullTaskDescriptor>* tasks) {
   std::vector<FullTaskDescriptor> filtered;
   for (FullTaskDescriptor& task : *tasks) {
-    if (isFilesAppId(task.task_descriptor.app_id))
+    if (IsFilesAppId(task.task_descriptor.app_id))
       filtered.push_back(task);
   }
   tasks->swap(filtered);
@@ -205,9 +205,9 @@
   std::vector<FullTaskDescriptor> filtered;
   for (FullTaskDescriptor& task : *tasks) {
     const auto& action = task.task_descriptor.action_id;
-    if (!isFilesAppId(task.task_descriptor.app_id)) {
+    if (!IsFilesAppId(task.task_descriptor.app_id)) {
       filtered.push_back(task);
-    } else if (actions.find(parseFilesAppActionId(action)) == actions.end()) {
+    } else if (actions.find(ParseFilesAppActionId(action)) == actions.end()) {
       filtered.push_back(task);
     }
   }
@@ -668,7 +668,7 @@
 // is used to handle certain action IDs of the file manager.
 bool ShouldBeOpenedWithBrowser(const std::string& extension_id,
                                const std::string& action_id) {
-  return isFilesAppId(extension_id) &&
+  return IsFilesAppId(extension_id) &&
          (action_id == "view-pdf" || action_id == "view-in-browser" ||
           action_id == "open-hosted-generic" ||
           action_id == "open-hosted-gdoc" ||
@@ -900,7 +900,7 @@
   // files to be directly opened with the browser. In a multiprofile session
   // this will always open on the current desktop, regardless of which profile
   // owns the files, so return TASK_RESULT_OPENED.
-  const std::string parsed_action_id(parseFilesAppActionId(task.action_id));
+  const std::string parsed_action_id(ParseFilesAppActionId(task.action_id));
   if (ShouldBeOpenedWithBrowser(task.app_id, parsed_action_id)) {
     const bool result =
         OpenFilesWithBrowser(profile, file_urls, parsed_action_id);
@@ -912,7 +912,7 @@
   }
 
   // When the FilesSWA is enabled: Open Files SWA if the task is for Files app.
-  if (ash::features::IsFileManagerSwaEnabled() && isFilesAppId(task.app_id)) {
+  if (ash::features::IsFileManagerSwaEnabled() && IsFilesAppId(task.app_id)) {
     std::u16string title;
     const GURL destination_entry =
         file_urls.size() ? file_urls[0].ToGURL() : GURL();
@@ -1104,7 +1104,7 @@
   // Unless it's HTML which should open in the browser (crbug.com/1121396).
   for (FullTaskDescriptor& task : *tasks) {
     if (IsFallbackFileHandler(task) &&
-        parseFilesAppActionId(task.task_descriptor.action_id) !=
+        ParseFilesAppActionId(task.task_descriptor.action_id) !=
             "view-in-browser") {
       const extensions::EntryInfo entry = entries[0];
       const base::FilePath& file_path = entry.path;
diff --git a/chrome/browser/ash/guest_os/guest_os_session_tracker.cc b/chrome/browser/ash/guest_os/guest_os_session_tracker.cc
index 67254462..821c45d 100644
--- a/chrome/browser/ash/guest_os/guest_os_session_tracker.cc
+++ b/chrome/browser/ash/guest_os/guest_os_session_tracker.cc
@@ -40,6 +40,11 @@
 
 GuestOsSessionTracker::GuestOsSessionTracker(std::string owner_id)
     : owner_id_(std::move(owner_id)) {
+  if (!ash::ConciergeClient::Get() || !ash::CiceroneClient::Get()) {
+    // These're null in unit tests unless explicitly set up. If missing, don't
+    // register as an observer.
+    return;
+  }
   ash::ConciergeClient::Get()->AddVmObserver(this);
   ash::CiceroneClient::Get()->AddObserver(this);
   vm_tools::concierge::ListVmsRequest request;
@@ -50,6 +55,9 @@
 }
 
 GuestOsSessionTracker::~GuestOsSessionTracker() {
+  if (!ash::ConciergeClient::Get() || !ash::CiceroneClient::Get()) {
+    return;
+  }
   ash::ConciergeClient::Get()->RemoveVmObserver(this);
   ash::CiceroneClient::Get()->RemoveObserver(this);
 }
@@ -133,20 +141,20 @@
   guests_.erase(id);
 }
 
-void GuestOsSessionTracker::RunOnceContainerStarted(
+base::CallbackListSubscription GuestOsSessionTracker::RunOnceContainerStarted(
     GuestId id,
     base::OnceCallback<void(GuestInfo)> callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   auto iter = guests_.find(id);
   if (iter != guests_.end()) {
     std::move(callback).Run(iter->second);
-    return;
+    return base::CallbackListSubscription();
   }
   auto& cb_list = container_start_callbacks_[id];
   if (!cb_list) {
     cb_list = std::make_unique<base::OnceCallbackList<void(GuestInfo)>>();
   }
-  cb_list->AddUnsafe(std::move(callback));
+  return cb_list->Add(std::move(callback));
 }
 
 void GuestOsSessionTracker::AddGuestForTesting(const GuestId& id,
diff --git a/chrome/browser/ash/guest_os/guest_os_session_tracker.h b/chrome/browser/ash/guest_os/guest_os_session_tracker.h
index 96ee464..87761d72d 100644
--- a/chrome/browser/ash/guest_os/guest_os_session_tracker.h
+++ b/chrome/browser/ash/guest_os/guest_os_session_tracker.h
@@ -44,9 +44,15 @@
   ~GuestOsSessionTracker() override;
 
   // Runs `callback` when the OnContainerStarted signal arrives for the guest
-  // with the given `id`.
-  void RunOnceContainerStarted(GuestId id,
-                               base::OnceCallback<void(GuestInfo)> callback);
+  // with the given `id`. To cancel the callback (e.g. upon timeout) destroy the
+  // returned subscription.
+  // TODO(b/231390254): If Chrome crashes while a container is running then
+  // we'll never get another OnContainerStarted message, which means
+  // RunOnceContainerStarted hangs forever. We need to list running containers
+  // and adopt them, the same as we do for VMs.
+  base::CallbackListSubscription RunOnceContainerStarted(
+      GuestId id,
+      base::OnceCallback<void(GuestInfo)> callback);
 
   // Returns information about a running guest. Returns nullopt if the guest
   // isn't recognised e.g. it's not running.
diff --git a/chrome/browser/ash/guest_os/guest_os_session_tracker_unittest.cc b/chrome/browser/ash/guest_os/guest_os_session_tracker_unittest.cc
index e4d9a2ef..5cadbe1 100644
--- a/chrome/browser/ash/guest_os/guest_os_session_tracker_unittest.cc
+++ b/chrome/browser/ash/guest_os/guest_os_session_tracker_unittest.cc
@@ -134,7 +134,7 @@
   FakeCiceroneClient()->NotifyContainerStarted(container_started_signal_);
   GuestId id{VmType::UNKNOWN, "vm_name", "penguin"};
   bool called = false;
-  tracker_.RunOnceContainerStarted(
+  auto _ = tracker_.RunOnceContainerStarted(
       id,
       base::BindLambdaForTesting([&called](GuestInfo info) { called = true; }));
   task_environment_.RunUntilIdle();
@@ -145,7 +145,7 @@
   FakeConciergeClient()->NotifyVmStarted(vm_started_signal_);
   GuestId id{VmType::UNKNOWN, "vm_name", "penguin"};
   bool called = false;
-  tracker_.RunOnceContainerStarted(
+  auto _ = tracker_.RunOnceContainerStarted(
       id,
       base::BindLambdaForTesting([&called](GuestInfo info) { called = true; }));
   task_environment_.RunUntilIdle();
@@ -155,4 +155,20 @@
   EXPECT_TRUE(called);
 }
 
+TEST_F(GuestOsSessionTrackerTest, RunOnceContainerStartedCancel) {
+  FakeConciergeClient()->NotifyVmStarted(vm_started_signal_);
+  GuestId id{VmType::UNKNOWN, "vm_name", "penguin"};
+  bool called = false;
+  static_cast<void>(tracker_.RunOnceContainerStarted(
+      id, base::BindLambdaForTesting(
+              [&called](GuestInfo info) { called = true; })));
+  task_environment_.RunUntilIdle();
+  EXPECT_FALSE(called);
+  FakeCiceroneClient()->NotifyContainerStarted(container_started_signal_);
+  task_environment_.RunUntilIdle();
+
+  // We dropped the subscription, so it should've been cancelled straight away.
+  EXPECT_FALSE(called);
+}
+
 }  // namespace guest_os
diff --git a/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc b/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc
index a610bd7..d5c406a 100644
--- a/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc
+++ b/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc
@@ -26,9 +26,9 @@
 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
 #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/ash/components/network/network_state_handler.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
 #include "chromeos/dbus/constants/dbus_switches.h"
 #include "chromeos/dbus/shill/shill_manager_client.h"
 #include "chromeos/test/chromeos_test_utils.h"
diff --git a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
index 35468bb3..a6a919e 100644
--- a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
+++ b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
@@ -92,13 +92,11 @@
 }
 
 void AllowlistSimpleChallengeSigningKey() {
-  chromeos::AttestationClient::Get()
-      ->GetTestInterface()
-      ->AllowlistSignSimpleChallengeKey(
-          /*username=*/"",
-          attestation::GetKeyNameForProfile(
-              chromeos::attestation::PROFILE_ENTERPRISE_ENROLLMENT_CERTIFICATE,
-              ""));
+  AttestationClient::Get()->GetTestInterface()->AllowlistSignSimpleChallengeKey(
+      /*username=*/"",
+      attestation::GetKeyNameForProfile(
+          chromeos::attestation::PROFILE_ENTERPRISE_ENROLLMENT_CERTIFICATE,
+          ""));
 }
 
 class EnrollmentEmbeddedPolicyServerBase : public OobeBaseTest {
diff --git a/chrome/browser/ash/login/oobe_interactive_ui_test.cc b/chrome/browser/ash/login/oobe_interactive_ui_test.cc
index ab6c5657..ef41c0c 100644
--- a/chrome/browser/ash/login/oobe_interactive_ui_test.cc
+++ b/chrome/browser/ash/login/oobe_interactive_ui_test.cc
@@ -916,7 +916,7 @@
   ~OobeZeroTouchInteractiveUITest() override = default;
 
   void SetUpOnMainThread() override {
-    chromeos::AttestationClient::Get()
+    AttestationClient::Get()
         ->GetTestInterface()
         ->AllowlistSignSimpleChallengeKey(
             /*username=*/"", attestation::GetKeyNameForProfile(
diff --git a/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc b/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc
index 311ac9a9..aed38e66 100644
--- a/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc
+++ b/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/ash/login/test/fake_gaia_mixin.h"
 #include "chrome/browser/ash/login/users/test_users.h"
 #include "chrome/common/chrome_paths.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
 #include "net/base/url_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/ash/login/saml/saml_browsertest.cc b/chrome/browser/ash/login/saml/saml_browsertest.cc
index c4badc2..f981240 100644
--- a/chrome/browser/ash/login/saml/saml_browsertest.cc
+++ b/chrome/browser/ash/login/saml/saml_browsertest.cc
@@ -70,12 +70,12 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
 #include "chromeos/ash/components/dbus/userdataauth/fake_cryptohome_misc_client.h"
 #include "chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "chromeos/dbus/cryptohome/key.pb.h"
 #include "chromeos/dbus/cryptohome/rpc.pb.h"
diff --git a/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.cc b/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.cc
index 497541de..caac1cac 100644
--- a/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.cc
+++ b/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.cc
@@ -7,11 +7,11 @@
 namespace ash {
 
 MockWrongHWIDScreen::MockWrongHWIDScreen(
-    WrongHWIDScreenView* view,
+    base::WeakPtr<WrongHWIDScreenView> view,
     const base::RepeatingClosure& exit_callback)
-    : WrongHWIDScreen(view, exit_callback) {}
+    : WrongHWIDScreen(std::move(view), exit_callback) {}
 
-MockWrongHWIDScreen::~MockWrongHWIDScreen() {}
+MockWrongHWIDScreen::~MockWrongHWIDScreen() = default;
 
 void MockWrongHWIDScreen::ExitScreen() {
   WrongHWIDScreen::OnExit();
@@ -19,19 +19,6 @@
 
 MockWrongHWIDScreenView::MockWrongHWIDScreenView() = default;
 
-MockWrongHWIDScreenView::~MockWrongHWIDScreenView() {
-  if (screen_)
-    screen_->OnViewDestroyed(this);
-}
-
-void MockWrongHWIDScreenView::Bind(WrongHWIDScreen* screen) {
-  screen_ = screen;
-  MockBind(screen_);
-}
-
-void MockWrongHWIDScreenView::Unbind() {
-  screen_ = nullptr;
-  MockUnbind();
-}
+MockWrongHWIDScreenView::~MockWrongHWIDScreenView() = default;
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.h b/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.h
index 5102b4e..071107f 100644
--- a/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.h
+++ b/chrome/browser/ash/login/screens/mock_wrong_hwid_screen.h
@@ -13,7 +13,7 @@
 
 class MockWrongHWIDScreen : public WrongHWIDScreen {
  public:
-  MockWrongHWIDScreen(WrongHWIDScreenView* view,
+  MockWrongHWIDScreen(base::WeakPtr<WrongHWIDScreenView> view,
                       const base::RepeatingClosure& exit_callback);
   ~MockWrongHWIDScreen() override;
 
@@ -28,16 +28,8 @@
   MockWrongHWIDScreenView();
   ~MockWrongHWIDScreenView() override;
 
-  void Bind(WrongHWIDScreen* screen) override;
-  void Unbind() override;
-
   MOCK_METHOD(void, Show, ());
   MOCK_METHOD(void, Hide, ());
-  MOCK_METHOD(void, MockBind, (WrongHWIDScreen*));
-  MOCK_METHOD(void, MockUnbind, ());
-
- private:
-  WrongHWIDScreen* screen_ = nullptr;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/wrong_hwid_screen.cc b/chrome/browser/ash/login/screens/wrong_hwid_screen.cc
index 6bb83106..f2bdec6 100644
--- a/chrome/browser/ash/login/screens/wrong_hwid_screen.cc
+++ b/chrome/browser/ash/login/screens/wrong_hwid_screen.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ash/login/screens/wrong_hwid_screen.h"
-
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/ash/login/wizard_controller.h"
 #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h"
 
@@ -14,21 +14,16 @@
 
 }  // namespace
 
-WrongHWIDScreen::WrongHWIDScreen(WrongHWIDScreenView* view,
+WrongHWIDScreen::WrongHWIDScreen(base::WeakPtr<WrongHWIDScreenView> view,
                                  const base::RepeatingClosure& exit_callback)
     : BaseScreen(WrongHWIDScreenView::kScreenId,
                  OobeScreenPriority::SCREEN_HARDWARE_ERROR),
-      view_(view),
+      view_(std::move(view)),
       exit_callback_(exit_callback) {
   DCHECK(view_);
-  if (view_)
-    view_->Bind(this);
 }
 
-WrongHWIDScreen::~WrongHWIDScreen() {
-  if (view_)
-    view_->Unbind();
-}
+WrongHWIDScreen::~WrongHWIDScreen() = default;
 
 void WrongHWIDScreen::OnExit() {
   if (is_hidden())
@@ -36,27 +31,21 @@
   exit_callback_.Run();
 }
 
-void WrongHWIDScreen::OnViewDestroyed(WrongHWIDScreenView* view) {
-  if (view_ == view)
-    view_ = nullptr;
-}
-
 void WrongHWIDScreen::ShowImpl() {
   if (view_)
     view_->Show();
 }
 
-void WrongHWIDScreen::HideImpl() {
-  if (view_)
-    view_->Hide();
-}
+void WrongHWIDScreen::HideImpl() {}
 
-void WrongHWIDScreen::OnUserActionDeprecated(const std::string& action_id) {
+void WrongHWIDScreen::OnUserAction(const base::Value::List& args) {
+  const std::string& action_id = args[0].GetString();
+
   if (action_id == kUserActionSkip) {
     OnExit();
-  } else {
-    BaseScreen::OnUserActionDeprecated(action_id);
+    return;
   }
+  BaseScreen::OnUserAction(args);
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/wrong_hwid_screen.h b/chrome/browser/ash/login/screens/wrong_hwid_screen.h
index c65e98f..595df67 100644
--- a/chrome/browser/ash/login/screens/wrong_hwid_screen.h
+++ b/chrome/browser/ash/login/screens/wrong_hwid_screen.h
@@ -5,9 +5,8 @@
 #ifndef CHROME_BROWSER_ASH_LOGIN_SCREENS_WRONG_HWID_SCREEN_H_
 #define CHROME_BROWSER_ASH_LOGIN_SCREENS_WRONG_HWID_SCREEN_H_
 
-#include <string>
-
 #include "base/callback.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
 // TODO(https://crbug.com/1164001): move to forward declaration.
 #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h"
@@ -18,7 +17,7 @@
 // malformed HWID to users.
 class WrongHWIDScreen : public BaseScreen {
  public:
-  WrongHWIDScreen(WrongHWIDScreenView* view,
+  WrongHWIDScreen(base::WeakPtr<WrongHWIDScreenView> view,
                   const base::RepeatingClosure& exit_callback);
 
   WrongHWIDScreen(const WrongHWIDScreen&) = delete;
@@ -26,10 +25,6 @@
 
   ~WrongHWIDScreen() override;
 
-  // This method is called, when view is being destroyed. Note, if Delegate
-  // is destroyed earlier then it has to call SetDelegate(NULL).
-  void OnViewDestroyed(WrongHWIDScreenView* view);
-
   void OnExit();
 
   void set_exit_callback_for_testing(
@@ -45,9 +40,9 @@
   // BaseScreen implementation:
   void ShowImpl() override;
   void HideImpl() override;
-  void OnUserActionDeprecated(const std::string& action_id) override;
+  void OnUserAction(const base::Value::List& args) override;
 
-  WrongHWIDScreenView* view_;
+  base::WeakPtr<WrongHWIDScreenView> view_;
   base::RepeatingClosure exit_callback_;
 };
 
diff --git a/chrome/browser/ash/login/session/user_session_initializer.cc b/chrome/browser/ash/login/session/user_session_initializer.cc
index b0ee90806..4a4e48c 100644
--- a/chrome/browser/ash/login/session/user_session_initializer.cc
+++ b/chrome/browser/ash/login/session/user_session_initializer.cc
@@ -7,7 +7,9 @@
 #include "ash/components/audio/cras_audio_handler.h"
 #include "ash/components/peripheral_notification/peripheral_notification_manager.h"
 #include "ash/components/tpm/install_attributes.h"
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
+#include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/system/sys_info.h"
@@ -16,6 +18,7 @@
 #include "base/task/thread_pool.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "chrome/browser/ash/arc/session/arc_service_launcher.h"
+#include "chrome/browser/ash/bruschetta/bruschetta_service.h"
 #include "chrome/browser/ash/camera_mic/vm_camera_mic_manager.h"
 #include "chrome/browser/ash/child_accounts/child_status_reporting_service_factory.h"
 #include "chrome/browser/ash/child_accounts/child_user_service_factory.h"
@@ -231,6 +234,10 @@
       crostini::CrostiniManager::GetForProfile(profile);
   if (crostini_manager)
     crostini_manager->MaybeUpdateCrostini();
+  if (base::FeatureList::IsEnabled(features::kBruschetta)) {
+    // Ensure the Bruschetta Service is running.
+    bruschetta::BruschettaService::GetForProfile(profile);
+  }
 
   clipboard_image_model_factory_impl_ =
       std::make_unique<ClipboardImageModelFactoryImpl>(profile);
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc
index 946ac52..ea7d1ce 100644
--- a/chrome/browser/ash/login/wizard_controller.cc
+++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -645,7 +645,7 @@
       base::BindRepeating(&WizardController::OnAppDownloadingScreenExit,
                           weak_factory_.GetWeakPtr())));
   append(std::make_unique<WrongHWIDScreen>(
-      oobe_ui->GetView<WrongHWIDScreenHandler>(),
+      oobe_ui->GetView<WrongHWIDScreenHandler>()->AsWeakPtr(),
       base::BindRepeating(&WizardController::OnWrongHWIDScreenExit,
                           weak_factory_.GetWeakPtr())));
   append(std::make_unique<LacrosDataMigrationScreen>(
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc
index 931c30d1..46e1795 100644
--- a/chrome/browser/ash/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -596,10 +596,10 @@
                 base::Unretained(wizard_controller))));
 
     mock_wrong_hwid_screen_view_ = std::make_unique<MockWrongHWIDScreenView>();
-    ExpectBindUnbind(mock_wrong_hwid_screen_view_.get());
+
     mock_wrong_hwid_screen_ =
         MockScreenExpectLifecycle(std::make_unique<MockWrongHWIDScreen>(
-            mock_wrong_hwid_screen_view_.get(),
+            mock_wrong_hwid_screen_view_.get()->AsWeakPtr(),
             base::BindRepeating(&WizardController::OnWrongHWIDScreenExit,
                                 base::Unretained(wizard_controller))));
 
@@ -1738,7 +1738,8 @@
   fake_statistics_provider_.SetMachineStatistic(system::kCheckEnrollmentKey,
                                                 "0");
 
-  DoInitialEnrollment(/*check_fre=*/false);
+  // TODO(igorcov): Change to /*check_fre=*/false when b/238592446 is fixed.
+  DoInitialEnrollment(/*check_fre=*/true);
 }
 
 // Tests that a server error occurs during the Initial Enrollment check.  The
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.cc b/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.cc
index 5824a1f..87d0a5e 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.cc
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.cc
@@ -265,9 +265,10 @@
       // Fall to the initial state determination check.
       break;
     case FRERequirement::kExplicitlyNotRequired:
-      // Skip FRE check and initial determination check if the device is
-      // explicitly marked as consumer owned.
-      return CheckType::kNone;
+      // Force initial determination check even if explicitly not required.
+      // TODO(igorcov): b/238592446 Return CheckType::kNone when that gets
+      // fixed.
+      break;
     case FRERequirement::kExplicitlyRequired:
       LOG(WARNING) << "Proceeding with FRE check.";
       return CheckType::kForcedReEnrollmentExplicitlyRequired;
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc b/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc
index 2625da39..1ca9c53ca 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc
@@ -361,10 +361,10 @@
             AutoEnrollmentTypeChecker::FRERequirement::kExplicitlyNotRequired);
   EXPECT_EQ(AutoEnrollmentTypeChecker::DetermineAutoEnrollmentCheckType(
                 /*is_system_clock_synchronized=*/true),
-            AutoEnrollmentTypeChecker::CheckType::kNone);
+            AutoEnrollmentTypeChecker::CheckType::kInitialStateDetermination);
   EXPECT_EQ(AutoEnrollmentTypeChecker::DetermineAutoEnrollmentCheckType(
                 /*is_system_clock_synchronized=*/false),
-            AutoEnrollmentTypeChecker::CheckType::kNone);
+            AutoEnrollmentTypeChecker::CheckType::kInitialStateDetermination);
 }
 
 TEST_F(AutoEnrollmentTypeCheckerTest,
diff --git a/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.cc b/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.cc
index cd62aa1..7f66e2e 100644
--- a/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.cc
+++ b/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.cc
@@ -9,9 +9,9 @@
 
 #include "ash/components/attestation/attestation_flow_utils.h"
 #include "base/bind.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/attestation/attestation.pb.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 
@@ -30,7 +30,7 @@
   request.set_key_label(
       ash::attestation::GetKeyNameForProfile(cert_profile, ""));
   request.set_challenge(data);
-  chromeos::AttestationClient::Get()->SignSimpleChallenge(
+  ash::AttestationClient::Get()->SignSimpleChallenge(
       request, base::BindOnce(&TpmEnrollmentKeySigningService::OnDataSigned,
                               weak_ptr_factory_.GetWeakPtr(), data,
                               std::move(callback)));
diff --git a/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.h b/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.h
index 0377b49f..f8d436f 100644
--- a/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.h
+++ b/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/memory/weak_ptr.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "components/policy/core/common/cloud/signing_service.h"
 
 namespace policy {
diff --git a/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service_unittest.cc b/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service_unittest.cc
index 6d8e7e62..60937f7 100644
--- a/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service_unittest.cc
+++ b/chrome/browser/ash/policy/enrollment/tpm_enrollment_key_signing_service_unittest.cc
@@ -12,8 +12,8 @@
 #include "base/callback_forward.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/attestation/attestation.pb.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -28,10 +28,10 @@
 class TpmEnrollmentKeySigningServiceTest : public testing::Test {
  public:
   TpmEnrollmentKeySigningServiceTest() {
-    chromeos::AttestationClient::InitializeFake();
+    ash::AttestationClient::InitializeFake();
   }
   ~TpmEnrollmentKeySigningServiceTest() override {
-    chromeos::AttestationClient::Shutdown();
+    ash::AttestationClient::Shutdown();
   }
 
   static void SaveChallengeResponseAndRunCallback(
@@ -50,7 +50,7 @@
 };
 
 TEST_F(TpmEnrollmentKeySigningServiceTest, SigningSuccess) {
-  chromeos::AttestationClient::Get()
+  ash::AttestationClient::Get()
       ->GetTestInterface()
       ->AllowlistSignSimpleChallengeKey(
           /*username=*/"",
@@ -72,7 +72,7 @@
   ::attestation::SignedData result_challenge_response;
   result_challenge_response.set_data(returned_signed_data.data());
   result_challenge_response.set_signature(returned_signed_data.signature());
-  EXPECT_TRUE(chromeos::AttestationClient::Get()
+  EXPECT_TRUE(ash::AttestationClient::Get()
                   ->GetTestInterface()
                   ->VerifySimpleChallengeResponse(kFakeChallenge,
                                                   result_challenge_response));
diff --git a/chrome/browser/ash/policy/server_backed_state/active_directory_device_state_uploader_unittest.cc b/chrome/browser/ash/policy/server_backed_state/active_directory_device_state_uploader_unittest.cc
index f5ed52b..76d3027 100644
--- a/chrome/browser/ash/policy/server_backed_state/active_directory_device_state_uploader_unittest.cc
+++ b/chrome/browser/ash/policy/server_backed_state/active_directory_device_state_uploader_unittest.cc
@@ -19,8 +19,8 @@
 #include "chrome/browser/ash/settings/device_settings_test_helper.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
 #include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "components/policy/core/common/cloud/cloud_policy_client.h"
 #include "components/policy/core/common/cloud/mock_device_management_service.h"
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.cc b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
index 41e56b8..34b06b6 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
@@ -67,13 +67,13 @@
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h"
 #include "chromeos/ash/components/network/device_state.h"
 #include "chromeos/ash/components/network/network_handler.h"
 #include "chromeos/ash/components/network/network_state.h"
 #include "chromeos/ash/components/network/network_state_handler.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/cryptohome/rpc.pb.h"
 #include "chromeos/dbus/hermes/hermes_euicc_client.h"
 #include "chromeos/dbus/hermes/hermes_manager_client.h"
@@ -440,7 +440,7 @@
   chromeos::TpmManagerClient::Get()->GetTpmNonsensitiveStatus(
       ::tpm_manager::GetTpmNonsensitiveStatusRequest(),
       base::BindOnce(&TpmStatusCombiner::OnGetTpmStatus, tpm_status_combiner));
-  chromeos::AttestationClient::Get()->GetStatus(
+  ash::AttestationClient::Get()->GetStatus(
       ::attestation::GetStatusRequest(),
       base::BindOnce(&TpmStatusCombiner::OnGetEnrollmentStatus,
                      tpm_status_combiner));
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.h b/chrome/browser/ash/policy/status_collector/device_status_collector.h
index 02487e3..fcadffd 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.h
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.h
@@ -373,7 +373,7 @@
   struct MemoryUsage {
     // Amount of free RAM (measures raw memory used by processes, not internal
     // memory waiting to be reclaimed by GC).
-    uint64_t bytes_of_ram_free;
+    int64_t bytes_of_ram_free;
 
     // Sampling timestamp.
     base::Time timestamp;
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
index 2f5c3f12..e68bebb 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
@@ -65,6 +65,7 @@
 #include "chrome/test/base/chrome_unit_test_suite.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/ash/components/dbus/cicerone/cicerone_client.h"
 #include "chromeos/ash/components/dbus/concierge/concierge_client.h"
 #include "chromeos/ash/components/dbus/seneschal/seneschal_client.h"
@@ -78,7 +79,6 @@
 #include "chromeos/ash/services/cros_healthd/public/cpp/fake_cros_healthd.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/cros_disks/cros_disks_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_manager/idle.pb.h"
@@ -892,7 +892,7 @@
     chromeos::CrasAudioHandler::InitializeForTesting();
     ash::UserDataAuthClient::InitializeFake();
     chromeos::PowerManagerClient::InitializeFake();
-    chromeos::AttestationClient::InitializeFake();
+    ash::AttestationClient::InitializeFake();
     chromeos::TpmManagerClient::InitializeFake();
     chromeos::LoginState::Initialize();
     ash::cros_healthd::FakeCrosHealthd::Initialize();
@@ -914,7 +914,7 @@
     ash::CiceroneClient::Shutdown();
     chromeos::LoginState::Shutdown();
     chromeos::TpmManagerClient::Shutdown();
-    chromeos::AttestationClient::Shutdown();
+    ash::AttestationClient::Shutdown();
     chromeos::PowerManagerClient::Shutdown();
     ash::UserDataAuthClient::Shutdown();
     chromeos::CrasAudioHandler::Shutdown();
@@ -2362,9 +2362,8 @@
   tpm_status_reply->set_is_enabled(true);
   tpm_status_reply->set_is_owned(true);
   tpm_status_reply->set_is_owner_password_present(false);
-  auto* enrollment_status_reply = chromeos::AttestationClient::Get()
-                                      ->GetTestInterface()
-                                      ->mutable_status_reply();
+  auto* enrollment_status_reply =
+      ash::AttestationClient::Get()->GetTestInterface()->mutable_status_reply();
   enrollment_status_reply->set_prepared_for_enrollment(true);
   enrollment_status_reply->set_enrolled(false);
   auto* da_info_reply = chromeos::TpmManagerClient::Get()
@@ -2435,9 +2434,8 @@
   auto* tpm_status_reply = chromeos::TpmManagerClient::Get()
                                ->GetTestInterface()
                                ->mutable_nonsensitive_status_reply();
-  auto* enrollment_status_reply = chromeos::AttestationClient::Get()
-                                      ->GetTestInterface()
-                                      ->mutable_status_reply();
+  auto* enrollment_status_reply =
+      ash::AttestationClient::Get()->GetTestInterface()->mutable_status_reply();
   auto* da_info_reply = chromeos::TpmManagerClient::Get()
                             ->GetTestInterface()
                             ->mutable_dictionary_attack_info_reply();
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
index 2c2862b..995bf27a 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
@@ -66,6 +66,7 @@
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h"
 #include "chromeos/ash/components/network/device_state.h"
 #include "chromeos/ash/components/network/network_handler.h"
@@ -73,7 +74,6 @@
 #include "chromeos/ash/components/network/network_state_handler.h"
 #include "chromeos/ash/services/cros_healthd/public/cpp/service_connection.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/cryptohome/rpc.pb.h"
 #include "chromeos/dbus/power_manager/idle.pb.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager.pb.h"
@@ -437,7 +437,7 @@
   chromeos::TpmManagerClient::Get()->GetTpmNonsensitiveStatus(
       ::tpm_manager::GetTpmNonsensitiveStatusRequest(),
       base::BindOnce(&TpmStatusCombiner::OnGetTpmStatus, tpm_status_combiner));
-  chromeos::AttestationClient::Get()->GetStatus(
+  ash::AttestationClient::Get()->GetStatus(
       ::attestation::GetStatusRequest(),
       base::BindOnce(&TpmStatusCombiner::OnGetEnrollmentStatus,
                      tpm_status_combiner));
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.h b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.h
index d5d21d1..47e09b8 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.h
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.h
@@ -342,7 +342,7 @@
 
     // Amount of free RAM (measures raw memory used by processes, not internal
     // memory waiting to be reclaimed by GC).
-    uint64_t bytes_of_ram_free;
+    int64_t bytes_of_ram_free;
 
     // Sampling timestamp.
     base::Time timestamp;
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
index f136a0c..6d4789e 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
@@ -63,6 +63,7 @@
 #include "chrome/test/base/chrome_unit_test_suite.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/ash/components/dbus/cicerone/cicerone_client.h"
 #include "chromeos/ash/components/dbus/concierge/concierge_client.h"
 #include "chromeos/ash/components/dbus/seneschal/seneschal_client.h"
@@ -75,7 +76,6 @@
 #include "chromeos/ash/components/network/network_state_handler.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/cros_disks/cros_disks_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_manager/idle.pb.h"
@@ -883,7 +883,7 @@
     chromeos::CrasAudioHandler::InitializeForTesting();
     ash::UserDataAuthClient::InitializeFake();
     chromeos::PowerManagerClient::InitializeFake();
-    chromeos::AttestationClient::InitializeFake();
+    ash::AttestationClient::InitializeFake();
     chromeos::TpmManagerClient::InitializeFake();
     chromeos::LoginState::Initialize();
 
@@ -905,7 +905,7 @@
     ash::CiceroneClient::Shutdown();
     chromeos::LoginState::Shutdown();
     chromeos::TpmManagerClient::Shutdown();
-    chromeos::AttestationClient::Shutdown();
+    ash::AttestationClient::Shutdown();
     chromeos::PowerManagerClient::Shutdown();
     ash::UserDataAuthClient::Shutdown();
     chromeos::CrasAudioHandler::Shutdown();
@@ -2386,9 +2386,8 @@
   tpm_status_reply->set_is_enabled(true);
   tpm_status_reply->set_is_owned(true);
   tpm_status_reply->set_is_owner_password_present(false);
-  auto* enrollment_status_reply = chromeos::AttestationClient::Get()
-                                      ->GetTestInterface()
-                                      ->mutable_status_reply();
+  auto* enrollment_status_reply =
+      ash::AttestationClient::Get()->GetTestInterface()->mutable_status_reply();
   enrollment_status_reply->set_prepared_for_enrollment(true);
   enrollment_status_reply->set_enrolled(false);
   auto* da_info_reply = chromeos::TpmManagerClient::Get()
@@ -2456,9 +2455,8 @@
   auto* tpm_status_reply = chromeos::TpmManagerClient::Get()
                                ->GetTestInterface()
                                ->mutable_nonsensitive_status_reply();
-  auto* enrollment_status_reply = chromeos::AttestationClient::Get()
-                                      ->GetTestInterface()
-                                      ->mutable_status_reply();
+  auto* enrollment_status_reply =
+      ash::AttestationClient::Get()->GetTestInterface()->mutable_status_reply();
   auto* da_info_reply = chromeos::TpmManagerClient::Get()
                             ->GetTestInterface()
                             ->mutable_dictionary_attack_info_reply();
diff --git a/chrome/browser/ash/policy/status_collector/tpm_status_combiner.h b/chrome/browser/ash/policy/status_collector/tpm_status_combiner.h
index 9819f7a8..25011306 100644
--- a/chrome/browser/ash/policy/status_collector/tpm_status_combiner.h
+++ b/chrome/browser/ash/policy/status_collector/tpm_status_combiner.h
@@ -8,7 +8,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 #include "chrome/browser/ash/policy/status_collector/device_status_collector.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager.pb.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 
diff --git a/chrome/browser/ash/printing/oauth2/authorization_zones_manager.cc b/chrome/browser/ash/printing/oauth2/authorization_zones_manager.cc
index 1affbde..0895a20 100644
--- a/chrome/browser/ash/printing/oauth2/authorization_zones_manager.cc
+++ b/chrome/browser/ash/printing/oauth2/authorization_zones_manager.cc
@@ -6,13 +6,19 @@
 
 #include <map>
 #include <memory>
+#include <set>
 #include <string>
 
 #include "base/check.h"
 #include "base/containers/contains.h"
+#include "base/notreached.h"
 #include "chrome/browser/ash/printing/oauth2/authorization_zone.h"
+#include "chrome/browser/ash/printing/oauth2/profile_auth_servers_sync_bridge.h"
 #include "chrome/browser/ash/printing/oauth2/status_code.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/model_type_store_service_factory.h"
+#include "chromeos/printing/uri.h"
+#include "components/sync/model/model_type_store_service.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "url/gurl.h"
 
@@ -20,10 +26,16 @@
 
 namespace {
 
-class AuthorizationZonesManagerImpl : public AuthorizationZonesManager {
+class AuthorizationZonesManagerImpl
+    : public AuthorizationZonesManager,
+      private ProfileAuthServersSyncBridge::Observer {
  public:
   explicit AuthorizationZonesManagerImpl(Profile* profile)
-      : url_loader_factory_(profile->GetURLLoaderFactory()) {}
+      : sync_bridge_(ProfileAuthServersSyncBridge::Create(
+            this,
+            ModelTypeStoreServiceFactory::GetForProfile(profile)
+                ->GetStoreFactory())),
+        url_loader_factory_(profile->GetURLLoaderFactory()) {}
 
   StatusCode SaveAuthorizationServerAsTrusted(
       const GURL& auth_server) override {
@@ -116,6 +128,23 @@
     return it_server->second.get();
   }
 
+  syncer::ModelTypeSyncBridge* GetModelTypeSyncBridge() override {
+    return sync_bridge_.get();
+  }
+
+  void OnProfileAuthorizationServersInitialized() override {
+    // TODO(pawliczek)
+    NOTIMPLEMENTED();
+  }
+
+  void OnProfileAuthorizationServersUpdate(
+      std::set<chromeos::Uri> removed,
+      std::set<chromeos::Uri> added) override {
+    // TODO(pawliczek)
+    NOTIMPLEMENTED();
+  }
+
+  std::unique_ptr<ProfileAuthServersSyncBridge> sync_bridge_;
   std::map<GURL, std::unique_ptr<AuthorizationZone>> servers_;
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
 };
diff --git a/chrome/browser/ash/printing/oauth2/authorization_zones_manager.h b/chrome/browser/ash/printing/oauth2/authorization_zones_manager.h
index 76fe5d9d..6a99305e 100644
--- a/chrome/browser/ash/printing/oauth2/authorization_zones_manager.h
+++ b/chrome/browser/ash/printing/oauth2/authorization_zones_manager.h
@@ -10,6 +10,7 @@
 
 #include "chrome/browser/ash/printing/oauth2/status_code.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "components/sync/model/model_type_sync_bridge.h"
 
 class GURL;
 class Profile;
@@ -66,6 +67,7 @@
   // `profile` must not be nullptr.
   static std::unique_ptr<AuthorizationZonesManager> Create(Profile* profile);
   ~AuthorizationZonesManager() override;
+  virtual syncer::ModelTypeSyncBridge* GetModelTypeSyncBridge() = 0;
 
   // Marks `auth_server` as trusted.
   virtual StatusCode SaveAuthorizationServerAsTrusted(
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
index 90a1576e..37d2a9a 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
@@ -194,7 +194,7 @@
     ash::WallpaperController::Get()->SetCustomWallpaper(
         user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(),
         /*file_name=*/"fakename", ash::WALLPAPER_LAYOUT_CENTER_CROPPED, image,
-        /*preview_mode=*/true);
+        /*preview_mode=*/true, /*file_path=*/"");
 
     loop.Run();
   }
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.cc
index 23e694f..de20f95 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.cc
@@ -44,7 +44,8 @@
  public:
   PersonalizationAppManagerImpl(
       content::BrowserContext* context,
-      local_search_service::LocalSearchServiceProxy& local_search_service_proxy)
+      ::chromeos::local_search_service::LocalSearchServiceProxy&
+          local_search_service_proxy)
       : context_(context) {
     if (ash::features::IsPersonalizationHubEnabled()) {
       // Only create the search handler if personalization hub feature is
@@ -110,7 +111,8 @@
 // static
 std::unique_ptr<PersonalizationAppManager> PersonalizationAppManager::Create(
     content::BrowserContext* context,
-    local_search_service::LocalSearchServiceProxy& local_search_service_proxy) {
+    ::chromeos::local_search_service::LocalSearchServiceProxy&
+        local_search_service_proxy) {
   return std::make_unique<PersonalizationAppManagerImpl>(
       context, local_search_service_proxy);
 }
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.h
index 8702ce7..085f01b 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.h
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.h
@@ -11,12 +11,14 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "content/public/browser/browser_context.h"
 
-namespace ash {
-
+// TODO(https://crbug.com/1164001): move forward declaration to ash.
+namespace chromeos {
 namespace local_search_service {
 class LocalSearchServiceProxy;
-}
+}  // namespace local_search_service
+}  // namespace chromeos
 
+namespace ash {
 namespace personalization_app {
 
 enum class HatsSurveyType {
@@ -35,7 +37,7 @@
  public:
   static std::unique_ptr<PersonalizationAppManager> Create(
       content::BrowserContext* context,
-      local_search_service::LocalSearchServiceProxy&
+      ::chromeos::local_search_service::LocalSearchServiceProxy&
           local_search_service_proxy);
 
   ~PersonalizationAppManager() override = default;
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager_factory.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager_factory.cc
index 4dd9a84f..3f45da9 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager_factory.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_manager_factory.cc
@@ -32,8 +32,8 @@
     : BrowserContextKeyedServiceFactory(
           "PersonalizationAppManager",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(
-      local_search_service::LocalSearchServiceProxyFactory::GetInstance());
+  DependsOn(::chromeos::local_search_service::LocalSearchServiceProxyFactory::
+                GetInstance());
 }
 
 PersonalizationAppManagerFactory::~PersonalizationAppManagerFactory() = default;
@@ -43,7 +43,7 @@
   DCHECK(context && !context->IsOffTheRecord())
       << "PersonalizationAppManager requires a real browser context";
 
-  auto* local_search_service_proxy = local_search_service::
+  auto* local_search_service_proxy = ::chromeos::local_search_service::
       LocalSearchServiceProxyFactory::GetForBrowserContext(context);
   DCHECK(local_search_service_proxy);
 
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
index 46a3296f..965bf4862 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -382,12 +382,14 @@
     case ash::WallpaperType::kCustomized: {
       base::FilePath file_name = base::FilePath(info.location).BaseName();
 
-      // Match selected wallpaper based on full filename including extension.
-      const std::string& key = file_name.value();
       // Do not show file extension in user-visible selected details text.
       std::vector<std::string> attribution = {
           file_name.RemoveExtension().value()};
 
+      // Match selected wallpaper based on full filename including extension.
+      const std::string& key =
+          info.user_file_path.empty() ? file_name.value() : info.user_file_path;
+
       NotifyWallpaperChanged(
           ash::personalization_app::mojom::CurrentWallpaper::New(
               wallpaper_data_url, std::move(attribution), info.layout,
diff --git a/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc b/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc
index 7e82ed7..428f029e 100644
--- a/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc
+++ b/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc
@@ -20,22 +20,12 @@
 #include "chrome/common/channel_info.h"
 #include "components/autofill_assistant/browser/public/autofill_assistant_factory.h"
 #include "components/autofill_assistant/browser/public/headless_script_controller.h"
+#include "components/autofill_assistant/browser/public/public_script_parameters.h"
 #include "content/public/browser/web_contents.h"
 #include "url/gurl.h"
 
-// TODO(b/234418435): Remove these values from here once exposed in
-// autofill_assistant/browser/public.
 namespace {
-constexpr char kPasswordChangeUsername[] = "PASSWORD_CHANGE_USERNAME";
-constexpr char kPasswordChangeSkipLoginParameter[] =
-    "PASSWORD_CHANGE_SKIP_LOGIN";
-constexpr char kIntentParameter[] = "INTENT";
-constexpr char kSourceParameter[] = "SOURCE";
 constexpr char kIntent[] = "PASSWORD_CHANGE";
-constexpr char kParameterStartImediately[] = "START_IMMEDIATELY";
-constexpr char kParameterOriginalDeepLink[] = "ORIGINAL_DEEPLINK";
-constexpr char kParameterEnabled[] = "ENABLED";
-constexpr char kParameterCaller[] = "CALLER";
 
 constexpr int kInChromeCaller = 7;
 constexpr int kSourcePasswordChangeLeakWarning = 10;
@@ -102,18 +92,28 @@
   side_panel_coordinator_ = CreateSidePanel();
   side_panel_coordinator_->AddObserver(this);
 
-  base::flat_map<std::string, std::string> params_map;
-  params_map[kPasswordChangeUsername] = username_;
-  params_map[kIntentParameter] = kIntent;
-  params_map[kParameterStartImediately] = "true";
-  params_map[kParameterOriginalDeepLink] = url_.spec();
-  params_map[kPasswordChangeSkipLoginParameter] =
-      skip_login_ ? "true" : "false";
-  params_map[kParameterEnabled] = "true";
-  params_map[kParameterCaller] = base::NumberToString(kInChromeCaller);
-  params_map[kSourceParameter] =
-      skip_login_ ? base::NumberToString(kSourcePasswordChangeLeakWarning)
-                  : base::NumberToString(kSourcePasswordChangeSettings);
+  base::flat_map<std::string, std::string> params_map = {
+      {autofill_assistant::public_script_parameters::
+           kPasswordChangeUsernameParameterName,
+       username_},
+      {autofill_assistant::public_script_parameters::kIntentParamenterName,
+       kIntent},
+      {autofill_assistant::public_script_parameters::
+           kStartImmediatelyParameterName,
+       "true"},
+      {autofill_assistant::public_script_parameters::
+           kOriginalDeeplinkParameterName,
+       url_.spec()},
+      {autofill_assistant::public_script_parameters::
+           kPasswordChangeSkipLoginParameterName,
+       skip_login_ ? "true" : "false"},
+      {autofill_assistant::public_script_parameters::kEnabledParameterName,
+       "true"},
+      {autofill_assistant::public_script_parameters::kCallerParameterName,
+       base::NumberToString(kInChromeCaller)},
+      {autofill_assistant::public_script_parameters::kSourceParameterName,
+       skip_login_ ? base::NumberToString(kSourcePasswordChangeLeakWarning)
+                   : base::NumberToString(kSourcePasswordChangeSettings)}};
 
   external_script_controller_ = CreateHeadlessScriptController();
   external_script_controller_->StartScript(
diff --git a/chrome/browser/background/background_application_list_model.cc b/chrome/browser/background/background_application_list_model.cc
index e413079..96c51b2 100644
--- a/chrome/browser/background/background_application_list_model.cc
+++ b/chrome/browser/background/background_application_list_model.cc
@@ -18,20 +18,17 @@
 #include "chrome/browser/background/background_contents_service_factory.h"
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "components/crx_file/id_util.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/image_loader.h"
-#include "extensions/browser/notification_types.h"
+#include "extensions/browser/permissions_manager.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_icon_set.h"
 #include "extensions/common/extension_resource.h"
@@ -158,9 +155,6 @@
 BackgroundApplicationListModel::BackgroundApplicationListModel(Profile* profile)
     : profile_(profile) {
   DCHECK(profile_);
-  registrar_.Add(this,
-                 extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-                 content::Source<Profile>(profile));
   extensions::ExtensionSystem::Get(profile_)->ready().Post(
       FROM_HERE,
       base::BindOnce(&BackgroundApplicationListModel::OnExtensionSystemReady,
@@ -300,17 +294,6 @@
   return false;
 }
 
-void BackgroundApplicationListModel::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(type, extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED);
-  OnExtensionPermissionsUpdated(
-      content::Details<UpdatedExtensionPermissionsInfo>(details)->extension,
-      content::Details<UpdatedExtensionPermissionsInfo>(details)->reason,
-      content::Details<UpdatedExtensionPermissionsInfo>(details)->permissions);
-}
-
 void BackgroundApplicationListModel::SendApplicationDataChangedNotifications() {
   for (auto& observer : observers_)
     observer.OnApplicationDataChanged();
@@ -357,6 +340,9 @@
         extensions::ProcessManager::Get(profile_));
   }
 
+  permissions_manager_observation_.Observe(
+      extensions::PermissionsManager::Get(profile_));
+
   startup_done_ = true;
 }
 
@@ -365,6 +351,7 @@
   DCHECK(extension_registry_observation_.IsObservingSource(registry));
   extension_registry_observation_.Reset();
   process_manager_observation_.Reset();
+  permissions_manager_observation_.Reset();
 }
 
 void BackgroundApplicationListModel::OnBackgroundContentsServiceChanged() {
@@ -376,20 +363,19 @@
 }
 
 void BackgroundApplicationListModel::OnExtensionPermissionsUpdated(
-    const Extension* extension,
-    UpdatedExtensionPermissionsInfo::Reason reason,
-    const PermissionSet& permissions) {
-  if (permissions.HasAPIPermission(APIPermissionID::kBackground) ||
+    const extensions::UpdatedExtensionPermissionsInfo& info) {
+  if (info.permissions.HasAPIPermission(APIPermissionID::kBackground) ||
       (base::FeatureList::IsEnabled(features::kOnConnectNative) &&
-       permissions.HasAPIPermission(APIPermissionID::kTransientBackground))) {
-    switch (reason) {
+       info.permissions.HasAPIPermission(
+           APIPermissionID::kTransientBackground))) {
+    switch (info.reason) {
       case UpdatedExtensionPermissionsInfo::ADDED:
       case UpdatedExtensionPermissionsInfo::REMOVED:
         Update();
-        if (IsBackgroundApp(*extension, profile_)) {
-          AssociateApplicationData(extension);
+        if (IsBackgroundApp(*info.extension, profile_)) {
+          AssociateApplicationData(info.extension);
         } else {
-          DissociateApplicationData(extension);
+          DissociateApplicationData(info.extension);
         }
         break;
       default:
diff --git a/chrome/browser/background/background_application_list_model.h b/chrome/browser/background/background_application_list_model.h
index d43b40a..0d725a0e 100644
--- a/chrome/browser/background/background_application_list_model.h
+++ b/chrome/browser/background/background_application_list_model.h
@@ -17,9 +17,8 @@
 #include "base/scoped_observation.h"
 #include "chrome/browser/background/background_contents_service.h"
 #include "chrome/browser/background/background_contents_service_observer.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "extensions/browser/extension_registry_observer.h"
+#include "extensions/browser/permissions_manager.h"
 #include "extensions/browser/process_manager.h"
 #include "extensions/browser/process_manager_observer.h"
 #include "extensions/common/extension.h"
@@ -32,16 +31,17 @@
 
 namespace extensions {
 class ExtensionRegistry;
-}
+struct UpdatedExtensionPermissionsInfo;
+}  // namespace extensions
 
 // Model for list of Background Applications associated with a Profile (i.e.
 // extensions with kBackgroundPermission set, or hosted apps with a
 // BackgroundContents).
 class BackgroundApplicationListModel
-    : public content::NotificationObserver,
-      public extensions::ExtensionRegistryObserver,
+    : public extensions::ExtensionRegistryObserver,
       public BackgroundContentsServiceObserver,
-      public extensions::ProcessManagerObserver {
+      public extensions::ProcessManagerObserver,
+      public extensions::PermissionsManager::Observer {
  public:
   // Observer is informed of changes to the model.  Users of the
   // BackgroundApplicationListModel should anticipate that associated data,
@@ -117,9 +117,7 @@
     return extensions_.end();
   }
 
-  size_t size() const {
-    return extensions_.size();
-  }
+  size_t size() const { return extensions_.size(); }
 
   // Returns true if all startup notifications have already been issued.
   bool startup_done() const { return startup_done_; }
@@ -144,11 +142,6 @@
   // Returns the Application associated with |extension| or NULL.
   Application* FindApplication(const extensions::Extension* extension);
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
   // extensions::ExtensionRegistryObserver:
   void OnExtensionLoaded(content::BrowserContext* browser_context,
                          const extensions::Extension* extension) override;
@@ -161,6 +154,10 @@
   void OnBackgroundContentsServiceChanged() override;
   void OnBackgroundContentsServiceDestroying() override;
 
+  // extensions::PermissionsManager::Observer:
+  void OnExtensionPermissionsUpdated(
+      const extensions::UpdatedExtensionPermissionsInfo& info) override;
+
   // Intended to be called when extension system is ready.
   void OnExtensionSystemReady();
 
@@ -168,12 +165,6 @@
   // application, e.g. the Icon, has changed.
   void SendApplicationDataChangedNotifications();
 
-  // Invoked by Observe for NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED.
-  void OnExtensionPermissionsUpdated(
-      const extensions::Extension* extension,
-      extensions::UpdatedExtensionPermissionsInfo::Reason reason,
-      const extensions::PermissionSet& permissions);
-
   // Refresh the list of background applications and generate notifications.
   void Update();
 
@@ -187,7 +178,6 @@
   extensions::ExtensionList extensions_;
   base::ObserverList<Observer, true>::Unchecked observers_;
   const raw_ptr<Profile> profile_;
-  content::NotificationRegistrar registrar_;
   bool startup_done_ = false;
 
   // Listens to extension load, unload notifications.
@@ -203,6 +193,10 @@
                           extensions::ProcessManagerObserver>
       process_manager_observation_{this};
 
+  base::ScopedObservation<extensions::PermissionsManager,
+                          extensions::PermissionsManager::Observer>
+      permissions_manager_observation_{this};
+
   base::WeakPtrFactory<BackgroundApplicationListModel> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
index 5f13adba..6796cf8 100644
--- a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
+++ b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -782,7 +782,11 @@
     @Test
     @MediumTest
     @Feature({"AppBanners"})
-    @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.INSTALLABLE_AMBIENT_BADGE_MESSAGE,
+    @CommandLineFlags.
+    Add({"enable-features=" + ChromeFeatureList.INSTALLABLE_AMBIENT_BADGE_MESSAGE + "<Study",
+            "force-fieldtrials=Study/Group",
+            "force-fieldtrial-params="
+                    + "Study.Group:installable_ambient_badge_message_throttle_domains_capacity/0",
             "disable-features=" + ChromeFeatureList.INSTALLABLE_AMBIENT_BADGE_INFOBAR})
     public void
     testBlockedAmbientBadgeDoesNotAppearAgainForMonths_Message() throws Exception {
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index 50d35d5f..b5d2fccc 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -173,8 +173,8 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/dbus/constants/attestation_constants.h"  // nogncheck
 #include "chromeos/dbus/dbus_thread_manager.h"              // nogncheck
 #include "components/user_manager/user.h"
@@ -1071,7 +1071,7 @@
             &ChromeBrowsingDataRemoverDelegate::OnClearPlatformKeys,
             weak_ptr_factory_.GetWeakPtr(),
             CreateTaskCompletionClosure(TracingDataType::kTpmAttestationKeys));
-        chromeos::AttestationClient::Get()->DeleteKeys(
+        ash::AttestationClient::Get()->DeleteKeys(
             request, base::BindOnce(
                          [](decltype(callback) cb,
                             const ::attestation::DeleteKeysReply& reply) {
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 b074d445..5aea2ff 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
@@ -177,7 +177,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ash/login/users/mock_user_manager.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
 #include "chromeos/dbus/tpm_manager/fake_tpm_manager_client.h"  // nogncheck
 #include "components/account_id/account_id.h"
 #include "components/user_manager/scoped_user_manager.h"
@@ -2078,18 +2078,16 @@
   user_manager::ScopedUserManager user_manager_enabler(
       base::WrapUnique(mock_user_manager));
 
-  chromeos::AttestationClient::InitializeFake();
+  ash::AttestationClient::InitializeFake();
   BlockUntilBrowsingDataRemoved(
       base::Time(), base::Time::Max(),
       content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES, false);
 
   const std::vector<::attestation::DeleteKeysRequest>& history =
-      chromeos::AttestationClient::Get()
-          ->GetTestInterface()
-          ->delete_keys_history();
+      ash::AttestationClient::Get()->GetTestInterface()->delete_keys_history();
   EXPECT_EQ(history.size(), 1u);
 
-  chromeos::AttestationClient::Shutdown();
+  ash::AttestationClient::Shutdown();
 }
 #endif
 
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index fa7c144..1132140 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -1049,7 +1049,7 @@
       ash::help_app::mojom::PageHandlerFactory, ash::HelpAppUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<
-      ash::local_search_service::mojom::Index, ash::HelpAppUI>(map);
+      chromeos::local_search_service::mojom::Index, ash::HelpAppUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<ash::help_app::mojom::SearchHandler,
                                          ash::HelpAppUI>(map);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index ad0c2bec..d08d66c3 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -249,6 +249,8 @@
     "//chromeos:chromeos_export",
     "//chromeos/ash/components/assistant:buildflags",
     "//chromeos/ash/components/dbus/anomaly_detector",
+    "//chromeos/ash/components/dbus/attestation",
+    "//chromeos/ash/components/dbus/attestation:attestation_proto",
     "//chromeos/ash/components/dbus/audio",
     "//chromeos/ash/components/dbus/authpolicy",
     "//chromeos/ash/components/dbus/authpolicy:authpolicy_proto",
@@ -328,8 +330,6 @@
     "//chromeos/dbus",
     "//chromeos/dbus:metrics_event_proto",
     "//chromeos/dbus:plugin_vm_service_proto",
-    "//chromeos/dbus/attestation",
-    "//chromeos/dbus/attestation:attestation_proto",
     "//chromeos/dbus/cdm_factory_daemon",
     "//chromeos/dbus/constants",
     "//chromeos/dbus/cros_disks",
@@ -2504,6 +2504,8 @@
     "../ash/borealis/testing/widgets.h",
     "../ash/bruschetta/fake_bruschetta_features.cc",
     "../ash/bruschetta/fake_bruschetta_features.h",
+    "../ash/bruschetta/fake_bruschetta_launcher.cc",
+    "../ash/bruschetta/fake_bruschetta_launcher.h",
     "../ash/cert_provisioning/mock_cert_provisioning_invalidator.cc",
     "../ash/cert_provisioning/mock_cert_provisioning_invalidator.h",
     "../ash/cert_provisioning/mock_cert_provisioning_scheduler.cc",
@@ -2705,6 +2707,7 @@
     "../ash/app_mode/app_launch_utils_unittest.cc",
     "../ash/app_mode/arc/arc_kiosk_app_service_unittest.cc",
     "../ash/app_mode/kiosk_app_launch_error_unittest.cc",
+    "../ash/app_mode/metrics/low_disk_metrics_service_unittest.cc",
     "../ash/app_mode/metrics/network_connectivity_metrics_service_unittest.cc",
     "../ash/app_mode/startup_app_launcher_unittest.cc",
     "../ash/app_mode/web_app/web_kiosk_app_launcher_unittest.cc",
@@ -2855,6 +2858,7 @@
     "../ash/borealis/infra/transition_unittest.cc",
     "../ash/browser_accelerator_configuration_unittest.cc",
     "../ash/bruschetta/bruschetta_launcher_unittest.cc",
+    "../ash/bruschetta/bruschetta_mount_provider_unittest.cc",
     "../ash/bruschetta/bruschetta_service_unittest.cc",
     "../ash/camera_mic/vm_camera_mic_manager_unittest.cc",
     "../ash/camera_presence_notifier_unittest.cc",
@@ -3631,6 +3635,8 @@
     "//chrome/test:test_support_ui",
     "//chrome/test:test_support_unit",
     "//chromeos/ash/components/dbus/anomaly_detector",
+    "//chromeos/ash/components/dbus/attestation",
+    "//chromeos/ash/components/dbus/attestation:attestation_proto",
     "//chromeos/ash/components/dbus/authpolicy",
     "//chromeos/ash/components/dbus/lorgnette_manager:lorgnette_proto",
     "//chromeos/ash/components/dbus/oobe_config",
@@ -3649,8 +3655,6 @@
     "//chromeos/components/sensors:test_support",
     "//chromeos/components/sync_wifi:test_support",
     "//chromeos/dbus:test_support",
-    "//chromeos/dbus/attestation",
-    "//chromeos/dbus/attestation:attestation_proto",
     "//chromeos/dbus/cros_disks",
     "//chromeos/dbus/cryptohome",
     "//chromeos/dbus/cryptohome:attestation_proto",
diff --git a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc
index 54435f6..f9f48cc 100644
--- a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc
+++ b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h"
 
+#include "base/metrics/histogram_functions.h"
 #include "chrome/browser/chromeos/app_mode/app_session.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_settings_navigation_throttle.h"
 #include "chrome/browser/ui/browser.h"
@@ -12,6 +13,8 @@
 
 namespace chromeos {
 
+const char kKioskNewBrowserWindowHistogram[] = "Kiosk.NewBrowserWindow";
+
 AppSessionBrowserWindowHandler::AppSessionBrowserWindowHandler(
     Profile* profile,
     Browser* browser,
@@ -36,15 +39,19 @@
       active_tab ? active_tab->GetURL().spec() : std::string();
 
   if (KioskSettingsNavigationThrottle::IsSettingsPage(url_string)) {
+    base::UmaHistogramEnumeration(kKioskNewBrowserWindowHistogram,
+                                  KioskBrowserWindowType::kSettingsPage);
     HandleNewSettingsWindow(browser, url_string);
   } else {
+    base::UmaHistogramEnumeration(kKioskNewBrowserWindowHistogram,
+                                  KioskBrowserWindowType::kOther);
     LOG(WARNING) << "Browser opened in kiosk session"
                  << ", url=" << url_string;
     browser->window()->Close();
   }
 
   on_browser_window_added_callback_.Run();
-}  // namespace chromeos
+}
 
 void AppSessionBrowserWindowHandler::HandleNewSettingsWindow(
     Browser* browser,
diff --git a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
index 9d71b9e..6f33a33 100644
--- a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
+++ b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
@@ -15,6 +15,17 @@
 
 namespace chromeos {
 
+extern const char kKioskNewBrowserWindowHistogram[];
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+// Keep in sync with respective enum in tools/metrics/histograms/enums.xml
+enum class KioskBrowserWindowType {
+  kSettingsPage = 0,
+  kOther = 1,
+  kMaxValue = kOther,
+};
+
 // This class monitors for the addition and removal of new browser windows
 // during the kiosk session. On construction it gets a main browser handle
 // stored as |browser_|.
diff --git a/chrome/browser/chromeos/app_mode/app_session_unittest.cc b/chrome/browser/chromeos/app_mode/app_session_unittest.cc
index f8c7fcc..9e9ca50 100644
--- a/chrome/browser/chromeos/app_mode/app_session_unittest.cc
+++ b/chrome/browser/chromeos/app_mode/app_session_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/app_mode/app_session.h"
+#include "chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/pref_names.h"
@@ -114,6 +115,11 @@
   histogram.ExpectTotalCount(kKioskSessionDurationNormalHistogram, 1);
   histogram.ExpectTotalCount(kKioskSessionDurationInDaysNormalHistogram, 0);
   histogram.ExpectTotalCount(kKioskSessionCountPerDayHistogram, 1);
+
+  histogram.ExpectBucketCount(kKioskNewBrowserWindowHistogram,
+                              KioskBrowserWindowType::kOther, 1);
+  histogram.ExpectBucketCount(kKioskNewBrowserWindowHistogram,
+                              KioskBrowserWindowType::kSettingsPage, 0);
 }
 
 // Check that sessions list in local_state contains only sessions within the
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/ash/ash_attestation_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/ash/ash_attestation_service_unittest.cc
index 59e0a80..5dc5b16 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/ash/ash_attestation_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/ash/ash_attestation_service_unittest.cc
@@ -20,8 +20,8 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
-#include "chromeos/dbus/attestation/attestation_ca.pb.h"
-#include "chromeos/dbus/attestation/attestation_client.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_ca.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
 #include "chromeos/dbus/constants/attestation_constants.h"
 #include "components/device_signals/core/common/signals_constants.h"
 #include "content/public/test/browser_task_environment.h"
@@ -103,7 +103,7 @@
   void SetUp() override {
     testing::Test::SetUp();
 
-    chromeos::AttestationClient::InitializeFake();
+    ash::AttestationClient::InitializeFake();
 
     mock_challenge_key_ = InjectMockChallengeKey();
     attestation_service_ =
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/common/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/attestation/common/BUILD.gn
index 13339a1..252e271 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/common/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/common/BUILD.gn
@@ -27,7 +27,8 @@
   public_deps = [ "//build:chromeos_buildflags" ]
 
   if (is_chromeos_ash) {
-    public_deps += [ "//chromeos/dbus/attestation:attestation_proto" ]
+    public_deps +=
+        [ "//chromeos/ash/components/dbus/attestation:attestation_proto" ]
   } else {
     public_deps += [ "//chrome/browser/enterprise/connectors/device_trust/attestation/common/proto:attestation_ca_proto" ]
   }
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/common/signals_type.h b/chrome/browser/enterprise/connectors/device_trust/attestation/common/signals_type.h
index 21f66ef..bf14a17 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/common/signals_type.h
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/common/signals_type.h
@@ -9,7 +9,7 @@
 #include "build/chromeos_buildflags.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "chromeos/dbus/attestation/attestation_ca.pb.h"
+#include "chromeos/ash/components/dbus/attestation/attestation_ca.pb.h"
 
 namespace enterprise_connectors {
 
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index 97734d6..cbebfe8b 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -415,9 +415,6 @@
       prefs::kExtensionsUIDeveloperMode,
       base::BindRepeating(&DeveloperPrivateEventRouter::OnProfilePrefChanged,
                           base::Unretained(this)));
-  notification_registrar_.Add(
-      this, extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::Source<Profile>(profile_.get()));
 }
 
 DeveloperPrivateEventRouter::~DeveloperPrivateEventRouter() {
@@ -570,7 +567,7 @@
     BroadcastItemStateChanged(developer::EVENT_TYPE_WARNINGS_CHANGED, id);
 }
 
-void DeveloperPrivateEventRouter::UserPermissionsSettingsChanged(
+void DeveloperPrivateEventRouter::OnUserPermissionsSettingsChanged(
     const PermissionsManager::UserPermissionsSettings& settings) {
   developer::UserSiteSettings user_site_settings =
       ConvertToUserSiteSettings(settings);
@@ -583,16 +580,10 @@
   event_router_->BroadcastEvent(std::move(event));
 }
 
-void DeveloperPrivateEventRouter::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, type);
-
-  UpdatedExtensionPermissionsInfo* info =
-      content::Details<UpdatedExtensionPermissionsInfo>(details).ptr();
+void DeveloperPrivateEventRouter::OnExtensionPermissionsUpdated(
+    const UpdatedExtensionPermissionsInfo& info) {
   BroadcastItemStateChanged(developer::EVENT_TYPE_PERMISSIONS_CHANGED,
-                            info->extension->id());
+                            info.extension->id());
 }
 
 void DeveloperPrivateEventRouter::OnProfilePrefChanged() {
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h
index 0184fb40..4e42b62 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.h
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h
@@ -23,8 +23,6 @@
 #include "chrome/common/extensions/api/developer_private.h"
 #include "chrome/common/extensions/webstore_install_result.h"
 #include "components/prefs/pref_change_registrar.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "extensions/browser/api/file_system/file_system_api.h"
 #include "extensions/browser/app_window/app_window_registry.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
@@ -72,7 +70,6 @@
                                     public ExtensionAllowlist::Observer,
                                     public ExtensionManagement::Observer,
                                     public WarningService::Observer,
-                                    public content::NotificationObserver,
                                     public PermissionsManager::Observer {
  public:
   explicit DeveloperPrivateEventRouter(Profile* profile);
@@ -142,14 +139,11 @@
   void ExtensionWarningsChanged(
       const ExtensionIdSet& affected_extensions) override;
 
-  // content::NotificationObserver:
-  void Observe(int notification_type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
   // PermissionsManager::Observer:
-  void UserPermissionsSettingsChanged(
+  void OnUserPermissionsSettingsChanged(
       const PermissionsManager::UserPermissionsSettings& settings) override;
+  void OnExtensionPermissionsUpdated(
+      const UpdatedExtensionPermissionsInfo& info) override;
 
   // Handles a profile preference change.
   void OnProfilePrefChanged();
@@ -198,8 +192,6 @@
 
   PrefChangeRegistrar pref_change_registrar_;
 
-  content::NotificationRegistrar notification_registrar_;
-
   base::WeakPtrFactory<DeveloperPrivateEventRouter> weak_factory_{this};
 };
 
@@ -210,7 +202,7 @@
   using UnpackedRetryId = std::string;
 
   static BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>*
-      GetFactoryInstance();
+  GetFactoryInstance();
 
   static std::unique_ptr<api::developer_private::ProfileInfo> CreateProfileInfo(
       Profile* profile);
@@ -641,7 +633,6 @@
 class DeveloperPrivatePackDirectoryFunction
     : public DeveloperPrivateAPIFunction,
       public PackExtensionJob::Client {
-
  public:
   DECLARE_EXTENSION_FUNCTION("developerPrivate.packDirectory",
                              DEVELOPERPRIVATE_PACKDIRECTORY)
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 8829e24..a0e85b1c 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
@@ -847,8 +847,16 @@
   content::test::FencedFrameTestHelper fenced_frame_test_helper_;
 };
 
+// TODO(crbug.com/1342975): Test is flaky on Linux TSan.
+#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
+#define MAYBE_BrowserActionPopupWithFencedFrame \
+  DISABLED_BrowserActionPopupWithFencedFrame
+#else
+#define MAYBE_BrowserActionPopupWithFencedFrame \
+  BrowserActionPopupWithFencedFrame
+#endif
 IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveFencedFrameTest,
-                       BrowserActionPopupWithFencedFrame) {
+                       MAYBE_BrowserActionPopupWithFencedFrame) {
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
   https_server.ServeFilesFromSourceDirectory("chrome/test/data");
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index 3599c6d9..92e2908 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -168,19 +168,16 @@
     return function->GetError();
   }
 
-  void WaitForTwoResults(ExtensionFunction* function,
-                         base::Value* first_result,
-                         base::Value* second_result) {
+  void WaitForOneResult(ExtensionFunction* function, base::Value* result) {
     RunMessageLoopUntilResponse();
     EXPECT_TRUE(function->GetError().empty())
         << "Unexpected error: " << function->GetError();
     EXPECT_NE(nullptr, function->GetResultList());
 
     const auto& result_list = *function->GetResultList();
-    EXPECT_EQ(2ul, result_list.size());
+    EXPECT_EQ(1ul, result_list.size());
 
-    *first_result = result_list[0].Clone();
-    *second_result = result_list[1].Clone();
+    *result = result_list[0].Clone();
   }
 
  private:
@@ -206,11 +203,8 @@
     return async_function_runner_->WaitForError(function);
   }
 
-  void WaitForTwoResults(ExtensionFunction* function,
-                         base::Value* first_result,
-                         base::Value* second_result) {
-    return async_function_runner_->WaitForTwoResults(function, first_result,
-                                                     second_result);
+  void WaitForOneResult(ExtensionFunction* function, base::Value* result) {
+    return async_function_runner_->WaitForOneResult(function, result);
   }
 
  private:
@@ -990,29 +984,19 @@
                                Browser* browser,
                                std::string* access_token,
                                std::set<std::string>* granted_scopes) {
-    EXPECT_TRUE(
-        utils::RunFunction(function, args, browser, api_test_utils::NONE));
+    std::unique_ptr<base::Value> result_value =
+        utils::RunFunctionAndReturnSingleResult(function, args, browser);
+    ASSERT_TRUE(result_value);
+    std::unique_ptr<api::identity::GetAuthTokenResult> result =
+        api::identity::GetAuthTokenResult::FromValue(*result_value);
+    ASSERT_TRUE(result);
 
-    EXPECT_TRUE(function->GetError().empty())
-        << "Unexpected error: " << function->GetError();
-    EXPECT_NE(nullptr, function->GetResultList());
-
-    const auto& result_list = *function->GetResultList();
-    EXPECT_EQ(2ul, result_list.size());
-
-    const auto& access_token_value = result_list[0];
-    const auto& granted_scopes_value = result_list[1];
-    EXPECT_TRUE(access_token_value.is_string());
-    EXPECT_TRUE(granted_scopes_value.is_list());
-
-    std::set<std::string> scopes;
-    for (const auto& scope : granted_scopes_value.GetListDeprecated()) {
-      EXPECT_TRUE(scope.is_string());
-      scopes.insert(scope.GetString());
-    }
-
-    *access_token = access_token_value.GetString();
-    *granted_scopes = std::move(scopes);
+    EXPECT_NE(nullptr, result->token);
+    *access_token = *result->token;
+    EXPECT_NE(nullptr, result->granted_scopes);
+    std::set<std::string> granted_scopes_map(result->granted_scopes->begin(),
+                                             result->granted_scopes->end());
+    *granted_scopes = std::move(granted_scopes_map);
   }
 
   void WaitForGetAuthTokenResults(
@@ -1020,25 +1004,22 @@
       std::string* access_token,
       std::set<std::string>* granted_scopes,
       AsyncFunctionRunner* function_runner = nullptr) {
-    base::Value access_token_value;
-    base::Value granted_scopes_value;
+    base::Value result_value;
     if (function_runner == nullptr) {
-      WaitForTwoResults(function, &access_token_value, &granted_scopes_value);
+      WaitForOneResult(function, &result_value);
     } else {
-      function_runner->WaitForTwoResults(function, &access_token_value,
-                                         &granted_scopes_value);
+      function_runner->WaitForOneResult(function, &result_value);
     }
-    EXPECT_TRUE(access_token_value.is_string());
-    EXPECT_TRUE(granted_scopes_value.is_list());
+    std::unique_ptr<api::identity::GetAuthTokenResult> result =
+        api::identity::GetAuthTokenResult::FromValue(result_value);
+    ASSERT_TRUE(result);
 
-    std::set<std::string> scopes;
-    for (const auto& scope : granted_scopes_value.GetListDeprecated()) {
-      EXPECT_TRUE(scope.is_string());
-      scopes.insert(scope.GetString());
-    }
-
-    *access_token = access_token_value.GetString();
-    *granted_scopes = std::move(scopes);
+    ASSERT_NE(nullptr, result->token);
+    *access_token = *result->token;
+    ASSERT_NE(nullptr, result->granted_scopes);
+    std::set<std::string> granted_scopes_map(result->granted_scopes->begin(),
+                                             result->granted_scopes->end());
+    *granted_scopes = std::move(granted_scopes_map);
   }
 
  private:
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index 24c2561d..b377740b4 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -325,12 +325,13 @@
     const std::set<std::string>& granted_scopes) {
   RecordFunctionResult(IdentityGetAuthTokenError(), remote_consent_approved_);
 
-  base::Value::List granted_scopes_value;
-  for (const auto& scope : granted_scopes)
-    granted_scopes_value.Append(scope);
+  api::identity::GetAuthTokenResult result;
+  result.token = std::make_unique<std::string>(access_token);
+  result.granted_scopes = std::make_unique<std::vector<std::string>>(
+      granted_scopes.begin(), granted_scopes.end());
 
-  CompleteAsyncRun(TwoArguments(base::Value(access_token),
-                                base::Value(std::move(granted_scopes_value))));
+  CompleteAsyncRun(
+      OneArgument(base::Value::FromUniquePtrValue(result.ToValue())));
 }
 
 void IdentityGetAuthTokenFunction::CompleteFunctionWithError(
diff --git a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
index 7ec5063..0b382fbf 100644
--- a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
+++ b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
@@ -912,13 +912,13 @@
     PermissionsManagerWaiter waiter(permissions_manager);
     permissions_manager->AddUserRestrictedSite(
         url::Origin::Create(policy_allowed_resource));
-    waiter.WaitForPermissionsChange();
+    waiter.WaitForUserPermissionsSettingsChange();
   }
   {
     PermissionsManagerWaiter waiter(permissions_manager);
     permissions_manager->AddUserPermittedSite(
         url::Origin::Create(policy_restricted_resource));
-    waiter.WaitForPermissionsChange();
+    waiter.WaitForUserPermissionsSettingsChange();
   }
 
   {
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
index 45d1f8f..b49ea6a 100644
--- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc
+++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -38,14 +38,12 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/crx_file/id_util.h"
 #include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/test_renderer_host.h"
 #include "content/public/test/web_contents_tester.h"
 #include "extensions/browser/extension_dialog_auto_confirm.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
-#include "extensions/browser/notification_types.h"
 #include "extensions/browser/permissions_manager.h"
 #include "extensions/browser/test_extension_registry_observer.h"
 #include "extensions/browser/test_management_policy.h"
@@ -319,9 +317,7 @@
     ManifestLocation location,
     const std::string& host_permission) {
   DictionaryBuilder manifest;
-  manifest.Set("name", name)
-      .Set("version", "1")
-      .Set("manifest_version", 2);
+  manifest.Set("name", name).Set("version", "1").Set("manifest_version", 2);
   if (action_key)
     manifest.Set(action_key, DictionaryBuilder().Build());
   if (!host_permission.empty())
@@ -912,7 +908,7 @@
     auto* manager = extensions::PermissionsManager::Get(profile());
     extensions::PermissionsManagerWaiter manager_waiter(manager);
     manager->AddUserPermittedSite(url::Origin::Create(url));
-    manager_waiter.WaitForPermissionsChange();
+    manager_waiter.WaitForUserPermissionsSettingsChange();
 
     // Verify "grant all extensions" item is visible and disabled, and the
     // "learn more" item is in the context menu.
@@ -935,7 +931,7 @@
     auto* manager = extensions::PermissionsManager::Get(profile());
     extensions::PermissionsManagerWaiter manager_waiter(manager);
     manager->AddUserRestrictedSite(url::Origin::Create(url));
-    manager_waiter.WaitForPermissionsChange();
+    manager_waiter.WaitForUserPermissionsSettingsChange();
 
     // Verify "block all extensions" item is visible and disabled, and the
     // "learn more" item is in the context menu.
@@ -1095,11 +1091,10 @@
   // Change extension to run "on click". Since we are revoking permissions, we
   // need to automatically accept the reload page bubble.
   action_runner->accept_bubble_for_testing(true);
-  content::WindowedNotificationObserver permissions_observer(
-      extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::NotificationService::AllSources());
+  extensions::PermissionsManagerWaiter waiter(
+      extensions::PermissionsManager::Get(profile()));
   menu.ExecuteCommand(kOnClick, 0);
-  permissions_observer.Wait();
+  waiter.WaitForExtensionPermissionsUpdate();
   EXPECT_TRUE(menu.IsCommandIdChecked(kOnClick));
   EXPECT_FALSE(menu.IsCommandIdChecked(kOnSite));
   EXPECT_FALSE(menu.IsCommandIdChecked(kOnAllSites));
@@ -1497,11 +1492,10 @@
   // need to automatically accept the reload page bubble.
   ExtensionActionRunner::GetForWebContents(web_contents)
       ->accept_bubble_for_testing(true);
-  content::WindowedNotificationObserver permissions_observer(
-      extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::NotificationService::AllSources());
+  extensions::PermissionsManagerWaiter waiter(
+      extensions::PermissionsManager::Get(profile()));
   menu.ExecuteCommand(kOnClick, 0);
-  permissions_observer.Wait();
+  waiter.WaitForExtensionPermissionsUpdate();
   EXPECT_TRUE(menu.IsCommandIdChecked(kOnClick));
   EXPECT_FALSE(menu.IsCommandIdChecked(kOnSite));
   EXPECT_FALSE(menu.IsCommandIdChecked(kOnAllSites));
@@ -1631,11 +1625,10 @@
     menu.ExecuteCommand(kOnClick, 0);
     ExtensionActionRunner::GetForWebContents(web_contents)
         ->accept_bubble_for_testing(true);
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     menu.ExecuteCommand(kOnClick, 0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
   }
 
   {
@@ -1688,11 +1681,10 @@
   // page bubble.
   ExtensionActionRunner::GetForWebContents(web_contents)
       ->accept_bubble_for_testing(true);
-  content::WindowedNotificationObserver permissions_observer(
-      extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::NotificationService::AllSources());
+  extensions::PermissionsManagerWaiter waiter(
+      extensions::PermissionsManager::Get(profile()));
   menu.ExecuteCommand(kOnClick, 0);
-  permissions_observer.Wait();
+  waiter.WaitForExtensionPermissionsUpdate();
 
   // This, sadly, removes access for the extension on b.com as well. :( This
   // is because we revoke all host permissions when transitioning from "don't
diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc
index 5cfe0d8..0889834 100644
--- a/chrome/browser/extensions/permissions_updater.cc
+++ b/chrome/browser/extensions/permissions_updater.cc
@@ -25,9 +25,6 @@
 #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
 #include "content/public/browser/browser_context.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/url_constants.h"
 #include "extensions/browser/event_router.h"
@@ -36,7 +33,6 @@
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_util.h"
 #include "extensions/browser/network_permissions_updater.h"
-#include "extensions/browser/notification_types.h"
 #include "extensions/browser/permissions_manager.h"
 #include "extensions/browser/renderer_startup_helper.h"
 #include "extensions/common/cors_util.h"
@@ -160,8 +156,8 @@
   NetworkPermissionsUpdateHelper* helper = new NetworkPermissionsUpdateHelper(
       browser_context,
       base::BindOnce(&PermissionsUpdater::NotifyPermissionsUpdated,
-                     browser_context, event_type, extension,
-                     changed.Clone(), std::move(completion_callback)));
+                     browser_context, event_type, extension, changed.Clone(),
+                     std::move(completion_callback)));
 
   // After an asynchronous call below, the helper will call
   // NotifyPermissionsUpdated if the profile is still valid.
@@ -301,8 +297,6 @@
     const PermissionSet& permissions,
     RemoveType remove_type,
     base::OnceClosure completion_callback) {
-  // TODO(devlin): Ideally, we'd have this CHECK in place, but unit tests are
-  // currently violating it.
   CHECK(PermissionsParser::GetOptionalPermissions(&extension)
             .Contains(permissions))
       << "Cannot remove optional permissions that are not "
@@ -572,7 +566,8 @@
     scoped_refptr<const Extension> extension,
     std::unique_ptr<const PermissionSet> changed,
     base::OnceClosure completion_callback) {
-  if (changed->IsEmpty() && event_type != POLICY) {
+  if ((changed->IsEmpty() && event_type != POLICY) ||
+      browser_context->ShutdownStarted()) {
     std::move(completion_callback).Run();
     return;
   }
@@ -598,10 +593,8 @@
   // Notify other APIs or interested parties.
   UpdatedExtensionPermissionsInfo info =
       UpdatedExtensionPermissionsInfo(extension.get(), *changed, reason);
-  content::NotificationService::current()->Notify(
-      NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::Source<Profile>(profile),
-      content::Details<UpdatedExtensionPermissionsInfo>(&info));
+  PermissionsManager::Get(browser_context)
+      ->NotifyExtensionPermissionsUpdated(info);
 
   // Send the new permissions to the renderers.
   for (RenderProcessHost::iterator host_iterator(
diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc
index c3a3fff9..427216e8 100644
--- a/chrome/browser/extensions/permissions_updater_unittest.cc
+++ b/chrome/browser/extensions/permissions_updater_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/files/file_path.h"
 #include "base/json/json_file_value_serializer.h"
@@ -14,7 +15,6 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_service_test_base.h"
 #include "chrome/browser/extensions/extension_util.h"
@@ -24,17 +24,16 @@
 #include "chrome/common/extensions/extension_test_util.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/crx_file/id_util.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_service.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_util.h"
+#include "extensions/browser/permissions_manager.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_features.h"
 #include "extensions/common/permissions/permission_set.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/common/value_builder.h"
+#include "extensions/test/permissions_manager_waiter.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using extension_test_util::LoadManifest;
@@ -63,65 +62,7 @@
       .Build();
 }
 
-// A helper class that listens for NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED.
-class PermissionsUpdaterListener : public content::NotificationObserver {
- public:
-  PermissionsUpdaterListener()
-      : received_notification_(false), waiting_(false) {
-    registrar_.Add(this,
-                   extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-                   content::NotificationService::AllSources());
-  }
-
-  void Reset() {
-    received_notification_ = false;
-    waiting_ = false;
-    extension_.reset();
-    permissions_ = NULL;
-  }
-
-  void Wait() {
-    if (received_notification_)
-      return;
-
-    waiting_ = true;
-    base::RunLoop run_loop;
-    run_loop.Run();
-  }
-
-  bool received_notification() const { return received_notification_; }
-  const Extension* extension() const { return extension_.get(); }
-  const PermissionSet* permissions() const { return permissions_.get(); }
-  UpdatedExtensionPermissionsInfo::Reason reason() const { return reason_; }
-
- private:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override {
-    received_notification_ = true;
-    UpdatedExtensionPermissionsInfo* info =
-        content::Details<UpdatedExtensionPermissionsInfo>(details).ptr();
-
-    extension_ = info->extension.get();
-    permissions_ = info->permissions.Clone();
-    reason_ = info->reason;
-
-    if (waiting_) {
-      waiting_ = false;
-      base::RunLoop::QuitCurrentWhenIdleDeprecated();
-    }
-  }
-
-  bool received_notification_;
-  bool waiting_;
-  content::NotificationRegistrar registrar_;
-  scoped_refptr<const Extension> extension_;
-  std::unique_ptr<const PermissionSet> permissions_;
-  UpdatedExtensionPermissionsInfo::Reason reason_;
-};
-
-class PermissionsUpdaterTest : public ExtensionServiceTestBase {
-};
+class PermissionsUpdaterTest : public ExtensionServiceTestBase {};
 
 void AddPattern(URLPatternSet* extent, const std::string& pattern) {
   int schemes = URLPattern::SCHEME_ALL;
@@ -199,17 +140,17 @@
     PermissionSet delta(apis.Clone(), ManifestPermissionSet(), hosts.Clone(),
                         URLPatternSet());
 
-    PermissionsUpdaterListener listener;
+    PermissionsManagerWaiter waiter(PermissionsManager::Get(profile_.get()));
     PermissionsUpdater(profile_.get())
         .GrantOptionalPermissions(*extension, delta, base::DoNothing());
-
-    listener.Wait();
-
-    // Verify that the permission notification was sent correctly.
-    ASSERT_TRUE(listener.received_notification());
-    ASSERT_EQ(extension.get(), listener.extension());
-    ASSERT_EQ(UpdatedExtensionPermissionsInfo::ADDED, listener.reason());
-    ASSERT_EQ(delta, *listener.permissions());
+    waiter.WaitForExtensionPermissionsUpdate(base::BindOnce(
+        [](scoped_refptr<const Extension> extension, PermissionSet* delta,
+           const UpdatedExtensionPermissionsInfo& info) {
+          ASSERT_EQ(extension.get(), info.extension);
+          ASSERT_EQ(UpdatedExtensionPermissionsInfo::ADDED, info.reason);
+          ASSERT_EQ(*delta, info.permissions);
+        },
+        extension, &delta));
 
     // Make sure the extension's active permissions reflect the change.
     active_permissions = PermissionSet::CreateUnion(default_permissions, delta);
@@ -233,18 +174,19 @@
     PermissionSet delta(apis.Clone(), ManifestPermissionSet(), hosts.Clone(),
                         URLPatternSet());
 
-    PermissionsUpdaterListener listener;
+    PermissionsManagerWaiter waiter(PermissionsManager::Get(profile_.get()));
     PermissionsUpdater(profile_.get())
         .RevokeOptionalPermissions(*extension, delta,
                                    PermissionsUpdater::REMOVE_SOFT,
                                    base::DoNothing());
-    listener.Wait();
-
-    // Verify that the notification was correct.
-    ASSERT_TRUE(listener.received_notification());
-    ASSERT_EQ(extension.get(), listener.extension());
-    ASSERT_EQ(UpdatedExtensionPermissionsInfo::REMOVED, listener.reason());
-    ASSERT_EQ(delta, *listener.permissions());
+    waiter.WaitForExtensionPermissionsUpdate(base::BindOnce(
+        [](scoped_refptr<const Extension> extension, PermissionSet* delta,
+           const UpdatedExtensionPermissionsInfo& info) {
+          ASSERT_EQ(extension.get(), info.extension);
+          ASSERT_EQ(UpdatedExtensionPermissionsInfo::REMOVED, info.reason);
+          ASSERT_EQ(*delta, info.permissions);
+        },
+        extension, &delta));
 
     // Make sure the extension's active permissions reflect the change.
     active_permissions =
diff --git a/chrome/browser/extensions/user_host_restrictions_browsertest.cc b/chrome/browser/extensions/user_host_restrictions_browsertest.cc
index b6e7310..42c8d1e 100644
--- a/chrome/browser/extensions/user_host_restrictions_browsertest.cc
+++ b/chrome/browser/extensions/user_host_restrictions_browsertest.cc
@@ -12,7 +12,6 @@
 #include "components/sessions/content/session_tab_helper.h"
 #include "content/public/test/browser_test.h"
 #include "extensions/browser/background_script_executor.h"
-#include "extensions/browser/notification_types.h"
 #include "extensions/browser/permissions_manager.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension_features.h"
@@ -61,19 +60,11 @@
   void WithholdExtensionPermissions(const Extension& extension) {
     // Withhold extension host permissions. Wait for the notification to be
     // fired to ensure all renderers and services have been properly updated.
-    auto is_update_for_extension =
-        [&extension](const content::NotificationSource& source,
-                     const content::NotificationDetails& details) {
-          UpdatedExtensionPermissionsInfo* info =
-              content::Details<UpdatedExtensionPermissionsInfo>(details).ptr();
-          return info->extension->id() == extension.id();
-        };
-    content::WindowedNotificationObserver permissions_observer(
-        NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        base::BindLambdaForTesting(is_update_for_extension));
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     ScriptingPermissionsModifier(profile(), &extension)
         .SetWithholdHostPermissions(true);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
   }
 
   // Adds `url` as a new user-permitted site and waits for the change to take
@@ -83,8 +74,8 @@
         PermissionsManager::Get(profile());
     PermissionsManagerWaiter waiter(permissions_manager);
     permissions_manager->AddUserPermittedSite(url::Origin::Create(url));
-    waiter.WaitForPermissionsChange();
-  };
+    waiter.WaitForUserPermissionsSettingsChange();
+  }
 
  private:
   base::test::ScopedFeatureList feature_list_;
@@ -274,7 +265,7 @@
     PermissionsManagerWaiter waiter(permissions_manager);
     permissions_manager->AddUserRestrictedSite(
         url::Origin::Create(restricted_url));
-    waiter.WaitForPermissionsChange();
+    waiter.WaitForUserPermissionsSettingsChange();
   }
 
   EXPECT_EQ("fetch1 - cat\n", try_fetch_url(allowed_url));
@@ -389,7 +380,7 @@
     PermissionsManagerWaiter waiter(permissions_manager);
     permissions_manager->RemoveUserPermittedSite(
         url::Origin::Create(allowed_url));
-    waiter.WaitForPermissionsChange();
+    waiter.WaitForUserPermissionsSettingsChange();
   }
 
   EXPECT_EQ(PermissionsData::PageAccess::kWithheld,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 10f3f48..7d08f86 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1830,12 +1830,6 @@
     "credential mode disallows. Without this flag enabled, Chrome will always "
     "try sending client certificates regardless of the credential mode.";
 
-const char kOmniboxActiveSearchEnginesName[] =
-    "Active Search Engines section on settings page";
-const char kOmniboxActiveSearchEnginesDescription[] =
-    "Enables a 'Your Search Engines' section on "
-    "chrome://settings/searchEngines.";
-
 const char kOmniboxAdaptiveSuggestionsCountName[] =
     "Adaptive Omnibox Suggestions count";
 const char kOmniboxAdaptiveSuggestionsCountDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index b4221bd..85a3401 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1038,9 +1038,6 @@
 extern const char kOmitCorsClientCertName[];
 extern const char kOmitCorsClientCertDescription[];
 
-extern const char kOmniboxActiveSearchEnginesName[];
-extern const char kOmniboxActiveSearchEnginesDescription[];
-
 extern const char kOmniboxAdaptiveSuggestionsCountName[];
 extern const char kOmniboxAdaptiveSuggestionsCountDescription[];
 
diff --git a/chrome/browser/lacros/browser_service_lacros_browsertest.cc b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
index c28faaa..a1c15a23 100644
--- a/chrome/browser/lacros/browser_service_lacros_browsertest.cc
+++ b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
@@ -324,15 +324,6 @@
     }
     DisableWelcomePages({profile});
 
-    // Lacros only supports syncing profiles for now.
-    // TODO(crbug.com/1260291): Revisit this once non-syncing profiles are
-    // allowed.
-    ProfileAttributesStorage* attributes_storage =
-        &profile_manager->GetProfileAttributesStorage();
-    attributes_storage->GetProfileAttributesWithPath(profile->GetPath())
-        ->SetAuthInfo("gaia_id", u"email",
-                      /*is_consented_primary_account=*/true);
-
     // Don't delete Profile too early.
     ScopedProfileKeepAlive profile_keep_alive(
         profile, ProfileKeepAliveOrigin::kBrowserWindow);
@@ -418,18 +409,6 @@
   }
   DisableWelcomePages({profile1, profile2});
 
-  // Lacros only supports syncing profiles for now.
-  // TODO(crbug.com/1260291): Revisit this once non-syncing profiles are
-  // allowed.
-  ProfileAttributesStorage* attributes_storage =
-      &profile_manager->GetProfileAttributesStorage();
-  attributes_storage->GetProfileAttributesWithPath(profile1->GetPath())
-      ->SetAuthInfo("gaia_id_1", u"email_1",
-                    /*is_consented_primary_account=*/true);
-  attributes_storage->GetProfileAttributesWithPath(profile2->GetPath())
-      ->SetAuthInfo("gaia_id_2", u"email_2",
-                    /*is_consented_primary_account=*/true);
-
   // Don't delete Profiles too early.
   ScopedProfileKeepAlive profile1_keep_alive(
       profile1, ProfileKeepAliveOrigin::kBrowserWindow);
diff --git a/chrome/browser/lacros/lacros_extension_apps_controller_lacros_browsertest.cc b/chrome/browser/lacros/lacros_extension_apps_controller_lacros_browsertest.cc
index c5d88ae..7c2700f 100644
--- a/chrome/browser/lacros/lacros_extension_apps_controller_lacros_browsertest.cc
+++ b/chrome/browser/lacros/lacros_extension_apps_controller_lacros_browsertest.cc
@@ -99,7 +99,7 @@
   crosapi::mojom::LaunchParamsPtr launch_params =
       crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id();
-  launch_params->launch_source = apps::mojom::LaunchSource::kFromTest;
+  launch_params->launch_source = apps::LaunchSource::kFromTest;
   controller->Launch(std::move(launch_params), base::DoNothing());
 
   // Wait for item to exist in shelf.
@@ -134,7 +134,7 @@
   crosapi::mojom::LaunchParamsPtr launch_params =
       crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id();
-  launch_params->launch_source = apps::mojom::LaunchSource::kFromTest;
+  launch_params->launch_source = apps::LaunchSource::kFromTest;
   controller->Launch(std::move(launch_params), base::DoNothing());
 
   // Wait for item to exist in shelf.
@@ -216,7 +216,7 @@
   crosapi::mojom::LaunchParamsPtr launch_params =
       crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id();
-  launch_params->launch_source = apps::mojom::LaunchSource::kFromTest;
+  launch_params->launch_source = apps::LaunchSource::kFromTest;
   controller->Launch(std::move(launch_params), base::DoNothing());
 
   // Wait for item to exist in shelf.
@@ -266,7 +266,7 @@
   crosapi::mojom::LaunchParamsPtr launch_params =
       crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id();
-  launch_params->launch_source = apps::mojom::LaunchSource::kFromTest;
+  launch_params->launch_source = apps::LaunchSource::kFromTest;
   controller->Launch(std::move(launch_params), base::DoNothing());
 
   // Wait for item to exist in shelf.
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc
index 3e657486..3ca1f94 100644
--- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc
+++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc
@@ -47,6 +47,12 @@
 
 void ChromeWebAuthnCredentialsDelegate::SelectWebAuthnCredential(
     std::string backend_id) {
+  // `backend_id` is the base64-encoded credential ID. See
+  // `OnCredentialsReceived()` for where these are encoded.
+  absl::optional<std::vector<uint8_t>> selected_credential_id =
+      base::Base64Decode(backend_id);
+  DCHECK(selected_credential_id);
+
 #if BUILDFLAG(IS_ANDROID)
   auto* credentials_delegate =
       ConditionalUiDelegateAndroid::GetConditionalUiDelegate(
@@ -55,10 +61,7 @@
     std::move(retrieve_suggestions_callback_).Run();
     return;
   }
-  absl::optional<std::vector<uint8_t>> selected_credential =
-      base::Base64Decode(backend_id);
-  DCHECK(selected_credential);
-  credentials_delegate->OnWebAuthnAccountSelected(*selected_credential);
+  credentials_delegate->OnWebAuthnAccountSelected(*selected_credential_id);
 #else
   ChromeAuthenticatorRequestDelegate* authenticator_delegate =
       AuthenticatorRequestScheduler::GetRequestDelegate(
@@ -67,7 +70,7 @@
     return;
   }
   authenticator_delegate->dialog_model()->OnAccountPreselected(
-      std::vector<uint8_t>(backend_id.begin(), backend_id.end()));
+      *selected_credential_id);
 #endif  // BUILDFLAG(IS_ANDROID)
 }
 
@@ -123,15 +126,7 @@
     }
     suggestion.icon = "fingerprint";
     suggestion.frontend_id = autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL;
-#if BUILDFLAG(IS_ANDROID)
-    // Android passes the credential ID instead of the user ID, because it
-    // needs the credential ID to directly populate the allowCredentials
-    // list when one is selected.
     suggestion.payload = base::Base64Encode(credential.cred_id);
-#else
-    suggestion.payload =
-        std::string(credential.user.id.begin(), credential.user.id.end());
-#endif
     suggestions.push_back(std::move(suggestion));
   }
   suggestions_ = std::move(suggestions);
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
index 627ebb3..e2a52ef 100644
--- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
+++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
@@ -248,14 +248,12 @@
         EXPECT_EQ(credential_id, CredId2());
         run_loop.Quit();
       }));
-  // Select the credential for User2.
-  credentials_delegate_->SelectWebAuthnCredential("5678");
-  run_loop.Run();
-#else
-  // On Android, the credential ID is the suggestion backend_id, whereas on
-  // desktop it is the user ID.
+#endif
+
   credentials_delegate_->SelectWebAuthnCredential(
       base::Base64Encode(CredId2()));
+
+#if BUILDFLAG(IS_ANDROID)
   auto credential_id = GetSelectedId();
   EXPECT_EQ(credential_id, CredId2());
 #endif
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
index 63d47e3..ae21e35 100644
--- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
+++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/performance_manager/policies/background_tab_loading_policy.h"
 #include "chrome/browser/performance_manager/policies/policy_features.h"
 #include "chrome/browser/performance_manager/policies/working_set_trimmer_policy.h"
+#include "chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "components/performance_manager/embedder/graph_features.h"
 #include "components/performance_manager/embedder/performance_manager_lifetime.h"
@@ -115,7 +116,11 @@
 
   if (base::FeatureList::IsEnabled(
           performance_manager::features::
-              kUrgentDiscardingFromPerformanceManager)) {
+              kUrgentDiscardingFromPerformanceManager) ||
+      base::FeatureList::IsEnabled(
+          performance_manager::features::kHighEfficiencyModeAvailable) ||
+      base::FeatureList::IsEnabled(
+          performance_manager::features::kBatterySaverModeAvailable)) {
     graph->PassToGraph(std::make_unique<
                        performance_manager::policies::PageDiscardingHelper>());
   }
@@ -183,6 +188,16 @@
 
   g_browser_process->profile_manager()->AddObserver(this);
 
+#if !BUILDFLAG(IS_ANDROID)
+  if (base::FeatureList::IsEnabled(
+          performance_manager::features::kHighEfficiencyModeAvailable) ||
+      base::FeatureList::IsEnabled(
+          performance_manager::features::kBatterySaverModeAvailable)) {
+    profile_discard_opt_out_list_helper_ = std::make_unique<
+        performance_manager::user_tuning::ProfileDiscardOptOutListHelper>();
+  }
+#endif
+
   page_load_metrics_observer_ =
       std::make_unique<performance_manager::PageLoadMetricsObserver>();
   page_live_state_data_helper_ =
@@ -228,6 +243,7 @@
 
 #if !BUILDFLAG(IS_ANDROID)
   high_efficiency_mode_policy_helper_.reset();
+  profile_discard_opt_out_list_helper_.reset();
 #endif
 
   // Releasing `performance_manager_lifetime_` will tear down the registry and
@@ -240,6 +256,15 @@
   profile_observations_.AddObservation(profile);
   performance_manager::PerformanceManagerRegistry::GetInstance()
       ->NotifyBrowserContextAdded(profile);
+
+#if !BUILDFLAG(IS_ANDROID)
+  if (base::FeatureList::IsEnabled(
+          performance_manager::features::kHighEfficiencyModeAvailable) ||
+      base::FeatureList::IsEnabled(
+          performance_manager::features::kBatterySaverModeAvailable)) {
+    profile_discard_opt_out_list_helper_->OnProfileAdded(profile);
+  }
+#endif
 }
 
 void ChromeBrowserMainExtraPartsPerformanceManager::
@@ -252,4 +277,13 @@
   profile_observations_.RemoveObservation(profile);
   performance_manager::PerformanceManagerRegistry::GetInstance()
       ->NotifyBrowserContextRemoved(profile);
+
+#if !BUILDFLAG(IS_ANDROID)
+  if (base::FeatureList::IsEnabled(
+          performance_manager::features::kHighEfficiencyModeAvailable) ||
+      base::FeatureList::IsEnabled(
+          performance_manager::features::kBatterySaverModeAvailable)) {
+    profile_discard_opt_out_list_helper_->OnProfileWillBeRemoved(profile);
+  }
+#endif
 }
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h
index 189b15e..14f3d87 100644
--- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h
+++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h
@@ -37,6 +37,10 @@
 namespace policies {
 class HighEfficiencyModePolicyHelper;
 }
+
+namespace user_tuning {
+class ProfileDiscardOptOutListHelper;
+}
 }  // namespace performance_manager
 
 // Handles the initialization of the performance manager and a few dependent
@@ -113,6 +117,9 @@
 #if !BUILDFLAG(IS_ANDROID)
   std::unique_ptr<performance_manager::policies::HighEfficiencyModePolicyHelper>
       high_efficiency_mode_policy_helper_;
+  std::unique_ptr<
+      performance_manager::user_tuning::ProfileDiscardOptOutListHelper>
+      profile_discard_opt_out_list_helper_;
 #endif  // !BUILDFLAG(IS_ANDROID)
 };
 
diff --git a/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc b/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc
index 0ffb5cb..eb76d9b 100644
--- a/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc
+++ b/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc
@@ -486,8 +486,11 @@
 size_t BackgroundTabLoadingPolicy::GetFreePhysicalMemoryMib() const {
   if (free_memory_mb_for_testing_ != 0)
     return free_memory_mb_for_testing_;
-  constexpr uint64_t kMibibytesInBytes = 1 << 20;
-  return base::SysInfo::AmountOfAvailablePhysicalMemory() / kMibibytesInBytes;
+  constexpr int64_t kMibibytesInBytes = 1 << 20;
+  int64_t free_mem =
+      base::SysInfo::AmountOfAvailablePhysicalMemory() / kMibibytesInBytes;
+  DCHECK_GE(free_mem, 0);
+  return free_mem;
 }
 
 void BackgroundTabLoadingPolicy::ErasePageNodeToLoadData(
diff --git a/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_unittest.cc b/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_unittest.cc
index 4ee06fd..ba2157ae5 100644
--- a/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_unittest.cc
+++ b/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_unittest.cc
@@ -23,6 +23,10 @@
 
     feature_list_.InitAndEnableFeature(
         performance_manager::features::kHighEfficiencyModeAvailable);
+    // This is usually called when the profile is created. Fake it here since it
+    // doesn't happen in tests.
+    PageDiscardingHelper::GetFromGraph(graph())->SetNoDiscardPatternsForProfile(
+        static_cast<PageNode*>(page_node())->GetBrowserContextID(), {});
 
     auto policy = std::make_unique<HighEfficiencyModePolicy>();
     policy_ = policy.get();
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper.cc b/chrome/browser/performance_manager/policies/page_discarding_helper.cc
index 2853e6fe..c4dc8693 100644
--- a/chrome/browser/performance_manager/policies/page_discarding_helper.cc
+++ b/chrome/browser/performance_manager/policies/page_discarding_helper.cc
@@ -23,6 +23,8 @@
 #include "components/performance_manager/public/graph/node_data_describer_registry.h"
 #include "components/performance_manager/public/graph/page_node.h"
 #include "components/performance_manager/public/graph/process_node.h"
+#include "components/url_matcher/url_matcher.h"
+#include "components/url_matcher/url_util.h"
 #include "url/gurl.h"
 
 namespace performance_manager {
@@ -287,6 +289,20 @@
     last_change_to_non_audible_time_[page_node] = base::TimeTicks::Now();
 }
 
+void PageDiscardingHelper::SetNoDiscardPatternsForProfile(
+    const std::string& browser_context_id,
+    const std::vector<std::string>& patterns) {
+  std::unique_ptr<url_matcher::URLMatcher>& entry =
+      profiles_no_discard_patterns_[browser_context_id];
+  entry = std::make_unique<url_matcher::URLMatcher>();
+  url_matcher::util::AddAllowFilters(entry.get(), patterns);
+}
+
+void PageDiscardingHelper::ClearNoDiscardPatternsForProfile(
+    const std::string& browser_context_id) {
+  profiles_no_discard_patterns_.erase(browser_context_id);
+}
+
 void PageDiscardingHelper::SetMockDiscarderForTesting(
     std::unique_ptr<mechanism::PageDiscarder> discarder) {
   page_discarder_ = std::move(discarder);
@@ -376,6 +392,11 @@
   if (!main_frame->GetURL().is_valid() || main_frame->GetURL().is_empty())
     return CanUrgentlyDiscardResult::kProtected;
 
+  if (IsPageOptedOutOfDiscarding(page_node->GetBrowserContextID(),
+                                 main_frame->GetURL())) {
+    return CanUrgentlyDiscardResult::kProtected;
+  }
+
   const auto* live_state_data = GetPageNodeLiveStateData(page_node);
 
   // The live state data won't be available if none of these events ever
@@ -423,6 +444,25 @@
   return CanUrgentlyDiscardResult::kEligible;
 }
 
+bool PageDiscardingHelper::IsPageOptedOutOfDiscarding(
+    const std::string& browser_context_id,
+    const GURL& url) const {
+  if (!base::FeatureList::IsEnabled(features::kHighEfficiencyModeAvailable) &&
+      !base::FeatureList::IsEnabled(features::kBatterySaverModeAvailable)) {
+    // This list takes effect regardless of which mode the user is operating
+    // under, but its launch is gated on these finch experiments for launch
+    // considerations.
+    return false;
+  }
+
+  auto it = profiles_no_discard_patterns_.find(browser_context_id);
+  // TODO(crbug.com/1308741): Change the CHECK to a DCHECK in Sept 2022, after
+  // verifying that there are no crash reports.
+  CHECK(it != profiles_no_discard_patterns_.end());
+
+  return !it->second->MatchURL(url).empty();
+}
+
 base::Value PageDiscardingHelper::DescribePageNodeData(
     const PageNode* node) const {
   auto* data = DiscardAttemptMarker::Get(PageNodeImpl::FromNode(node));
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper.h b/chrome/browser/performance_manager/policies/page_discarding_helper.h
index bd0a303..eca9365 100644
--- a/chrome/browser/performance_manager/policies/page_discarding_helper.h
+++ b/chrome/browser/performance_manager/policies/page_discarding_helper.h
@@ -18,6 +18,10 @@
 #include "components/performance_manager/public/graph/page_node.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+namespace url_matcher {
+class URLMatcher;
+}  // namespace url_matcher
+
 namespace performance_manager {
 
 namespace mechanism {
@@ -63,6 +67,10 @@
   void OnBeforePageNodeRemoved(const PageNode* page_node) override;
   void OnIsAudibleChanged(const PageNode* page_node) override;
 
+  void SetNoDiscardPatternsForProfile(const std::string& browser_context_id,
+                                      const std::vector<std::string>& patterns);
+  void ClearNoDiscardPatternsForProfile(const std::string& browser_context_id);
+
   void SetMockDiscarderForTesting(
       std::unique_ptr<mechanism::PageDiscarder> discarder);
   bool CanUrgentlyDiscardForTesting(
@@ -103,6 +111,9 @@
       const PageNode* page_node,
       bool consider_minimum_protection_time = true) const;
 
+  bool IsPageOptedOutOfDiscarding(const std::string& browser_context_id,
+                                  const GURL& url) const;
+
   // NodeDataDescriber implementation:
   base::Value DescribePageNodeData(const PageNode* node) const override;
 
@@ -126,6 +137,9 @@
   std::unique_ptr<performance_manager::mechanism::PageDiscarder>
       page_discarder_;
 
+  std::map<std::string, std::unique_ptr<url_matcher::URLMatcher>>
+      profiles_no_discard_patterns_;
+
   raw_ptr<Graph> graph_ = nullptr;
 
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc b/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc
index c533d79b..35a3311 100644
--- a/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc
+++ b/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -205,6 +206,48 @@
           page_node()));
 }
 
+TEST_F(PageDiscardingHelperTest, TestCannotDiscardPageOnNoDiscardList) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures({features::kHighEfficiencyModeAvailable,
+                                 features::kBatterySaverModeAvailable},
+                                {});
+  // static_cast page_node because it's declared as a PageNodeImpl which hides
+  // the members it overrides from PageNode.
+  PageDiscardingHelper::GetFromGraph(graph())->SetNoDiscardPatternsForProfile(
+      static_cast<PageNode*>(page_node())->GetBrowserContextID(),
+      {"youtube.com"});
+  frame_node()->OnNavigationCommitted(GURL("https://www.youtube.com"), false);
+  EXPECT_FALSE(
+      PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting(
+          page_node()));
+
+  frame_node()->OnNavigationCommitted(GURL("https://www.example.com"), false);
+  EXPECT_TRUE(
+      PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting(
+          page_node()));
+
+  // Changing the no discard list rebuilds the matcher
+  PageDiscardingHelper::GetFromGraph(graph())->SetNoDiscardPatternsForProfile(
+      static_cast<PageNode*>(page_node())->GetBrowserContextID(),
+      {"google.com"});
+  frame_node()->OnNavigationCommitted(GURL("https://www.youtube.com"), false);
+  EXPECT_TRUE(
+      PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting(
+          page_node()));
+  frame_node()->OnNavigationCommitted(GURL("https://www.google.com"), false);
+  EXPECT_FALSE(
+      PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting(
+          page_node()));
+
+  // Setting the no discard list to empty makes all URLs discardable again.
+  PageDiscardingHelper::GetFromGraph(graph())->SetNoDiscardPatternsForProfile(
+      static_cast<PageNode*>(page_node())->GetBrowserContextID(), {});
+  frame_node()->OnNavigationCommitted(GURL("https://www.google.com"), false);
+  EXPECT_TRUE(
+      PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting(
+          page_node()));
+}
+
 // Tests UrgentlyDiscardMultiplePages.
 
 TEST_F(PageDiscardingHelperTest, UrgentlyDiscardMultiplePagesNoCandidate) {
diff --git a/chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.cc b/chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.cc
new file mode 100644
index 0000000..986f42c
--- /dev/null
+++ b/chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.cc
@@ -0,0 +1,89 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/values.h"
+#include "chrome/browser/performance_manager/policies/page_discarding_helper.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/performance_manager/public/features.h"
+#include "components/performance_manager/public/performance_manager.h"
+#include "components/performance_manager/public/user_tuning/prefs.h"
+#include "components/prefs/pref_service.h"
+#include "components/url_matcher/url_matcher.h"
+#include "components/user_prefs/user_prefs.h"
+#include "url/gurl.h"
+
+namespace performance_manager::user_tuning {
+
+ProfileDiscardOptOutListHelper::ProfileDiscardOptOutTracker::
+    ProfileDiscardOptOutTracker(const std::string& browser_context_id,
+                                PrefService* pref_service)
+    : browser_context_id_(browser_context_id) {
+  pref_change_registrar_.Init(pref_service);
+
+  pref_change_registrar_.Add(
+      performance_manager::user_tuning::prefs::kTabDiscardingExceptions,
+      base::BindRepeating(&ProfileDiscardOptOutListHelper::
+                              ProfileDiscardOptOutTracker::OnOptOutListChanged,
+                          base::Unretained(this)));
+  // Trigger a first update so the list reflects the initial pref value.
+  OnOptOutListChanged();
+}
+
+ProfileDiscardOptOutListHelper::ProfileDiscardOptOutTracker::
+    ~ProfileDiscardOptOutTracker() {
+  performance_manager::PerformanceManager::CallOnGraph(
+      FROM_HERE,
+      base::BindOnce(
+          [](std::string browser_context_id,
+             performance_manager::Graph* graph) {
+            policies::PageDiscardingHelper::GetFromGraph(graph)
+                ->ClearNoDiscardPatternsForProfile(browser_context_id);
+          },
+          browser_context_id_));
+}
+
+void ProfileDiscardOptOutListHelper::ProfileDiscardOptOutTracker::
+    OnOptOutListChanged() {
+  const base::Value::List& value_list =
+      pref_change_registrar_.prefs()->GetValueList(
+          performance_manager::user_tuning::prefs::kTabDiscardingExceptions);
+  std::vector<std::string> patterns;
+  patterns.reserve(value_list.size());
+  std::transform(value_list.begin(), value_list.end(),
+                 std::back_inserter(patterns),
+                 [](const base::Value& val) { return val.GetString(); });
+
+  performance_manager::PerformanceManager::CallOnGraph(
+      FROM_HERE,
+      base::BindOnce(
+          [](std::string browser_context_id, std::vector<std::string> patterns,
+             performance_manager::Graph* graph) {
+            policies::PageDiscardingHelper::GetFromGraph(graph)
+                ->SetNoDiscardPatternsForProfile(browser_context_id, patterns);
+          },
+          browser_context_id_, std::move(patterns)));
+}
+
+ProfileDiscardOptOutListHelper::ProfileDiscardOptOutListHelper() = default;
+ProfileDiscardOptOutListHelper::~ProfileDiscardOptOutListHelper() = default;
+
+void ProfileDiscardOptOutListHelper::OnProfileAdded(Profile* profile) {
+  discard_opt_out_trackers_.emplace(
+      std::piecewise_construct, std::forward_as_tuple(profile->UniqueId()),
+      std::forward_as_tuple(profile->UniqueId(), profile->GetPrefs()));
+}
+
+void ProfileDiscardOptOutListHelper::OnProfileWillBeRemoved(Profile* profile) {
+  auto it = discard_opt_out_trackers_.find(profile->UniqueId());
+  DCHECK(it != discard_opt_out_trackers_.end());
+  discard_opt_out_trackers_.erase(it);
+}
+
+}  // namespace performance_manager::user_tuning
diff --git a/chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.h b/chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.h
new file mode 100644
index 0000000..1e42a167
--- /dev/null
+++ b/chrome/browser/performance_manager/user_tuning/profile_discard_opt_out_list_helper.h
@@ -0,0 +1,50 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_USER_TUNING_PROFILE_DISCARD_OPT_OUT_LIST_HELPER_H_
+#define CHROME_BROWSER_PERFORMANCE_MANAGER_USER_TUNING_PROFILE_DISCARD_OPT_OUT_LIST_HELPER_H_
+
+#include <map>
+#include <string>
+
+#include "components/prefs/pref_change_registrar.h"
+
+class Profile;
+
+namespace performance_manager::user_tuning {
+
+// This class observes changes to each Profile's Discard Opt Out List
+// preference, and updates the PageDiscardingHelper accordingly.
+class ProfileDiscardOptOutListHelper {
+ public:
+  ProfileDiscardOptOutListHelper();
+  ~ProfileDiscardOptOutListHelper();
+
+  void OnProfileAdded(Profile* profile);
+  void OnProfileWillBeRemoved(Profile* profile);
+
+ private:
+  // A helper class to encapsulate the tracking of a single profile's
+  // preference.
+  class ProfileDiscardOptOutTracker {
+   public:
+    // Initialize this tracker's state, such that it starts observing the
+    // relevant prefs in `pref_service`
+    ProfileDiscardOptOutTracker(const std::string& browser_context_id,
+                                PrefService* pref_service);
+    ~ProfileDiscardOptOutTracker();
+
+   private:
+    void OnOptOutListChanged();
+
+    const std::string browser_context_id_;
+    PrefChangeRegistrar pref_change_registrar_;
+  };
+
+  std::map<std::string, ProfileDiscardOptOutTracker> discard_opt_out_trackers_;
+};
+
+}  // namespace performance_manager::user_tuning
+
+#endif  // CHROME_BROWSER_PERFORMANCE_MANAGER_USER_TUNING_PROFILE_DISCARD_OPT_OUT_LIST_HELPER_H_
diff --git a/chrome/browser/permissions/permission_update_message_controller_android.cc b/chrome/browser/permissions/permission_update_message_controller_android.cc
index 50f93b2..fef163a3e 100644
--- a/chrome/browser/permissions/permission_update_message_controller_android.cc
+++ b/chrome/browser/permissions/permission_update_message_controller_android.cc
@@ -65,6 +65,7 @@
   // more than expected.
   for (auto& delegate : message_delegates_) {
     if (delegate->GetTitleId() == title_id) {
+      delegate->AttachAdditionalCallback(std::move(callback));
       return;
     }
   }
diff --git a/chrome/browser/permissions/permission_update_message_controller_android_unittest.cc b/chrome/browser/permissions/permission_update_message_controller_android_unittest.cc
index f4dc7dd..bc4d16be 100644
--- a/chrome/browser/permissions/permission_update_message_controller_android_unittest.cc
+++ b/chrome/browser/permissions/permission_update_message_controller_android_unittest.cc
@@ -152,7 +152,7 @@
   ShowMedia(mock_permission_update_callback2.Get(), false);
   EXPECT_EQ(1u, GetMessageDelegatesSize());
   EXPECT_CALL(mock_permission_update_callback1, Run(false));
-  EXPECT_CALL(mock_permission_update_callback2, Run(false)).Times(0);
+  EXPECT_CALL(mock_permission_update_callback2, Run(false));
 
   // Message is dismissed first by primary action, and then permission update
   // callback is invoked. In this case, the dismiss reason should be
diff --git a/chrome/browser/permissions/permission_update_message_delegate_android.cc b/chrome/browser/permissions/permission_update_message_delegate_android.cc
index ba07441..c631f56 100644
--- a/chrome/browser/permissions/permission_update_message_delegate_android.cc
+++ b/chrome/browser/permissions/permission_update_message_delegate_android.cc
@@ -27,9 +27,9 @@
     PermissionUpdatedCallback callback,
     base::OnceCallback<void(PermissionUpdateMessageDelegate*)> delete_callback_)
     : content_settings_types_(content_settings_types),
-      callback_(std::move(callback)),
       delete_callback_(std::move(delete_callback_)) {
-  DCHECK(callback_);
+  DCHECK(callback);
+  callbacks_.push_back(std::move(callback));
   message_ = std::make_unique<messages::MessageWrapper>(
       messages::MessageIdentifier::PERMISSION_UPDATE,
       base::BindOnce(
@@ -53,9 +53,13 @@
                      base::Unretained(this)));
 }
 
+PermissionUpdateMessageDelegate::~PermissionUpdateMessageDelegate() {
+  DismissInternal();
+}
+
 void PermissionUpdateMessageDelegate::OnPermissionResult(
     bool all_permissions_granted) {
-  std::move(callback_).Run(all_permissions_granted);
+  RunCallbacks(all_permissions_granted);
   permissions::PermissionUmaUtil::RecordMissingPermissionInfobarAction(
       permissions::PermissionAction::GRANTED, content_settings_types_);
   // The callback may destroy `this`.
@@ -67,6 +71,11 @@
   return title_id_;
 }
 
+void PermissionUpdateMessageDelegate::AttachAdditionalCallback(
+    PermissionUpdatedCallback callback) {
+  callbacks_.push_back(std::move(callback));
+}
+
 void PermissionUpdateMessageDelegate::HandlePrimaryActionCallback() {
   permission_update_requester_->RequestPermissions();
 }
@@ -78,8 +87,9 @@
   message_.reset();
   // PermissionUpdateRequester::RequestPermissions can invoke its callback
   // synchronously in some cases. In that case, |OnPermissionResult| will be
-  // executed before this callback and |callback_| will be null.
-  if (dismiss_reason == messages::DismissReason::PRIMARY_ACTION || !callback_) {
+  // executed before this callback and |callbacks_| will be empty.
+  if (dismiss_reason == messages::DismissReason::PRIMARY_ACTION ||
+      callbacks_.empty()) {
     return;
   }
   permissions::PermissionUmaUtil::RecordMissingPermissionInfobarAction(
@@ -87,7 +97,7 @@
           ? permissions::PermissionAction::DISMISSED
           : permissions::PermissionAction::IGNORED,
       content_settings_types_);
-  std::move(callback_).Run(/*all_permissions_granted=*/false);
+  RunCallbacks(/*all_permissions_granted=*/false);
   // This dismiss callback should be executed in the end, because this can
   // destroy the current object.
   std::move(delete_callback_).Run(this);
@@ -100,6 +110,10 @@
   }
 }
 
-PermissionUpdateMessageDelegate::~PermissionUpdateMessageDelegate() {
-  DismissInternal();
+void PermissionUpdateMessageDelegate::RunCallbacks(
+    bool all_permissions_granted) {
+  for (auto& callback : callbacks_) {
+    std::move(callback).Run(all_permissions_granted);
+  }
+  callbacks_.clear();
 }
diff --git a/chrome/browser/permissions/permission_update_message_delegate_android.h b/chrome/browser/permissions/permission_update_message_delegate_android.h
index 7477a57..ad308f8 100644
--- a/chrome/browser/permissions/permission_update_message_delegate_android.h
+++ b/chrome/browser/permissions/permission_update_message_delegate_android.h
@@ -41,6 +41,7 @@
 
   void OnPermissionResult(bool all_permissions_granted);
   int GetTitleId();
+  void AttachAdditionalCallback(PermissionUpdatedCallback callback);
 
  private:
   friend class PermissionUpdateMessageControllerAndroidTest;
@@ -48,9 +49,10 @@
   void HandlePrimaryActionCallback();
   void HandleDismissCallback(messages::DismissReason dismiss_reason);
   void DismissInternal();
+  void RunCallbacks(bool all_permissions_granted);
 
   std::vector<ContentSettingsType> content_settings_types_;
-  PermissionUpdatedCallback callback_;
+  std::vector<PermissionUpdatedCallback> callbacks_;
   base::OnceCallback<void(PermissionUpdateMessageDelegate*)> delete_callback_;
   std::unique_ptr<PermissionUpdateRequester> permission_update_requester_;
   std::unique_ptr<messages::MessageWrapper> message_;
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 1985efa6..922ec9ab 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1149,8 +1149,8 @@
   ash::KioskAppManager::RegisterPrefs(registry);
   ash::KioskCryptohomeRemover::RegisterPrefs(registry);
   ash::language_prefs::RegisterPrefs(registry);
-  ash::local_search_service::SearchMetricsReporter::RegisterLocalStatePrefs(
-      registry);
+  chromeos::local_search_service::SearchMetricsReporter::
+      RegisterLocalStatePrefs(registry);
   ash::login::SecurityTokenSessionController::RegisterLocalStatePrefs(registry);
   ash::reporting::LoginLogoutReporter::RegisterPrefs(registry);
   ash::MultiProfileUserController::RegisterPrefs(registry);
diff --git a/chrome/browser/resource_coordinator/session_restore_policy.cc b/chrome/browser/resource_coordinator/session_restore_policy.cc
index 6787763..15ca094 100644
--- a/chrome/browser/resource_coordinator/session_restore_policy.cc
+++ b/chrome/browser/resource_coordinator/session_restore_policy.cc
@@ -68,8 +68,11 @@
   }
 
   size_t GetFreeMemoryMiB() const override {
-    constexpr uint64_t kMibibytesInBytes = 1 << 20;
-    return base::SysInfo::AmountOfAvailablePhysicalMemory() / kMibibytesInBytes;
+    constexpr int64_t kMibibytesInBytes = 1 << 20;
+    int64_t free_mem =
+        base::SysInfo::AmountOfAvailablePhysicalMemory() / kMibibytesInBytes;
+    DCHECK(free_mem >= 0);
+    return free_mem;
   }
 
   base::TimeTicks NowTicks() const override { return base::TimeTicks::Now(); }
diff --git a/chrome/browser/resources/side_panel/read_anything/app.html b/chrome/browser/resources/side_panel/read_anything/app.html
index 0a17ab22..21e59de6 100644
--- a/chrome/browser/resources/side_panel/read_anything/app.html
+++ b/chrome/browser/resources/side_panel/read_anything/app.html
@@ -5,25 +5,7 @@
     font-size: 18px;
     padding:  20px;
   }
-
-  .standard {
-    font-family: Roboto, Arial, sans-serif;
-  }
-  .sans-serif {
-    font-family: Roboto, Tahoma, sans-serif;
-  }
-  .serif {
-    font-family: Didot, Georgia, serif;
-  }
-  .arial {
-    font-family: Arial, Verdona, sans-serif;
-  }
-  .open-sans {
-    font-family: 'Open Sans', Courier, sans-serif;
-  }
-  .calibri {
-    font-family: Calibri, 'Times New Roman', serif;
-  }
 </style>
-<div id="container" class$="[[fontName_]]" style$="font-size:[[fontSize_]]px;">
+<div id="container"
+     style$="font-size:[[fontSize_]]px; font-family:[[fontName_]];">
 </div>
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts
index d06f4263..e4c878f2 100644
--- a/chrome/browser/resources/side_panel/read_anything/app.ts
+++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -63,14 +63,11 @@
   // Defines the valid font names that can be passed to front-end and maps
   // them to a corresponding class style in app.html. Must stay in-sync with
   // the names set in read_anything_font_model.cc.
-  private defaultFontName: string = 'standard';
-  private validFontNames: Array<{name: string, cssClass: string}> = [
-    {name: 'Standard font', cssClass: 'standard'},
-    {name: 'Serif', cssClass: 'serif'},
-    {name: 'Sans-serif', cssClass: 'sans-serif'},
-    {name: 'Arial', cssClass: 'arial'},
-    {name: 'Open Sans', cssClass: 'open-sans'},
-    {name: 'Calibri', cssClass: 'calibri'}
+  private defaultFontName: string = 'Standard font';
+  private validFontNames: Array<{name: string}> = [
+    {name: 'Standard font'}, {name: 'Sans'}, {name: 'Serif'}, {name: 'Arial'},
+    {name: 'Roboto'}, {name: 'Courier New'}, {name: 'Comic Sans MS'},
+    {name: 'Webdings'}, {name: 'Impact'}
   ];
 
   override connectedCallback() {
@@ -174,10 +171,8 @@
   updateFontName() {
     // Validate that the given font name is a valid choice, or use the default.
     const validFontName = this.validFontNames.find(
-        (f: {name: string, cssClass: string}) =>
-            f.name === chrome.readAnything.fontName);
-    this.fontName_ =
-        validFontName ? validFontName.cssClass : this.defaultFontName;
+        (f: {name: string}) => f.name === chrome.readAnything.fontName);
+    this.fontName_ = validFontName ? validFontName.name : this.defaultFontName;
   }
 
   updateFontSize() {
diff --git a/chrome/browser/segmentation_platform/android/contextual_page_action_controller_android.cc b/chrome/browser/segmentation_platform/android/contextual_page_action_controller_android.cc
index 64e40c7..ab18efe2 100644
--- a/chrome/browser/segmentation_platform/android/contextual_page_action_controller_android.cc
+++ b/chrome/browser/segmentation_platform/android/contextual_page_action_controller_android.cc
@@ -38,7 +38,7 @@
 
   // Populate input context.
   // TODO(shaktisahu): Have these string constants defined at a common file.
-  input_context->metadata_args.emplace("url", url->spec());
+  input_context->metadata_args.emplace("url", *url);
   segmentation_platform::SegmentationPlatformService*
       segmentation_platform_service = segmentation_platform::
           SegmentationPlatformServiceFactory::GetForProfile(profile);
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_config.cc b/chrome/browser/segmentation_platform/segmentation_platform_config.cc
index 4564b5e..e9b9aa1 100644
--- a/chrome/browser/segmentation_platform/segmentation_platform_config.cc
+++ b/chrome/browser/segmentation_platform/segmentation_platform_config.cc
@@ -174,7 +174,6 @@
         SegmentId::OPTIMIZATION_TARGET_CONTEXTUAL_PAGE_ACTION_PRICE_TRACKING);
   }
   config->on_demand_execution = true;
-  config->trigger = TriggerType::kPageLoad;
   return config;
 }
 
diff --git a/chrome/browser/storage_access_api/api_browsertest.cc b/chrome/browser/storage_access_api/api_browsertest.cc
index d31cc68..18814b8 100644
--- a/chrome/browser/storage_access_api/api_browsertest.cc
+++ b/chrome/browser/storage_access_api/api_browsertest.cc
@@ -511,12 +511,8 @@
     : public StorageAccessAPIBrowserTest,
       public testing::WithParamInterface<TestType> {
  public:
-  TestType GetTestType() const { return GetParam(); }
-
-  void ExpectStorage(TestType test_type,
-                     content::RenderFrameHost* frame,
-                     bool expected) {
-    switch (test_type) {
+  void ExpectStorage(content::RenderFrameHost* frame, bool expected) {
+    switch (GetTestType()) {
       case TestType::kFrame:
         storage::test::ExpectStorageForFrame(frame, expected);
         return;
@@ -526,8 +522,8 @@
     }
   }
 
-  void SetStorage(TestType test_type, content::RenderFrameHost* frame) {
-    switch (test_type) {
+  void SetStorage(content::RenderFrameHost* frame) {
+    switch (GetTestType()) {
       case TestType::kFrame:
         storage::test::SetStorageForFrame(frame);
         return;
@@ -536,6 +532,9 @@
         return;
     }
   }
+
+ private:
+  TestType GetTestType() const { return GetParam(); }
 };
 
 // Validate that the Storage Access API will unblock other types of storage
@@ -543,20 +542,18 @@
 // party pair requested on.
 IN_PROC_BROWSER_TEST_P(StorageAccessAPIStorageBrowserTest,
                        ThirdPartyIFrameStorageRequestsAccess) {
-  const TestType test_type = GetTestType();
-
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/browsing_data/site_data.html");
 
-  ExpectStorage(test_type, GetFrame(), false);
-  SetStorage(test_type, GetFrame());
-  ExpectStorage(test_type, GetFrame(), true);
+  ExpectStorage(GetFrame(), false);
+  SetStorage(GetFrame());
+  ExpectStorage(GetFrame(), true);
 
   SetBlockThirdPartyCookies(true);
 
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/browsing_data/site_data.html");
-  ExpectStorage(test_type, GetFrame(), false);
+  ExpectStorage(GetFrame(), false);
   EXPECT_FALSE(storage::test::HasStorageAccessForFrame(GetFrame()));
 
   // Allow all requests to b.com on a.com to access storage.
@@ -565,28 +562,26 @@
 
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/browsing_data/site_data.html");
-  ExpectStorage(test_type, GetFrame(), true);
+  ExpectStorage(GetFrame(), true);
   EXPECT_TRUE(storage::test::HasStorageAccessForFrame(GetFrame()));
 }
 
 IN_PROC_BROWSER_TEST_P(StorageAccessAPIStorageBrowserTest,
                        NestedThirdPartyIFrameStorage) {
-  const TestType test_type = GetTestType();
-
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/iframe.html");
   NavigateNestedFrameTo("c.com", "/browsing_data/site_data.html");
 
-  ExpectStorage(test_type, GetNestedFrame(), false);
-  SetStorage(test_type, GetNestedFrame());
-  ExpectStorage(test_type, GetNestedFrame(), true);
+  ExpectStorage(GetNestedFrame(), false);
+  SetStorage(GetNestedFrame());
+  ExpectStorage(GetNestedFrame(), true);
 
   SetBlockThirdPartyCookies(true);
 
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/iframe.html");
   NavigateNestedFrameTo("c.com", "/browsing_data/site_data.html");
-  ExpectStorage(test_type, GetNestedFrame(), false);
+  ExpectStorage(GetNestedFrame(), false);
   EXPECT_FALSE(storage::test::HasStorageAccessForFrame(GetNestedFrame()));
 
   // Allow all requests to b.com on a.com to access storage.
@@ -596,7 +591,7 @@
   NavigateToPageWithFrame("a.com");
   NavigateFrameTo("b.com", "/iframe.html");
   NavigateNestedFrameTo("c.com", "/browsing_data/site_data.html");
-  ExpectStorage(test_type, GetNestedFrame(), true);
+  ExpectStorage(GetNestedFrame(), true);
   EXPECT_TRUE(storage::test::HasStorageAccessForFrame(GetNestedFrame()));
 }
 
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index 2abecd4d..166bd8a 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -127,6 +127,8 @@
 #include "ash/public/cpp/app_list/app_list_switches.h"
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/crosapi/browser_util.h"
+#include "chrome/browser/ash/printing/oauth2/authorization_zones_manager.h"
+#include "chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h"
 #include "chrome/browser/ash/printing/printers_sync_bridge.h"
 #include "chrome/browser/ash/printing/synced_printers_manager.h"
 #include "chrome/browser/ash/printing/synced_printers_manager_factory.h"
@@ -507,6 +509,18 @@
       syncer::WORKSPACE_DESK,
       std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
           workspace_desk_delegate)));
+
+  if (chromeos::features::IsOAuthIppEnabled()) {
+    syncer::ModelTypeControllerDelegate*
+        printers_authorization_servers_delegate =
+            GetControllerDelegateForModelType(
+                syncer::PRINTERS_AUTHORIZATION_SERVERS)
+                .get();
+    controllers.push_back(std::make_unique<syncer::ModelTypeController>(
+        syncer::PRINTERS_AUTHORIZATION_SERVERS,
+        std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
+            printers_authorization_servers_delegate)));
+  }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   return controllers;
@@ -604,6 +618,12 @@
           ->GetSyncBridge()
           ->change_processor()
           ->GetControllerDelegate();
+    case syncer::PRINTERS_AUTHORIZATION_SERVERS:
+      return ash::printing::oauth2::AuthorizationZonesManagerFactory::
+          GetForBrowserContext(profile_)
+              ->GetModelTypeSyncBridge()
+              ->change_processor()
+              ->GetControllerDelegate();
     case syncer::WIFI_CONFIGURATIONS:
       return WifiConfigurationSyncServiceFactory::GetForProfile(profile_,
                                                                 /*create=*/true)
diff --git a/chrome/browser/sync/sync_service_factory.cc b/chrome/browser/sync/sync_service_factory.cc
index 9cdc094..2570d93b 100644
--- a/chrome/browser/sync/sync_service_factory.cc
+++ b/chrome/browser/sync/sync_service_factory.cc
@@ -73,6 +73,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
+#include "chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h"
 #include "chrome/browser/ash/printing/synced_printers_manager_factory.h"
 #include "chrome/browser/sync/desk_sync_service_factory.h"
 #include "chrome/browser/sync/wifi_configuration_sync_service_factory.h"
@@ -243,6 +244,8 @@
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   DependsOn(ash::SyncedPrintersManagerFactory::GetInstance());
+  DependsOn(
+      ash::printing::oauth2::AuthorizationZonesManagerFactory::GetInstance());
   DependsOn(DeskSyncServiceFactory::GetInstance());
   DependsOn(WifiConfigurationSyncServiceFactory::GetInstance());
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/sync/sync_service_factory_unittest.cc b/chrome/browser/sync/sync_service_factory_unittest.cc
index 45b7f5e..33a4774 100644
--- a/chrome/browser/sync/sync_service_factory_unittest.cc
+++ b/chrome/browser/sync/sync_service_factory_unittest.cc
@@ -126,7 +126,9 @@
       datatypes.Put(syncer::OS_PRIORITY_PREFERENCES);
     }
     datatypes.Put(syncer::PRINTERS);
-    // TODO(pawliczek): Add PRINTERS_AUTHORIZATION_SERVERS when ready.
+    if (chromeos::features::IsOAuthIppEnabled()) {
+      datatypes.Put(syncer::PRINTERS_AUTHORIZATION_SERVERS);
+    }
     datatypes.Put(syncer::WIFI_CONFIGURATIONS);
     datatypes.Put(syncer::WORKSPACE_DESK);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index af8bd11d..6f504d1a 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3138,6 +3138,7 @@
       "//chrome/browser/ui/webui/settings/ash/os_apps_page/mojom",
       "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings",
       "//chrome/browser/web_applications",
+      "//chrome/browser/webshare:storage",
       "//chrome/services/file_util/public/cpp",
       "//chromeos/ash/components/assistant:buildflags",
       "//chromeos/ash/components/dbus/audio",
@@ -4806,6 +4807,8 @@
       "views/side_panel/read_anything/read_anything_controller.h",
       "views/side_panel/read_anything/read_anything_coordinator.cc",
       "views/side_panel/read_anything/read_anything_coordinator.h",
+      "views/side_panel/read_anything/read_anything_font_combobox.cc",
+      "views/side_panel/read_anything/read_anything_font_combobox.h",
       "views/side_panel/read_anything/read_anything_model.cc",
       "views/side_panel/read_anything/read_anything_model.h",
       "views/side_panel/read_anything/read_anything_toolbar_view.cc",
diff --git a/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc b/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc
index 87d9d5e..45de338 100644
--- a/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc
+++ b/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc
@@ -9,9 +9,11 @@
 #include <vector>
 
 #include "ash/components/arc/mojom/intent_helper.mojom.h"
+#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/new_window_delegate.h"
 #include "base/check.h"
 #include "base/containers/fixed_flat_map.h"
+#include "base/files/file_path.h"
 #include "base/files/safe_base_name.h"
 #include "base/notreached.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
@@ -22,7 +24,11 @@
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/arc/fileapi/arc_content_file_system_url_util.h"
 #include "chrome/browser/ash/arc/intent_helper/custom_tab_session_impl.h"
+#include "chrome/browser/ash/file_manager/fileapi_util.h"
+#include "chrome/browser/ash/file_manager/path_util.h"
+#include "chrome/browser/ash/fusebox/fusebox_server.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/chromeos/fileapi/external_file_url_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
@@ -35,6 +41,7 @@
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
+#include "chrome/browser/webshare/prepare_directory_task.h"
 #include "chrome/common/webui_url_constants.h"
 #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
 #include "components/arc/intent_helper/custom_tab.h"
@@ -45,6 +52,9 @@
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "components/user_manager/user_manager.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "net/base/filename_util.h"
+#include "net/base/url_util.h"
+#include "storage/browser/file_system/file_system_context.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/window_open_disposition.h"
 #include "url/gurl.h"
@@ -134,7 +144,51 @@
   return url;
 }
 
+// Converts an externalfile:// ARC URL to a file:// URL managed by the FuseBox
+// Moniker system. This Moniker file is readable on the Linux filesystem like
+// any other file. Returns the input URL if a Moniker could not be created.
+GURL ConvertToMonikerFileUrl(Profile* profile, GURL external_file_url) {
+  const base::FilePath virtual_path =
+      chromeos::ExternalFileURLToVirtualPath(external_file_url);
+
+  const storage::FileSystemURL fs_url =
+      file_manager::util::GetFileManagerFileSystemContext(profile)
+          ->CreateCrackedFileSystemURL(
+              blink::StorageKey(file_manager::util::GetFilesAppOrigin()),
+              storage::kFileSystemTypeExternal, virtual_path);
+  if (!fs_url.is_valid()) {
+    return external_file_url;
+  }
+
+  fusebox::Server* fusebox_server = fusebox::Server::GetInstance();
+  if (!fusebox_server) {
+    return external_file_url;
+  }
+
+  fusebox::Moniker moniker = fusebox_server->CreateMoniker(fs_url);
+
+  // Keep the Moniker alive for the same time as a file shared through the Web
+  // Share API. We could be cleverer about scheduling the clean up, but "destroy
+  // after a fixed amount of time" is simple and works well enough in
+  // practice.
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](fusebox::Moniker moniker) {
+            fusebox::Server* fusebox_server = fusebox::Server::GetInstance();
+            if (fusebox_server) {
+              fusebox_server->DestroyMoniker(moniker);
+            }
+          },
+          moniker),
+      webshare::PrepareDirectoryTask::kSharedFileLifetime);
+
+  return net::FilePathToFileURL(
+      base::FilePath(fusebox::MonikerMap::GetFilename(moniker)));
+}
+
 apps::mojom::IntentPtr ConvertLaunchIntent(
+    Profile* profile,
     const arc::mojom::LaunchIntentPtr& launch_intent) {
   apps::mojom::IntentPtr intent = apps::mojom::Intent::New();
 
@@ -155,6 +209,10 @@
       auto file = apps::mojom::IntentFile::New();
 
       file->url = arc::ArcUrlToExternalFileUrl(file_info->content_uri);
+      if (ash::features::IsArcFuseBoxFileSharingEnabled()) {
+        file->url = ConvertToMonikerFileUrl(profile, file->url);
+      }
+
       file->mime_type = file_info->type;
       file->file_name = file_info->name;
       file->file_size = file_info->size;
@@ -373,7 +431,7 @@
     const GURL& start_url,
     arc::mojom::LaunchIntentPtr arc_intent) {
   DCHECK(start_url.is_valid());
-  DCHECK(start_url.SchemeIs(url::kHttpsScheme));
+  DCHECK(start_url.SchemeIs(url::kHttpsScheme) || net::IsLocalhost(start_url));
 
   // Fetch the profile associated with ARC. This method should only be called
   // for a |url| which was installed via ARC, and so we want the web app that is
@@ -403,7 +461,7 @@
     return;
   }
 
-  apps::mojom::IntentPtr intent = ConvertLaunchIntent(arc_intent);
+  apps::mojom::IntentPtr intent = ConvertLaunchIntent(profile, arc_intent);
 
   auto disposition = WindowOpenDisposition::NEW_WINDOW;
   proxy->AppRegistryCache().ForOneApp(
diff --git a/chrome/browser/ui/ash/desks/chrome_desks_templates_delegate.cc b/chrome/browser/ui/ash/desks/chrome_desks_templates_delegate.cc
index 7737cf3..8ccd34c 100644
--- a/chrome/browser/ui/ash/desks/chrome_desks_templates_delegate.cc
+++ b/chrome/browser/ui/ash/desks/chrome_desks_templates_delegate.cc
@@ -280,6 +280,15 @@
   if (tab_strip_model) {
     app_launch_info->urls = GetURLsIfApplicable(tab_strip_model);
     app_launch_info->active_tab_index = tab_strip_model->active_index();
+    int index_of_first_non_pinned_tab =
+        tab_strip_model->IndexOfFirstNonPinnedTab();
+    // Only set this field if there are pinned tabs. `IndexOfFirstNonPinnedTab`
+    // returns 0 if there are no pinned tabs.
+    if (index_of_first_non_pinned_tab > 0 &&
+        index_of_first_non_pinned_tab <= tab_strip_model->count()) {
+      app_launch_info->first_non_pinned_tab_index =
+          index_of_first_non_pinned_tab;
+    }
     if (tab_strip_model->SupportsTabGroups()) {
       app_launch_info->tab_group_infos =
           chrome_desks_util::ConvertTabGroupsToTabGroupInfos(
diff --git a/chrome/browser/ui/ash/desks/chrome_desks_util.cc b/chrome/browser/ui/ash/desks/chrome_desks_util.cc
index de003bb..bc33e0e 100644
--- a/chrome/browser/ui/ash/desks/chrome_desks_util.cc
+++ b/chrome/browser/ui/ash/desks/chrome_desks_util.cc
@@ -61,4 +61,15 @@
   }
 }
 
+void SetBrowserPinnedTabs(int32_t first_non_pinned_tab_index,
+                          Browser* browser) {
+  TabStripModel* tab_strip_model = browser->tab_strip_model();
+
+  DCHECK(first_non_pinned_tab_index <= tab_strip_model->count());
+  for (int32_t tab_index = 0; tab_index < first_non_pinned_tab_index;
+       tab_index++) {
+    tab_strip_model->SetTabPinned(tab_index, /*pinned=*/true);
+  }
+}
+
 }  // namespace chrome_desks_util
diff --git a/chrome/browser/ui/ash/desks/chrome_desks_util.h b/chrome/browser/ui/ash/desks/chrome_desks_util.h
index a730ef7..1eb6dc8f 100644
--- a/chrome/browser/ui/ash/desks/chrome_desks_util.h
+++ b/chrome/browser/ui/ash/desks/chrome_desks_util.h
@@ -27,6 +27,9 @@
     const std::vector<app_restore::TabGroupInfo>& tab_groups,
     Browser* browser);
 
+// Sets tabs in `browser` to be pinned up to the `first_non_pinned_tab_index`.
+void SetBrowserPinnedTabs(int32_t first_non_pinned_tab_index, Browser* browser);
+
 }  // namespace chrome_desks_util
 
 #endif
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
index de3c495..b09bebc 100644
--- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -433,6 +433,16 @@
     return browser;
   }
 
+  Browser* CreateBrowserWithPinnedTabs(const std::vector<GURL>& urls,
+                                       int first_non_pinned_tab_index) {
+    Browser* browser = CreateBrowserImpl(urls, absl::nullopt);
+
+    chrome_desks_util::SetBrowserPinnedTabs(first_non_pinned_tab_index,
+                                            browser);
+    browser->window()->Show();
+    return browser;
+  }
+
   Browser* CreateBrowserWithTabGroups(
       const std::vector<GURL>& urls,
       const std::vector<app_restore::TabGroupInfo>& tab_groups) {
@@ -562,6 +572,50 @@
                                        data->tab_group_infos.value()));
 }
 
+// Tests that a browser's pinned tabs can be captured correctly in a saved desk.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest, CaptureBrowserWithPinnedTabs) {
+  std::vector<GURL> tabs = {GURL(kExampleUrl1), GURL(kExampleUrl2)};
+  int expected_number_of_pinned_tabs = 1;
+
+  // Create a new browser and add a few tabs to it.
+  Browser* browser =
+      CreateBrowserWithPinnedTabs(tabs, expected_number_of_pinned_tabs);
+  aura::Window* window = browser->window()->GetNativeWindow();
+
+  const int32_t browser_window_id =
+      window->GetProperty(app_restore::kWindowIdKey);
+  // Get current tabs from browser.
+  std::vector<GURL> urls = GetURLsForBrowserWindow(browser);
+
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  ClickSaveDeskAsTemplateButton();
+
+  std::vector<const ash::DeskTemplate*> templates = GetAllEntries();
+  ASSERT_EQ(1u, templates.size());
+
+  const ash::DeskTemplate* desk_template = templates.front();
+  const app_restore::RestoreData* restore_data =
+      desk_template->desk_restore_data();
+  const auto& app_id_to_launch_list = restore_data->app_id_to_launch_list();
+  EXPECT_EQ(1u, app_id_to_launch_list.size());
+
+  // Find `browser` window's app restore data.
+  auto iter = app_id_to_launch_list.find(app_constants::kChromeAppId);
+  ASSERT_TRUE(iter != app_id_to_launch_list.end());
+  auto app_restore_data_iter = iter->second.find(browser_window_id);
+  ASSERT_TRUE(app_restore_data_iter != iter->second.end());
+  const auto& data = app_restore_data_iter->second;
+  // Check the urls are captured correctly in the `desk_template`.
+  EXPECT_EQ(urls, data->urls.value());
+
+  // Assert number of pinned tabs is correct.
+  EXPECT_TRUE(data->first_non_pinned_tab_index.has_value());
+  EXPECT_THAT(expected_number_of_pinned_tabs,
+              data->first_non_pinned_tab_index.value());
+}
+
 // Tests that incognito browser windows will NOT be captured in the desk
 // template.
 IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest, CaptureIncognitoBrowserTest) {
@@ -964,6 +1018,40 @@
               testing::UnorderedElementsAreArray(got_tab_groups.value()));
 }
 
+// Tests that a browser's pinned tabs can be launched correctly in a saved desk.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest, LaunchBrowserWithPinnedTabs) {
+  ASSERT_TRUE(DesksClient::Get());
+
+  // create expected values.
+  std::vector<GURL> tabs = {GURL(kExampleUrl1), GURL(kExampleUrl2)};
+  int expected_number_of_pinned_tabs = 1;
+
+  // Create a new browser and add a few tabs to it.
+  Browser* browser =
+      CreateBrowserWithPinnedTabs(tabs, expected_number_of_pinned_tabs);
+
+  // Get current tabs from browser.
+  std::vector<GURL> urls = GetURLsForBrowserWindow(browser);
+
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+
+  ClickSaveDeskAsTemplateButton();
+
+  ClickFirstTemplateItem();
+
+  // Wait for tabs to load.
+  content::RunAllTasksUntilIdle();
+
+  // Verify that the browser was launched with the correct urls and active tab.
+  Browser* new_browser = FindLaunchedBrowserByURLs(urls);
+  ASSERT_TRUE(new_browser);
+
+  // Assert the number of pinned tabs is correct.
+  ASSERT_EQ(expected_number_of_pinned_tabs,
+            new_browser->tab_strip_model()->IndexOfFirstNonPinnedTab());
+}
+
 // Tests that browser session restore isn't triggered when we launch a template
 // that contains a browser window.
 IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
diff --git a/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc b/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc
index 773f3ade..7f8e0d6 100644
--- a/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc
+++ b/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc
@@ -220,6 +220,13 @@
             app_restore_data->tab_group_infos.value(), browser);
       }
 
+      if (app_restore_data->first_non_pinned_tab_index.has_value() &&
+          app_restore_data->first_non_pinned_tab_index.value() <=
+              urls->size()) {
+        chrome_desks_util::SetBrowserPinnedTabs(
+            app_restore_data->first_non_pinned_tab_index.value(), browser);
+      }
+
       // We need to handle minimized windows separately since unlike other
       // window types, it's not shown.
       if (window_state_type &&
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index 7c6bb49..fbc8f515 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -59,7 +59,8 @@
                                                  const std::string& file_name,
                                                  ash::WallpaperLayout layout,
                                                  const gfx::ImageSkia& image,
-                                                 bool preview_mode) {
+                                                 bool preview_mode,
+                                                 const std::string& file_path) {
   ++set_custom_wallpaper_count_;
 }
 
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index 4a336e8dc..5386483e 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -80,7 +80,8 @@
                           const std::string& file_name,
                           ash::WallpaperLayout layout,
                           const gfx::ImageSkia& image,
-                          bool preview_mode) override;
+                          bool preview_mode,
+                          const std::string& file_path = "") override;
   void SetOnlineWallpaper(const ash::OnlineWallpaperParams& params,
                           SetWallpaperCallback callback) override;
   void SetOnlineWallpaperIfExists(const ash::OnlineWallpaperParams& params,
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
index 60dc63a..872fac6 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -325,11 +325,12 @@
     const std::string& file_name,
     ash::WallpaperLayout layout,
     const gfx::ImageSkia& image,
-    bool preview_mode) {
+    bool preview_mode,
+    const std::string& file_path) {
   if (!IsKnownUser(account_id))
     return;
   wallpaper_controller_->SetCustomWallpaper(account_id, file_name, layout,
-                                            image, preview_mode);
+                                            image, preview_mode, file_path);
 }
 
 void WallpaperControllerClientImpl::SetOnlineWallpaper(
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
index 181b544..d699c61 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -108,7 +108,8 @@
                           const std::string& file_name,
                           ash::WallpaperLayout layout,
                           const gfx::ImageSkia& image,
-                          bool preview_mode);
+                          bool preview_mode,
+                          const std::string& file_path = "");
   void SetOnlineWallpaper(
       const ash::OnlineWallpaperParams& params,
       ash::WallpaperController::SetWallpaperCallback callback);
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc
index 6c74ce14..46ae199 100644
--- a/chrome/browser/ui/popup_browsertest.cc
+++ b/chrome/browser/ui/popup_browsertest.cc
@@ -318,4 +318,17 @@
       << " popup: " << popup_bounds.ToString();
 }
 
+// Opens two popups with custom position and size, but one has noopener. They
+// should both have the same position and size. http://crbug.com/1011688
+IN_PROC_BROWSER_TEST_P(PopupBrowserTest, NoopenerPositioning) {
+  Browser* noopener_popup = OpenPopup(
+      browser(),
+      "open('.', '', 'noopener=1,height=200,width=200,top=100,left=100')");
+  Browser* opener_popup = OpenPopup(
+      browser(),
+      "open('.', '', 'height=200,width=200,top=100,left=100')");
+  EXPECT_EQ(noopener_popup->window()->GetBounds(),
+            opener_popup->window()->GetBounds());
+}
+
 }  // namespace
diff --git a/chrome/browser/ui/search_engines/template_url_table_model.cc b/chrome/browser/ui/search_engines/template_url_table_model.cc
index 4b49ef9..d9fd693e 100644
--- a/chrome/browser/ui/search_engines/template_url_table_model.cc
+++ b/chrome/browser/ui/search_engines/template_url_table_model.cc
@@ -48,9 +48,8 @@
       default_entries.push_back(template_url);
     } else if (template_url->type() == TemplateURL::OMNIBOX_API_EXTENSION) {
       extension_entries.push_back(template_url);
-    } else if (OmniboxFieldTrial::IsActiveSearchEnginesEnabled() &&
-               (template_url->is_active() ==
-                TemplateURLData::ActiveStatus::kTrue)) {
+    } else if (template_url->is_active() ==
+               TemplateURLData::ActiveStatus::kTrue) {
       active_entries.push_back(template_url);
     } else {
       other_entries.push_back(template_url);
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model.cc b/chrome/browser/ui/toolbar/toolbar_actions_model.cc
index 2f83fdb..a458fa9 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_model.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_model.cc
@@ -21,7 +21,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_management.h"
 #include "chrome/browser/extensions/extension_message_bubble_controller.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
@@ -34,13 +33,11 @@
 #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
 #include "chrome/browser/ui/toolbar/toolbar_actions_model_factory.h"
 #include "components/prefs/pref_service.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_action_manager.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extension_util.h"
-#include "extensions/browser/notification_types.h"
+#include "extensions/browser/permissions_manager.h"
 #include "extensions/browser/pref_names.h"
 #include "extensions/browser/unloaded_extension_reason.h"
 #include "extensions/common/extension_set.h"
@@ -69,10 +66,6 @@
       extensions::pref_names::kPinnedExtensions,
       base::BindRepeating(&ToolbarActionsModel::UpdatePinnedActionIds,
                           base::Unretained(this)));
-
-  notification_registrar_.Add(
-      this, extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::Source<Profile>(profile_.get()));
 }
 
 ToolbarActionsModel::~ToolbarActionsModel() {}
@@ -136,21 +129,18 @@
   UpdatePinnedActionIds();
 }
 
-void ToolbarActionsModel::Observe(int type,
-                                  const content::NotificationSource& source,
-                                  const content::NotificationDetails& details) {
-  DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, type);
-
-  const extensions::ExtensionId& extension_id =
-      content::Details<extensions::UpdatedExtensionPermissionsInfo>(details)
-          ->extension->id();
-
-  if (HasAction(extension_id)) {
+void ToolbarActionsModel::OnExtensionPermissionsUpdated(
+    const extensions::UpdatedExtensionPermissionsInfo& info) {
+  if (HasAction(info.extension->id())) {
     for (Observer& observer : observers_)
-      observer.OnToolbarActionUpdated(extension_id);
+      observer.OnToolbarActionUpdated(info.extension->id());
   }
 }
 
+void ToolbarActionsModel::Shutdown() {
+  permissions_manager_observation_.Reset();
+}
+
 void ToolbarActionsModel::RemovePref(const ActionId& action_id) {
   // The extension is already unloaded at this point, and so shouldn't be in
   // the active pinned set.
@@ -172,6 +162,8 @@
   // taken from prefs.
   extension_registry_observation_.Observe(extension_registry_.get());
   extension_action_observation_.Observe(extension_action_api_.get());
+  permissions_manager_observation_.Observe(
+      extensions::PermissionsManager::Get(profile_));
 
   auto* management =
       extensions::ExtensionManagementFactory::GetForBrowserContext(profile_);
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model.h b/chrome/browser/ui/toolbar/toolbar_actions_model.h
index bc8d2253..8e7b4ce 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_model.h
+++ b/chrome/browser/ui/toolbar/toolbar_actions_model.h
@@ -16,12 +16,11 @@
 #include "chrome/browser/extensions/extension_management.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_change_registrar.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "extensions/browser/extension_action.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_registry_observer.h"
+#include "extensions/browser/permissions_manager.h"
 #include "extensions/common/extension.h"
 
 class Browser;
@@ -44,7 +43,7 @@
 class ToolbarActionsModel : public extensions::ExtensionActionAPI::Observer,
                             public extensions::ExtensionRegistryObserver,
                             public extensions::ExtensionManagement::Observer,
-                            public content::NotificationObserver,
+                            public extensions::PermissionsManager::Observer,
                             public KeyedService {
  public:
   using ActionId = std::string;
@@ -156,10 +155,12 @@
   // extensions::ExtensionManagement::Observer:
   void OnExtensionManagementSettingsChanged() override;
 
-  // content::NotificationObserver:
-  void Observe(int notification_type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  // extensions::PermissionsManager::Observer:
+  void OnExtensionPermissionsUpdated(
+      const extensions::UpdatedExtensionPermissionsInfo& info) override;
+
+  // KeyedService:
+  void Shutdown() override;
 
   // To be called after the extension service is ready; gets loaded extensions
   // from the ExtensionRegistry, their saved order from the pref service, and
@@ -246,8 +247,9 @@
                           extensions::ExtensionManagement::Observer>
       extension_management_observation_{this};
 
-  // Registrar for receiving permission-related notifications.
-  content::NotificationRegistrar notification_registrar_;
+  base::ScopedObservation<extensions::PermissionsManager,
+                          extensions::PermissionsManager::Observer>
+      permissions_manager_observation_{this};
 
   base::WeakPtrFactory<ToolbarActionsModel> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc b/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc
index c8d6031..ae765e3 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc
@@ -14,6 +14,7 @@
 #include "extensions/browser/extension_prefs_factory.h"
 #include "extensions/browser/extension_registry_factory.h"
 #include "extensions/browser/extensions_browser_client.h"
+#include "extensions/browser/permissions_manager.h"
 
 // static
 ToolbarActionsModel* ToolbarActionsModelFactory::GetForProfile(
@@ -36,6 +37,7 @@
   DependsOn(extensions::ExtensionRegistryFactory::GetInstance());
   DependsOn(extensions::ExtensionSystemFactory::GetInstance());
   DependsOn(extensions::ExtensionManagementFactory::GetInstance());
+  DependsOn(extensions::PermissionsManager::GetFactory());
 }
 
 ToolbarActionsModelFactory::~ToolbarActionsModelFactory() {}
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc
index 2d76188..83e20bc5 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc
@@ -30,14 +30,14 @@
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "extensions/browser/disable_reason.h"
 #include "extensions/browser/extension_system.h"
-#include "extensions/browser/notification_types.h"
+#include "extensions/browser/permissions_manager.h"
 #include "extensions/browser/pref_names.h"
 #include "extensions/common/extension.h"
+#include "extensions/test/permissions_manager_waiter.h"
 #include "extensions/test/test_extension_dir.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "ui/views/animation/ink_drop.h"
@@ -762,13 +762,12 @@
         browser()->tab_strip_model()->GetActiveWebContents();
     extensions::ExtensionActionRunner::GetForWebContents(web_contents)
         ->accept_bubble_for_testing(true);
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     context_menu->ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_CLICK,
         /*event_flags=*/0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
   }
 
   // The extension should not have access to the website.
@@ -788,13 +787,12 @@
 
   // Change the extension permissions to run on site using the context menu.
   {
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     context_menu->ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_SITE,
         /*event_flags=*/0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
   }
 
   // The extension should have access to the site by default.
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 f60e70d1..f300262b 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
@@ -445,7 +445,7 @@
   ConsistencyCheck();
 }
 
-void ExtensionsTabbedMenuView::UserPermissionsSettingsChanged(
+void ExtensionsTabbedMenuView::OnUserPermissionsSettingsChanged(
     const extensions::PermissionsManager::UserPermissionsSettings& settings) {
   UpdateSiteAccessMenuItems(toolbar_model_->action_ids());
   UpdateSiteAccessTab();
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 41f394e..8c039dd 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
@@ -119,7 +119,7 @@
   void OnToolbarPinnedActionsChanged() override;
 
   // PermissionsManager::Observer:
-  void UserPermissionsSettingsChanged(
+  void OnUserPermissionsSettingsChanged(
       const extensions::PermissionsManager::UserPermissionsSettings& settings)
       override;
 
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 0650075..f815f4d 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
@@ -17,11 +17,11 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_navigation_observer.h"
-#include "extensions/browser/notification_types.h"
+#include "extensions/browser/permissions_manager.h"
 #include "extensions/common/extension_features.h"
+#include "extensions/test/permissions_manager_waiter.h"
 #include "extensions/test/test_extension_dir.h"
 #include "ui/views/animation/ink_drop.h"
 #include "ui/views/layout/animating_layout_manager.h"
@@ -413,13 +413,12 @@
                                ContextMenuSource::kMenuItem));
   ASSERT_TRUE(context_menu);
   {
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     context_menu->ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_CLICK,
         /*event_flags=*/0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
   }
 
   // Verify the extension is in the requests access section.
@@ -433,13 +432,12 @@
   // Allow the site to access the extension by changing the extension
   // permissions to run on site using the context menu.
   {
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     context_menu->ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_SITE,
         /*event_flags=*/0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
   }
 
   // Verify the extension is in the has access section.
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 aa4f37c7..5a9410e 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
@@ -20,9 +20,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/url_formatter/url_formatter.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
-#include "extensions/browser/notification_types.h"
 #include "extensions/browser/test_extension_registry_observer.h"
 #include "extensions/common/extension_features.h"
 #include "extensions/common/extension_urls.h"
@@ -289,11 +287,10 @@
 void ExtensionsTabbedMenuViewUnitTest::SelectSiteAccessInCombobox(
     SiteAccessMenuItemView* site_access_item,
     int index) {
-  content::WindowedNotificationObserver permissions_observer(
-      extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::NotificationService::AllSources());
+  extensions::PermissionsManagerWaiter waiter(
+      extensions::PermissionsManager::Get(profile()));
   site_access_item->site_access_combobox_for_testing()->SetSelectedRow(index);
-  permissions_observer.Wait();
+  waiter.WaitForExtensionPermissionsUpdate();
   LayoutMenuIfNecessary();
 }
 
@@ -307,7 +304,7 @@
                                gfx::PointF(), ui::EventTimeForNow(),
                                ui::EF_LEFT_MOUSE_BUTTON, 0);
   site_setting->NotifyClick(release_event);
-  manager_waiter.WaitForPermissionsChange();
+  manager_waiter.WaitForUserPermissionsSettingsChange();
   LayoutMenuIfNecessary();
 }
 
@@ -852,12 +849,11 @@
 
   // Change extension's site access to run "on site" using the context menu.
   {
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     menu.ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_SITE, 0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
     LayoutMenuIfNecessary();
   }
 
@@ -871,12 +867,11 @@
 
   // Change extension's site access to run "on click" using the context menu.
   {
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     menu.ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_CLICK, 0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
     LayoutMenuIfNecessary();
   }
 
@@ -915,11 +910,10 @@
             kOnClickComboboxIndex);
 
   // Run extensions action by clicking on it.
-  content::WindowedNotificationObserver permissions_observer(
-      extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::NotificationService::AllSources());
+  extensions::PermissionsManagerWaiter waiter(
+      extensions::PermissionsManager::Get(profile()));
   ClickPrimaryActionButton(GetOnlyRequestsAccessMenuItem());
-  permissions_observer.Wait();
+  waiter.WaitForExtensionPermissionsUpdate();
   LayoutMenuIfNecessary();
 
   // Verify extension is in the "has access" section with "on click" access.
@@ -1095,13 +1089,12 @@
   // in one of the extensions to be able to test both site access sections.
   const GURL url("http://www.a.com");
   web_contents_tester()->NavigateAndCommit(url);
-  content::WindowedNotificationObserver permissions_observer(
-      extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::NotificationService::AllSources());
+  extensions::PermissionsManagerWaiter waiter(
+      extensions::PermissionsManager::Get(profile()));
   extensions::SitePermissionsHelper(profile()).UpdateSiteAccess(
       *extensionA, browser()->tab_strip_model()->GetActiveWebContents(),
       /*new_access=*/extensions::SitePermissionsHelper::SiteAccess::kOnClick);
-  permissions_observer.Wait();
+  waiter.WaitForExtensionPermissionsUpdate();
   WaitForAnimation();
   ShowSiteAccessTabInMenu();
 
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
index dbce96a3..2a31f36 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -538,7 +538,7 @@
   drop_weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
-void ExtensionsToolbarContainer::UserPermissionsSettingsChanged(
+void ExtensionsToolbarContainer::OnUserPermissionsSettingsChanged(
     const extensions::PermissionsManager::UserPermissionsSettings& settings) {
   UpdateControlsVisibility();
 }
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h
index e21c435..d2b7fba4 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h
@@ -242,7 +242,7 @@
   void OnToolbarPinnedActionsChanged() override;
 
   // PermissionsManager::Observer:
-  void UserPermissionsSettingsChanged(
+  void OnUserPermissionsSettingsChanged(
       const extensions::PermissionsManager::UserPermissionsSettings& settings)
       override;
 
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 c3d9159e..1fb3e61 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
@@ -12,8 +12,6 @@
 #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h"
 #include "chrome/browser/ui/views/extensions/extensions_toolbar_unittest.h"
 #include "chrome/grit/generated_resources.h"
-#include "content/public/browser/notification_service.h"
-#include "extensions/browser/notification_types.h"
 #include "extensions/common/extension_features.h"
 #include "extensions/test/permissions_manager_waiter.h"
 #include "ui/views/view_utils.h"
@@ -221,12 +219,11 @@
   // Change the extension to run only on click using the context
   // menu. The extension should request access to the current site.
   {
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     context_menu.ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_CLICK, 0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
     EXPECT_TRUE(IsRequestAccessButtonVisible());
     EXPECT_EQ(
         request_access_button()->GetText(),
@@ -236,12 +233,11 @@
   // Change the extension to run only on site using the context
   // menu. The extension should not request access to the current site.
   {
-    content::WindowedNotificationObserver permissions_observer(
-        extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-        content::NotificationService::AllSources());
+    extensions::PermissionsManagerWaiter waiter(
+        extensions::PermissionsManager::Get(profile()));
     context_menu.ExecuteCommand(
         extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_SITE, 0);
-    permissions_observer.Wait();
+    waiter.WaitForExtensionPermissionsUpdate();
     EXPECT_FALSE(IsRequestAccessButtonVisible());
   }
 }
@@ -355,7 +351,7 @@
     extensions::PermissionsManagerWaiter manager_waiter(
         extensions::PermissionsManager::Get(profile()));
     manager->AddUserPermittedSite(url_origin);
-    manager_waiter.WaitForPermissionsChange();
+    manager_waiter.WaitForUserPermissionsSettingsChange();
     WaitForAnimation();
     EXPECT_FALSE(IsRequestAccessButtonVisible());
   }
@@ -365,7 +361,7 @@
     extensions::PermissionsManagerWaiter manager_waiter(
         extensions::PermissionsManager::Get(profile()));
     manager->AddUserRestrictedSite(url_origin);
-    manager_waiter.WaitForPermissionsChange();
+    manager_waiter.WaitForUserPermissionsSettingsChange();
     WaitForAnimation();
     EXPECT_FALSE(IsRequestAccessButtonVisible());
   }
@@ -376,7 +372,7 @@
     extensions::PermissionsManagerWaiter manager_waiter(
         extensions::PermissionsManager::Get(profile()));
     manager->RemoveUserRestrictedSite(url_origin);
-    manager_waiter.WaitForPermissionsChange();
+    manager_waiter.WaitForUserPermissionsSettingsChange();
     WaitForAnimation();
     EXPECT_TRUE(IsRequestAccessButtonVisible());
   }
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_unittest.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_unittest.cc
index e85bd71..e9ca6c6 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_unittest.cc
@@ -12,11 +12,10 @@
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
 #include "components/crx_file/id_util.h"
-#include "content/public/browser/notification_service.h"
-#include "extensions/browser/notification_types.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/value_builder.h"
+#include "extensions/test/permissions_manager_waiter.h"
 #include "ui/events/base_event_utils.h"
 #include "ui/views/layout/animating_layout_manager_test_util.h"
 #include "ui/views/view_utils.h"
@@ -122,12 +121,11 @@
 
 void ExtensionsToolbarUnitTest::WithholdHostPermissions(
     const extensions::Extension* extension) {
-  content::WindowedNotificationObserver permissions_observer(
-      extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-      content::NotificationService::AllSources());
+  extensions::PermissionsManagerWaiter waiter(
+      extensions::PermissionsManager::Get(profile()));
   extensions::ScriptingPermissionsModifier(profile(), extension)
       .RemoveAllGrantedHostPermissions();
-  permissions_observer.Wait();
+  waiter.WaitForExtensionPermissionsUpdate();
 }
 
 void ExtensionsToolbarUnitTest::ClickButton(views::Button* button) const {
diff --git a/chrome/browser/ui/views/frame/glass_browser_caption_button_container.cc b/chrome/browser/ui/views/frame/glass_browser_caption_button_container.cc
index d314b2ec..9fbc95d 100644
--- a/chrome/browser/ui/views/frame/glass_browser_caption_button_container.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_caption_button_container.cc
@@ -197,10 +197,11 @@
   maximize_button_->SetVisible(!is_maximized && can_maximize);
 
   // In touch mode, windows cannot be taken out of fullscreen or tiled mode, so
-  // the maximize/restore button should be disabled.
+  // the maximize/restore button should be disabled, unless the window is not
+  // maximized. TODO(crbug.com/1338572): Also check if the window is tiled.
   const bool is_touch = ui::TouchUiController::Get()->touch_ui();
   restore_button_->SetEnabled(!is_touch);
-  maximize_button_->SetEnabled(!is_touch);
+  maximize_button_->SetEnabled(!is_touch || !is_maximized);
   InvalidateLayout();
 }
 
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
index b6bfd38..8cf7a93 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
@@ -27,16 +27,110 @@
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/user_display_mode.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
+#include "chrome/common/webui_url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/common/content_features.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
+#include "ui/base/pointer/touch_ui_controller.h"
 #include "ui/color/color_id.h"
 #include "ui/color/color_provider.h"
 #include "ui/views/view_utils.h"
 
+class GlassBrowserFrameViewTest : public InProcessBrowserTest {
+ public:
+  GlassBrowserFrameViewTest() = default;
+  GlassBrowserFrameViewTest(const GlassBrowserFrameViewTest&) = delete;
+  GlassBrowserFrameViewTest& operator=(const GlassBrowserFrameViewTest&) =
+      delete;
+  ~GlassBrowserFrameViewTest() override = default;
+
+ protected:
+  GlassBrowserFrameView* GetGlassBrowserFrameView() {
+    auto* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
+    views::NonClientFrameView* frame_view =
+        browser_view->GetWidget()->non_client_view()->frame_view();
+
+    if (!views::IsViewClass<GlassBrowserFrameView>(frame_view))
+      return nullptr;
+    return static_cast<GlassBrowserFrameView*>(frame_view);
+  }
+
+  const WindowsCaptionButton* GetMaximizeButton() {
+    auto* glass_frame_view = GetGlassBrowserFrameView();
+    if (!glass_frame_view)
+      return nullptr;
+    auto* caption_button_container =
+        glass_frame_view->caption_button_container_for_testing();
+    return static_cast<const WindowsCaptionButton*>(
+        caption_button_container->GetViewByID(VIEW_ID_MAXIMIZE_BUTTON));
+  }
+};
+
+// Test that in touch mode, the maximize button is enabled for a non-maximized
+// window.
+IN_PROC_BROWSER_TEST_F(GlassBrowserFrameViewTest,
+                       NonMaximizedTouchMaximizeButtonState) {
+  ui::TouchUiController::TouchUiScoperForTesting touch_ui_scoper_{true};
+  auto* maximize_button = GetMaximizeButton();
+  if (!maximize_button)
+    GTEST_SKIP();
+
+  EXPECT_TRUE(maximize_button->GetVisible());
+  EXPECT_TRUE(maximize_button->GetEnabled());
+}
+
+// Test that in touch mode, the maximize button is disabled and not visible for
+// a maximized window.
+IN_PROC_BROWSER_TEST_F(GlassBrowserFrameViewTest,
+                       MaximizedTouchMaximizeButtonState) {
+  ui::TouchUiController::TouchUiScoperForTesting touch_ui_scoper_{true};
+  auto* glass_frame_view = GetGlassBrowserFrameView();
+  if (!glass_frame_view)
+    GTEST_SKIP();
+
+  glass_frame_view->frame()->Maximize();
+
+  static_cast<views::View*>(glass_frame_view)->Layout();
+  auto* maximize_button = GetMaximizeButton();
+
+  // Button isn't visible, and should be disabled.
+  EXPECT_FALSE(maximize_button->GetEnabled());
+  EXPECT_FALSE(maximize_button->GetVisible());
+}
+
+// Test that in non touch mode, the maximize button is enabled for a
+// non-maximized window.
+IN_PROC_BROWSER_TEST_F(GlassBrowserFrameViewTest,
+                       NonTouchNonMaximizedMaximizeButtonState) {
+  ui::TouchUiController::TouchUiScoperForTesting touch_ui_scoper_{false};
+  auto* maximize_button = GetMaximizeButton();
+  if (!maximize_button)
+    GTEST_SKIP();
+
+  EXPECT_TRUE(maximize_button->GetVisible());
+  EXPECT_TRUE(maximize_button->GetEnabled());
+}
+
+// Test that in non touch mode, the maximize button is enabled and not visible
+// for a maximized window.
+IN_PROC_BROWSER_TEST_F(GlassBrowserFrameViewTest,
+                       NonTouchMaximizedMaximizeButtonState) {
+  ui::TouchUiController::TouchUiScoperForTesting touch_ui_scoper_{false};
+  auto* glass_frame_view = GetGlassBrowserFrameView();
+  if (!glass_frame_view)
+    GTEST_SKIP();
+
+  glass_frame_view->frame()->Maximize();
+
+  static_cast<views::View*>(glass_frame_view)->Layout();
+  auto* maximize_button = GetMaximizeButton();
+  EXPECT_FALSE(maximize_button->GetVisible());
+  EXPECT_TRUE(maximize_button->GetEnabled());
+}
+
 class WebAppGlassBrowserFrameViewTest : public InProcessBrowserTest {
  public:
   WebAppGlassBrowserFrameViewTest() = default;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 06baad6..05644a9 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -1816,10 +1816,8 @@
 
   menu_contents->AddSeparator(ui::NORMAL_SEPARATOR);
 
-  menu_contents->AddItemWithStringId(
-      IDC_EDIT_SEARCH_ENGINES, OmniboxFieldTrial::IsActiveSearchEnginesEnabled()
-                                   ? IDS_MANAGE_SEARCH_ENGINES_AND_SITE_SEARCH
-                                   : IDS_MANAGE_SEARCH_ENGINES);
+  menu_contents->AddItemWithStringId(IDC_EDIT_SEARCH_ENGINES,
+                                     IDS_MANAGE_SEARCH_ENGINES_AND_SITE_SEARCH);
 
   const PrefService::Preference* show_full_urls_pref =
       location_bar_view_->profile()->GetPrefs()->FindPreference(
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 cb7b963..38704705 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
@@ -39,6 +39,10 @@
       model_->GetFontModel()->GetFontNameAt(new_choice));
 }
 
+ui::ComboboxModel* ReadAnythingController::GetFontComboboxModel() {
+  return static_cast<ui::ComboboxModel*>(model_->GetFontModel());
+}
+
 void ReadAnythingController::OnFontSizeChanged(bool increase) {
   if (increase) {
     model_->IncreaseTextSize();
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 19960ef..f047f83 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
@@ -11,12 +11,14 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
+#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h"
 #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "ui/accessibility/ax_node_id_forward.h"
 #include "ui/accessibility/ax_tree_update_forward.h"
+#include "ui/base/models/combobox_model.h"
 
 class Browser;
 
@@ -32,6 +34,7 @@
 //  as the browser.
 //
 class ReadAnythingController : public ReadAnythingToolbarView::Delegate,
+                               public ReadAnythingFontCombobox::Delegate,
                                public ReadAnythingPageHandler::Delegate,
                                public TabStripModelObserver,
                                public content::WebContentsObserver {
@@ -48,9 +51,12 @@
 
  private:
   // ReadAnythingToolbarView::Delegate:
-  void OnFontChoiceChanged(int new_choice) override;
   void OnFontSizeChanged(bool increase) override;
 
+  // ReadAnythingFontCombobox::Delegate:
+  void OnFontChoiceChanged(int new_choice) override;
+  ui::ComboboxModel* GetFontComboboxModel() override;
+
   // ReadAnythingPageHandler::Delegate:
   void OnUIReady() override;
 
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
index 10b29da..6f4c9ad 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
@@ -19,6 +19,7 @@
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/combobox_model.h"
 
 ReadAnythingCoordinator::ReadAnythingCoordinator(Browser* browser)
     : BrowserUserData<ReadAnythingCoordinator>(*browser) {
@@ -82,8 +83,10 @@
 
 std::unique_ptr<views::View> ReadAnythingCoordinator::CreateContainerView() {
   // Create the views.
-  auto toolbar =
-      std::make_unique<ReadAnythingToolbarView>(this, controller_.get());
+  auto toolbar = std::make_unique<ReadAnythingToolbarView>(
+      this,
+      /* ReadAnythingToolbarView::Delegate* = */ controller_.get(),
+      /* ReadAnythingFontCombobox::Delegate* = */ controller_.get());
 
   Browser* browser = &GetBrowser();
   auto content_web_view = std::make_unique<SidePanelWebUIViewT<ReadAnythingUI>>(
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.cc
new file mode 100644
index 0000000..76384927
--- /dev/null
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.cc
@@ -0,0 +1,57 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h"
+
+#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
+#include "ui/base/models/combobox_model.h"
+#include "ui/base/models/image_model.h"
+#include "ui/base/models/menu_model.h"
+#include "ui/views/controls/combobox/combobox_menu_model.h"
+
+// Adapts a ui::ComboboxModel for Read Anything.
+class ReadAnythingFontCombobox::MenuModel : public ComboboxMenuModel {
+ public:
+  MenuModel(Combobox* owner, ui::ComboboxModel* model)
+      : ComboboxMenuModel(owner, model) {}
+  MenuModel(const MenuModel&) = delete;
+  MenuModel& operator&(const MenuModel&) = delete;
+  ~MenuModel() override = default;
+
+  // Overridden from ComboboxMenuModel:
+ private:
+  // The Read Anything font combobox will not have icons on any platform.
+  bool HasIcons() const override { return false; }
+
+  // The Read Anything font combobox will use a different FontList for each
+  // item in the menu. This will give a preview of the font to the user.
+  const gfx::FontList* GetLabelFontListAt(int index) const override {
+    return new gfx::FontList(static_cast<ReadAnythingFontModel*>(GetModel())
+                                 ->GetLabelFontListAt(index));
+  }
+};
+
+ReadAnythingFontCombobox::ReadAnythingFontCombobox(
+    ReadAnythingFontCombobox::Delegate* delegate)
+    : Combobox(std::move(delegate->GetFontComboboxModel())),
+      delegate_(std::move(delegate)) {
+  // TODO(1266555): This is placeholder text, update for final UI.
+  SetTooltipTextAndAccessibleName(u"Font Choice");
+
+  SetCallback(
+      base::BindRepeating(&ReadAnythingFontCombobox::FontNameChangedCallback,
+                          weak_pointer_factory_.GetWeakPtr()));
+
+  std::unique_ptr<ComboboxMenuModel> new_model =
+      std::make_unique<MenuModel>(this, GetModel());
+
+  SetMenuModel(std::move(new_model));
+}
+
+void ReadAnythingFontCombobox::FontNameChangedCallback() {
+  if (delegate_)
+    delegate_->OnFontChoiceChanged(GetSelectedIndex());
+}
+
+ReadAnythingFontCombobox::~ReadAnythingFontCombobox() = default;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h
new file mode 100644
index 0000000..bad6b4e
--- /dev/null
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_FONT_COMBOBOX_H_
+#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_FONT_COMBOBOX_H_
+
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/base/models/combobox_model.h"
+#include "ui/views/controls/combobox/combobox.h"
+
+class ReadAnythingFontCombobox : public views::Combobox {
+ public:
+  class Delegate {
+   public:
+    virtual void OnFontChoiceChanged(int new_choice) = 0;
+    virtual ui::ComboboxModel* GetFontComboboxModel() = 0;
+  };
+
+  explicit ReadAnythingFontCombobox(
+      ReadAnythingFontCombobox::Delegate* delegate);
+  ReadAnythingFontCombobox(const ReadAnythingFontCombobox&) = delete;
+  ReadAnythingFontCombobox& operator=(const ReadAnythingFontCombobox&) = delete;
+  ~ReadAnythingFontCombobox() override;
+
+ private:
+  class MenuModel;
+
+  void FontNameChangedCallback();
+
+  raw_ptr<ReadAnythingFontCombobox::Delegate> delegate_;
+
+  base::WeakPtrFactory<ReadAnythingFontCombobox> weak_pointer_factory_{this};
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_FONT_COMBOBOX_H_
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 75ee82b..aee99f4 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
@@ -9,6 +9,7 @@
 
 #include "base/check.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 
 ReadAnythingModel::ReadAnythingModel(std::string prefs_font_name)
@@ -86,11 +87,14 @@
 ReadAnythingFontModel::ReadAnythingFontModel() {
   // TODO(1266555): Replace these with proper versions once finalized.
   font_choices_.emplace_back(u"Standard font");
-  font_choices_.emplace_back(u"Sans-serif");
+  font_choices_.emplace_back(u"Sans");
   font_choices_.emplace_back(u"Serif");
   font_choices_.emplace_back(u"Arial");
-  font_choices_.emplace_back(u"Open Sans");
-  font_choices_.emplace_back(u"Calibri");
+  font_choices_.emplace_back(u"Roboto");
+  font_choices_.emplace_back(u"Courier New");
+  font_choices_.emplace_back(u"Comic Sans MS");
+  font_choices_.emplace_back(u"Webdings");
+  font_choices_.emplace_back(u"Impact");
   font_choices_.shrink_to_fit();
 }
 
@@ -133,4 +137,17 @@
   return base::UTF16ToUTF8(font_choices_.at(index));
 }
 
+// This method uses the text from the drop down at |index| and creates the
+// string that will be sent to the UI to use in the CSS for the panel.
+// This text is not visible to the user.
+// We append 'Arial' and '18px' to have a back-up font and a set size in case
+// the chosen font does not work for some reason.
+// E.g. User chooses 'Roboto', this method returns 'Roboto, Arial, 18px'.
+// TODO(1266555): Finalize font choices and approach with UI/UX.
+std::string ReadAnythingFontModel::GetLabelFontListAt(int index) {
+  std::string font_label = base::UTF16ToUTF8(GetDropDownTextAt(index));
+  base::StringAppendF(&font_label, "%s", ", Arial, 18px");
+  return font_label;
+}
+
 ReadAnythingFontModel::~ReadAnythingFontModel() = default;
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 ed9c4e0..815b8fcf 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
@@ -34,6 +34,7 @@
   bool IsValidFontName(const std::string& font_name);
   bool IsValidFontIndex(int index);
   void SetDefaultIndexFromPrefsFontName(std::string prefs_font_name);
+  std::string GetLabelFontListAt(int index);
 
  protected:
   // ui::Combobox implementation:
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 fd9a280f..b41f7e5 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
@@ -119,19 +119,25 @@
 
 TEST_F(ReadAnythingModelTest, FontModelIsValidFontName) {
   EXPECT_TRUE(GetFontModel()->IsValidFontName("Standard font"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Sans-serif"));
+  EXPECT_TRUE(GetFontModel()->IsValidFontName("Sans"));
   EXPECT_TRUE(GetFontModel()->IsValidFontName("Serif"));
   EXPECT_TRUE(GetFontModel()->IsValidFontName("Arial"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Open Sans"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Calibri"));
+  EXPECT_TRUE(GetFontModel()->IsValidFontName("Roboto"));
+  EXPECT_TRUE(GetFontModel()->IsValidFontName("Courier New"));
+  EXPECT_TRUE(GetFontModel()->IsValidFontName("Comic Sans MS"));
+  EXPECT_TRUE(GetFontModel()->IsValidFontName("Webdings"));
+  EXPECT_TRUE(GetFontModel()->IsValidFontName("Impact"));
   EXPECT_FALSE(GetFontModel()->IsValidFontName("xxyyzz"));
 }
 
 TEST_F(ReadAnythingModelTest, FontModelGetCurrentFontName) {
   EXPECT_EQ("Standard font", GetFontModel()->GetFontNameAt(0));
-  EXPECT_EQ("Sans-serif", GetFontModel()->GetFontNameAt(1));
+  EXPECT_EQ("Sans", GetFontModel()->GetFontNameAt(1));
   EXPECT_EQ("Serif", GetFontModel()->GetFontNameAt(2));
   EXPECT_EQ("Arial", GetFontModel()->GetFontNameAt(3));
-  EXPECT_EQ("Open Sans", GetFontModel()->GetFontNameAt(4));
-  EXPECT_EQ("Calibri", GetFontModel()->GetFontNameAt(5));
+  EXPECT_EQ("Roboto", GetFontModel()->GetFontNameAt(4));
+  EXPECT_EQ("Courier New", GetFontModel()->GetFontNameAt(5));
+  EXPECT_EQ("Comic Sans MS", GetFontModel()->GetFontNameAt(6));
+  EXPECT_EQ("Webdings", GetFontModel()->GetFontNameAt(7));
+  EXPECT_EQ("Impact", GetFontModel()->GetFontNameAt(8));
 }
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 aab2e958..c1f82d9 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
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_constants.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
 #include "components/vector_icons/cc_macros.h"
 #include "components/vector_icons/vector_icons.h"
 #include "ui/color/color_id.h"
@@ -26,10 +25,10 @@
 
 ReadAnythingToolbarView::ReadAnythingToolbarView(
     ReadAnythingCoordinator* coordinator,
-    ReadAnythingToolbarView::Delegate* delegate)
-    : delegate_(delegate), coordinator_(std::move(coordinator)) {
+    ReadAnythingToolbarView::Delegate* toolbar_delegate,
+    ReadAnythingFontCombobox::Delegate* font_combobox_delegate)
+    : delegate_(toolbar_delegate), coordinator_(std::move(coordinator)) {
   coordinator_->AddObserver(this);
-  auto* font_model = coordinator_->GetModel()->GetFontModel();
 
   // Create and set a BoxLayout LayoutManager for this view.
   auto layout = std::make_unique<views::BoxLayout>(
@@ -42,14 +41,8 @@
   SetLayoutManager(std::move(layout));
 
   // Create a font selection combobox for the toolbar.
-  auto combobox = std::make_unique<views::Combobox>();
-  combobox->SetCallback(
-      base::BindRepeating(&ReadAnythingToolbarView::FontNameChangedCallback,
-                          weak_pointer_factory_.GetWeakPtr()));
-  combobox->SetSizeToLargestLabel(true);
-  // TODO(1266555): This is placeholder text, remove for final UI.
-  combobox->SetTooltipTextAndAccessibleName(u"Font Choice");
-  combobox->SetModel(font_model);
+  auto combobox =
+      std::make_unique<ReadAnythingFontCombobox>(font_combobox_delegate);
 
   // Create the decrease/increase text size buttons.
   // TODO(1266555): These use placeholder text, update for final UI.
@@ -75,11 +68,6 @@
   AddChildView(Separator());
 }
 
-void ReadAnythingToolbarView::FontNameChangedCallback() {
-  if (delegate_)
-    delegate_->OnFontChoiceChanged(font_combobox_->GetSelectedIndex());
-}
-
 void ReadAnythingToolbarView::DecreaseFontSizeCallback() {
   if (delegate_)
     delegate_->OnFontSizeChanged(/* increase = */ false);
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 b1668b8..3b86c64 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
@@ -9,6 +9,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
+#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h"
 #include "ui/base/models/combobox_model.h"
 #include "ui/views/controls/combobox/combobox.h"
 #include "ui/views/view.h"
@@ -25,12 +26,13 @@
  public:
   class Delegate {
    public:
-    virtual void OnFontChoiceChanged(int new_choice) = 0;
     virtual void OnFontSizeChanged(bool increase) = 0;
   };
 
-  ReadAnythingToolbarView(ReadAnythingCoordinator* coordinator,
-                          ReadAnythingToolbarView::Delegate* delegate);
+  ReadAnythingToolbarView(
+      ReadAnythingCoordinator* coordinator,
+      ReadAnythingToolbarView::Delegate* toolbar_delegate,
+      ReadAnythingFontCombobox::Delegate* font_combobox_delegate);
   ReadAnythingToolbarView(const ReadAnythingToolbarView&) = delete;
   ReadAnythingToolbarView& operator=(const ReadAnythingToolbarView&) = delete;
   ~ReadAnythingToolbarView() override;
@@ -41,7 +43,6 @@
  private:
   friend class ReadAnythingToolbarViewTest;
 
-  void FontNameChangedCallback();
   void DecreaseFontSizeCallback();
   void IncreaseFontSizeCallback();
 
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 b551f29..a7ce10d 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
@@ -16,10 +16,16 @@
 class MockReadAnythingToolbarViewDelegate
     : public ReadAnythingToolbarView::Delegate {
  public:
-  MOCK_METHOD(void, OnFontChoiceChanged, (int new_choice), (override));
   MOCK_METHOD(void, OnFontSizeChanged, (bool increase), (override));
 };
 
+class MockReadAnythingFontComboboxDelegate
+    : public ReadAnythingFontCombobox::Delegate {
+ public:
+  MOCK_METHOD(void, OnFontChoiceChanged, (int new_choice), (override));
+  MOCK_METHOD(ui::ComboboxModel*, GetFontComboboxModel, (), (override));
+};
+
 class MockReadAnythingCoordinator : public ReadAnythingCoordinator {
  public:
   explicit MockReadAnythingCoordinator(Browser* browser)
@@ -48,44 +54,36 @@
     coordinator_ = std::make_unique<MockReadAnythingCoordinator>(browser());
 
     toolbar_view_ = std::make_unique<ReadAnythingToolbarView>(
-        coordinator_.get(), &delegate_);
+        coordinator_.get(), &toolbar_delegate_, &font_combobox_delegate_);
   }
 
   void TearDownOnMainThread() override { coordinator_ = nullptr; }
 
   // Wrapper methods around the ReadAnythingToolbarView.
 
-  void FontNameChangedCallback() { toolbar_view_->FontNameChangedCallback(); }
-
   void DecreaseFontSizeCallback() { toolbar_view_->DecreaseFontSizeCallback(); }
 
   void IncreaseFontSizeCallback() { toolbar_view_->IncreaseFontSizeCallback(); }
 
  protected:
-  MockReadAnythingToolbarViewDelegate delegate_;
+  MockReadAnythingToolbarViewDelegate toolbar_delegate_;
+  MockReadAnythingFontComboboxDelegate font_combobox_delegate_;
 
  private:
   std::unique_ptr<ReadAnythingToolbarView> toolbar_view_;
   std::unique_ptr<MockReadAnythingCoordinator> coordinator_;
 };
 
-IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, FontNameChanged) {
-  EXPECT_CALL(delegate_, OnFontChoiceChanged(_)).Times(1);
-  EXPECT_CALL(delegate_, OnFontSizeChanged(_)).Times(0);
-
-  FontNameChangedCallback();
-}
-
-IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, DecreaseTextSizeClicked) {
-  EXPECT_CALL(delegate_, OnFontChoiceChanged(_)).Times(0);
-  EXPECT_CALL(delegate_, OnFontSizeChanged(IsFalse())).Times(1);
+IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, DecreaseFontSizeCallback) {
+  EXPECT_CALL(toolbar_delegate_, OnFontSizeChanged(false)).Times(1);
+  EXPECT_CALL(toolbar_delegate_, OnFontSizeChanged(true)).Times(0);
 
   DecreaseFontSizeCallback();
 }
 
-IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, IncreaseTextSizeClicked) {
-  EXPECT_CALL(delegate_, OnFontChoiceChanged(_)).Times(0);
-  EXPECT_CALL(delegate_, OnFontSizeChanged(IsTrue())).Times(1);
+IN_PROC_BROWSER_TEST_F(ReadAnythingToolbarViewTest, IncreaseFontSizeCallback) {
+  EXPECT_CALL(toolbar_delegate_, OnFontSizeChanged(false)).Times(0);
+  EXPECT_CALL(toolbar_delegate_, OnFontSizeChanged(true)).Times(1);
 
   IncreaseFontSizeCallback();
 }
diff --git a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
index b0c2db7..8115b24 100644
--- a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
+++ b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/check.h"
+#include "base/feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/autofill/payments/webauthn_dialog_model.h"
 #include "chrome/browser/ui/views/webauthn/authenticator_bio_enrollment_sheet_view.h"
@@ -19,6 +20,7 @@
 #include "chrome/browser/ui/webauthn/sheet_models.h"
 #include "chrome/browser/ui/webauthn/transport_hover_list_model.h"
 #include "chrome/browser/webauthn/authenticator_request_dialog_model.h"
+#include "device/fido/features.h"
 #include "ui/gfx/paint_vector_icon.h"
 
 namespace {
@@ -210,7 +212,17 @@
       break;
     case Step::kSelectAccount:
       sheet_view = std::make_unique<AuthenticatorSelectAccountSheetView>(
-          std::make_unique<AuthenticatorSelectAccountSheetModel>(dialog_model));
+          std::make_unique<AuthenticatorSelectAccountSheetModel>(
+              dialog_model,
+              AuthenticatorSelectAccountSheetModel::kPostUserVerification));
+      break;
+    case Step::kPreSelectAccount:
+      DCHECK(base::FeatureList::IsEnabled(
+          device::kWebAuthnNewDiscoverableCredentialsUi));
+      sheet_view = std::make_unique<AuthenticatorSelectAccountSheetView>(
+          std::make_unique<AuthenticatorSelectAccountSheetModel>(
+              dialog_model,
+              AuthenticatorSelectAccountSheetModel::kPreUserVerification));
       break;
     case Step::kAttestationPermissionRequest:
       sheet_view = std::make_unique<AuthenticatorRequestSheetView>(
diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc
index 01c11a8cf..e7dc7742 100644
--- a/chrome/browser/ui/webauthn/sheet_models.cc
+++ b/chrome/browser/ui/webauthn/sheet_models.cc
@@ -1173,8 +1173,9 @@
 // AuthenticatorSelectAccountSheetModel ---------------------------------------
 
 AuthenticatorSelectAccountSheetModel::AuthenticatorSelectAccountSheetModel(
-    AuthenticatorRequestDialogModel* dialog_model)
-    : AuthenticatorSheetModelBase(dialog_model) {}
+    AuthenticatorRequestDialogModel* dialog_model,
+    Mode mode)
+    : AuthenticatorSheetModelBase(dialog_model), mode_(mode) {}
 
 AuthenticatorSelectAccountSheetModel::~AuthenticatorSelectAccountSheetModel() =
     default;
@@ -1186,7 +1187,14 @@
 }
 
 void AuthenticatorSelectAccountSheetModel::OnAccept() {
-  dialog_model()->OnAccountSelected(selected_);
+  switch (mode_) {
+    case kPreUserVerification:
+      dialog_model()->OnAccountPreselectedIndex(selected_);
+      break;
+    case kPostUserVerification:
+      dialog_model()->OnAccountSelected(selected_);
+      break;
+  }
 }
 
 const gfx::VectorIcon&
diff --git a/chrome/browser/ui/webauthn/sheet_models.h b/chrome/browser/ui/webauthn/sheet_models.h
index 212ed23..321a8388 100644
--- a/chrome/browser/ui/webauthn/sheet_models.h
+++ b/chrome/browser/ui/webauthn/sheet_models.h
@@ -481,8 +481,18 @@
 class AuthenticatorSelectAccountSheetModel
     : public AuthenticatorSheetModelBase {
  public:
-  explicit AuthenticatorSelectAccountSheetModel(
-      AuthenticatorRequestDialogModel* dialog_model);
+  // Indicates whether the corresponding view is presented before or after
+  // gathering user verification and generating an assertion signature.
+  // `kPreUserVerification` is only possible with platform authenticators
+  // for which we can silently enumerate credentials.
+  enum Mode {
+    kPostUserVerification,
+    kPreUserVerification,
+  };
+
+  AuthenticatorSelectAccountSheetModel(
+      AuthenticatorRequestDialogModel* dialog_model,
+      Mode mode);
   ~AuthenticatorSelectAccountSheetModel() override;
 
   // Set the index of the currently selected row.
@@ -501,6 +511,7 @@
   bool IsAcceptButtonEnabled() const override;
   std::u16string GetAcceptButtonLabel() const override;
 
+  const Mode mode_;
   size_t selected_ = 0;
 };
 
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 7a3756ec..34190651 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -1549,6 +1549,7 @@
       GURL(chrome::kOsUIAddSupervisionURL),
       GURL(chrome::kChromeUIAppDisabledURL),
       GURL(chrome::kOsUIAppDisabledURL),
+      GURL(chrome::kOsUIAppServiceInternalsURL),
       GURL(chrome::kChromeUIArcGraphicsTracingURL),
       GURL(chrome::kChromeUIArcOverviewTracingURL),
       GURL(chrome::kChromeUIArcPowerControlURL),
diff --git a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc
index 338e23c..bd6dca5 100644
--- a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc
@@ -11,40 +11,15 @@
 
 namespace chromeos {
 
-constexpr StaticOobeScreenId WrongHWIDScreenView::kScreenId;
-
 WrongHWIDScreenHandler::WrongHWIDScreenHandler()
-    : BaseScreenHandler(kScreenId) {
-  set_user_acted_method_path_deprecated(
-      "login.WrongHWIDMessageScreen.userActed");
-}
+    : BaseScreenHandler(kScreenId) {}
 
-WrongHWIDScreenHandler::~WrongHWIDScreenHandler() {
-  if (screen_)
-    screen_->OnViewDestroyed(this);
-}
+WrongHWIDScreenHandler::~WrongHWIDScreenHandler() = default;
 
 void WrongHWIDScreenHandler::Show() {
-  if (!IsJavascriptAllowed()) {
-    show_on_init_ = true;
-    return;
-  }
   ShowInWebUI();
 }
 
-void WrongHWIDScreenHandler::Hide() {
-}
-
-void WrongHWIDScreenHandler::Bind(WrongHWIDScreen* screen) {
-  screen_ = screen;
-  BaseScreenHandler::SetBaseScreenDeprecated(screen_);
-}
-
-void WrongHWIDScreenHandler::Unbind() {
-  screen_ = nullptr;
-  BaseScreenHandler::SetBaseScreenDeprecated(nullptr);
-}
-
 void WrongHWIDScreenHandler::DeclareLocalizedValues(
     ::login::LocalizedValuesBuilder* builder) {
   builder->Add("wrongHWIDScreenHeader", IDS_WRONG_HWID_SCREEN_HEADER);
@@ -56,11 +31,4 @@
                 IDS_WRONG_HWID_SCREEN_SKIP_LINK);
 }
 
-void WrongHWIDScreenHandler::InitializeDeprecated() {
-  if (show_on_init_) {
-    show_on_init_ = false;
-    Show();
-  }
-}
-
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h
index e67880c..f078801 100644
--- a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h
@@ -5,30 +5,21 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WRONG_HWID_SCREEN_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WRONG_HWID_SCREEN_HANDLER_H_
 
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace ash {
-class WrongHWIDScreen;
-}
-
 namespace chromeos {
 
 // Interface between wrong HWID screen and its representation.
 // Note, do not forget to call OnViewDestroyed in the dtor.
-class WrongHWIDScreenView {
+class WrongHWIDScreenView : public base::SupportsWeakPtr<WrongHWIDScreenView> {
  public:
-  constexpr static StaticOobeScreenId kScreenId{"wrong-hwid"};
+  inline constexpr static StaticOobeScreenId kScreenId{
+      "wrong-hwid", "WrongHWIDMessageScreen"};
 
-  virtual ~WrongHWIDScreenView() {}
+  virtual ~WrongHWIDScreenView() = default;
 
   virtual void Show() = 0;
-  virtual void Hide() = 0;
-
-  // Binds `screen` to the view.
-  virtual void Bind(ash::WrongHWIDScreen* screen) = 0;
-
-  // Unbinds the screen from the view.
-  virtual void Unbind() = 0;
 };
 
 // WebUI implementation of WrongHWIDScreenActor.
@@ -47,19 +38,10 @@
  private:
   // WrongHWIDScreenActor implementation:
   void Show() override;
-  void Hide() override;
-  void Bind(ash::WrongHWIDScreen* screen) override;
-  void Unbind() override;
 
   // BaseScreenHandler implementation:
   void DeclareLocalizedValues(
       ::login::LocalizedValuesBuilder* builder) override;
-  void InitializeDeprecated() override;
-
-  ash::WrongHWIDScreen* screen_ = nullptr;
-
-  // Keeps whether screen should be shown right after initialization.
-  bool show_on_init_ = false;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/ash/search/search_handler.cc b/chrome/browser/ui/webui/settings/ash/search/search_handler.cc
index 65b6b7b6..889a416 100644
--- a/chrome/browser/ui/webui/settings/ash/search/search_handler.cc
+++ b/chrome/browser/ui/webui/settings/ash/search/search_handler.cc
@@ -18,12 +18,8 @@
 
 namespace chromeos {
 namespace settings {
-
 namespace {
 
-// TODO(https://crbug.com/1164001): remove after migrating this file to ns ash.
-namespace local_search_service = ::ash::local_search_service;
-
 bool ContainsSectionResult(const std::vector<mojom::SearchResultPtr>& results,
                            mojom::Section section) {
   return std::find_if(
diff --git a/chrome/browser/ui/webui/settings/ash/search/search_handler.h b/chrome/browser/ui/webui/settings/ash/search/search_handler.h
index 998910a..fd7722d7 100644
--- a/chrome/browser/ui/webui/settings/ash/search/search_handler.h
+++ b/chrome/browser/ui/webui/settings/ash/search/search_handler.h
@@ -107,7 +107,7 @@
   SearchTagRegistry* search_tag_registry_;
   OsSettingsSections* sections_;
   Hierarchy* hierarchy_;
-  mojo::Remote<ash::local_search_service::mojom::Index> index_remote_;
+  mojo::Remote<local_search_service::mojom::Index> index_remote_;
 
   // Note: Expected to have multiple clients, so ReceiverSet/RemoteSet are used.
   mojo::ReceiverSet<mojom::SearchHandler> receivers_;
diff --git a/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.cc b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.cc
index 6793903f..44c862d 100644
--- a/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.cc
+++ b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.cc
@@ -16,12 +16,8 @@
 
 namespace chromeos {
 namespace settings {
-
 namespace {
 
-// TODO(https://crbug.com/1164001): remove after migrating this file to ns ash.
-namespace local_search_service = ::ash::local_search_service;
-
 std::vector<int> GetMessageIds(const SearchConcept* search_concept) {
   // Start with only the canonical ID.
   std::vector<int> alt_tag_message_ids{search_concept->canonical_message_id};
diff --git a/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h
index b8fec37..4c8568e 100644
--- a/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h
+++ b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h
@@ -60,8 +60,8 @@
     std::unordered_map<std::string, ConceptWithShouldAddBool> pending_updates_;
   };
 
-  explicit SearchTagRegistry(local_search_service::LocalSearchServiceProxy*
-                                 local_search_service_proxy);
+  SearchTagRegistry(local_search_service::LocalSearchServiceProxy*
+                        local_search_service_proxy);
   SearchTagRegistry(const SearchTagRegistry& other) = delete;
   SearchTagRegistry& operator=(const SearchTagRegistry& other) = delete;
   virtual ~SearchTagRegistry();
@@ -94,7 +94,7 @@
   void NotifyRegistryDeleted(uint32_t /*num_deleted*/);
 
   // Index used by the LocalSearchService for string matching.
-  mojo::Remote<ash::local_search_service::mojom::Index> index_remote_;
+  mojo::Remote<local_search_service::mojom::Index> index_remote_;
 
   // In-memory cache of all results which have been added to the
   // LocalSearchService. Contents are kept in sync with |index_remote_|.
diff --git a/chrome/browser/ui/webui/settings/ash/search/search_tag_registry_unittest.cc b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry_unittest.cc
index 8813031..bb47722b 100644
--- a/chrome/browser/ui/webui/settings/ash/search/search_tag_registry_unittest.cc
+++ b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry_unittest.cc
@@ -15,12 +15,8 @@
 
 namespace chromeos {
 namespace settings {
-
 namespace {
 
-// TODO(https://crbug.com/1164001): remove after migrating this file to ns ash.
-namespace local_search_service = ::ash::local_search_service;
-
 class FakeObserver : public SearchTagRegistry::Observer {
  public:
   FakeObserver() = default;
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
index 687cfcd5..6edefc12 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
@@ -20,8 +20,6 @@
 #include "chrome/browser/ash/kerberos/kerberos_credentials_manager.h"
 // TODO(https://crbug.com/1164001): forward declare when moved ash
 #include "chrome/browser/ash/printing/cups_printers_manager.h"
-// TODO(https://crbug.com/1164001): forward declare when moved ash
-#include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 class ArcAppListPrefs;
@@ -41,7 +39,13 @@
 class SyncService;
 }  // namespace syncer
 
-namespace chromeos::settings {
+namespace chromeos {
+
+namespace local_search_service {
+class LocalSearchServiceProxy;
+}  // namespace local_search_service
+
+namespace settings {
 
 class Hierarchy;
 class OsSettingsSections;
@@ -131,6 +135,7 @@
   std::unique_ptr<AppNotificationHandler> app_notification_handler_;
 };
 
-}  // namespace chromeos::settings
+}  // namespace settings
+}  // namespace chromeos
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_MANAGER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
index a5e3a480..2cd73306 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
@@ -25,8 +25,6 @@
 namespace chromeos {
 namespace settings {
 
-namespace local_search_service = ::ash::local_search_service;
-
 // static
 OsSettingsManager* OsSettingsManagerFactory::GetForProfile(Profile* profile) {
   return static_cast<OsSettingsManager*>(
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
index e909d5e..01ca9f23 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
@@ -35,8 +35,6 @@
 namespace chromeos {
 namespace settings {
 
-namespace local_search_service = ::ash::local_search_service;
-
 // Verifies the OsSettingsManager initialization flow. Behavioral functionality
 // is tested via unit tests on the sub-elements owned by OsSettingsManager.
 class OsSettingsManagerTest : public testing::Test {
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 0f7583d..20fe6e4 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -2028,9 +2028,8 @@
        IDS_SETTINGS_SEARCH_ENGINES_ADDITIONAL_EXTENSIONS},
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
-  html_source->AddBoolean(
-      "isActiveSearchEnginesFlagEnabled",
-      base::FeatureList::IsEnabled(omnibox::kActiveSearchEngines));
+  // TODO(crbug.com/1340259): Remove this and cleanup front-end code.
+  html_source->AddBoolean("isActiveSearchEnginesFlagEnabled", true);
 }
 
 void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
diff --git a/chrome/browser/unified_consent/unified_consent_browsertest.cc b/chrome/browser/unified_consent/unified_consent_browsertest.cc
index 368a7425..2b4f672 100644
--- a/chrome/browser/unified_consent/unified_consent_browsertest.cc
+++ b/chrome/browser/unified_consent/unified_consent_browsertest.cc
@@ -86,12 +86,6 @@
     UnifiedConsentBrowserTest,
     PRE_SettingsHistogram_UrlKeyedAnonymizedDataCollectionEnabled) {
   EnableSync(0);
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // Lacros only supports syncing profiles for now.
-  // TODO(https://crbug.com/1260291): Revisit this once non-syncing profiles
-  // are allowed.
-  EnableSync(1);
-#endif
   consent_service()->SetUrlKeyedAnonymizedDataCollectionEnabled(true);
 }
 
diff --git a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
index 8d342b8..59383c9a 100644
--- a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
+++ b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
@@ -53,6 +53,7 @@
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
+#include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
 #include "components/webapps/browser/install_result_code.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
@@ -491,7 +492,7 @@
   navigation_observer.StartWatchingNewWebContents();
   auto launch_params = crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id;
-  launch_params->launch_source = apps::mojom::LaunchSource::kFromTest;
+  launch_params->launch_source = apps::LaunchSource::kFromTest;
   lacros_web_apps_controller.Launch(std::move(launch_params),
                                     base::DoNothing());
   navigation_observer.Wait();
@@ -516,7 +517,7 @@
   navigation_observer.StartWatchingNewWebContents();
   auto launch_params = crosapi::mojom::LaunchParams::New();
   launch_params->app_id = app_id;
-  launch_params->launch_source = apps::mojom::LaunchSource::kFromTest;
+  launch_params->launch_source = apps::LaunchSource::kFromTest;
   launch_params->intent = crosapi::mojom::Intent::New();
   launch_params->intent->action = apps_util::kIntentActionView;
   launch_params->intent->activity_name = launch_url.spec();
diff --git a/chrome/browser/web_applications/web_app_icon_manager.cc b/chrome/browser/web_applications/web_app_icon_manager.cc
index f528a8a..b6099ac 100644
--- a/chrome/browser/web_applications/web_app_icon_manager.cc
+++ b/chrome/browser/web_applications/web_app_icon_manager.cc
@@ -796,6 +796,11 @@
                                   const SortedSizesPx& icon_sizes,
                                   ReadIconsCallback callback) const {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  if (!registrar_->GetAppById(app_id)) {
+    std::move(callback).Run(std::map<SquareSizePx, SkBitmap>());
+    return;
+  }
   DCHECK(HasIcons(app_id, purpose, icon_sizes));
 
   icon_task_runner_->PostTaskAndReplyWithResult(
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
index 043932c..d5185c7 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/containers/contains.h"
+#include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/observer_list.h"
 #include "base/process/launch.h"
@@ -367,6 +368,19 @@
       SetCurrentStep(Step::kErrorInternalUnrecognized);
       return;
     }
+
+    // For empty allow list requests, let the user select one of the silently
+    // enumerated credentials before dispatching to the platform authenticator.
+    if (base::FeatureList::IsEnabled(
+            device::kWebAuthnNewDiscoverableCredentialsUi) &&
+        transport_availability_.has_empty_allow_list &&
+        !transport_availability_.recognized_platform_authenticator_credentials
+             .empty()) {
+      ephemeral_state_.creds_ =
+          transport_availability_.recognized_platform_authenticator_credentials;
+      SetCurrentStep(Step::kPreSelectAccount);
+      return;
+    }
   }
 
   if (transport_availability_.request_type ==
@@ -651,20 +665,31 @@
 }
 
 void AuthenticatorRequestDialogModel::OnAccountPreselected(
-    const std::vector<uint8_t>& id) {
-  for (const auto& cred : creds()) {
-    if (cred.user.id == id) {
-      account_preselected_callback_.Run(cred.cred_id);
-      ephemeral_state_.creds_.clear();
-      if (transport_availability()->has_win_native_api_authenticator) {
-        HideDialogAndDispatchToNativeWindowsApi();
-      } else {
-        HideDialogAndDispatchToPlatformAuthenticator();
-      }
+    const std::vector<uint8_t>& credential_id) {
+  for (size_t i = 0; i < creds().size(); ++i) {
+    if (creds().at(i).cred_id == credential_id) {
+      OnAccountPreselectedIndex(i);
       return;
     }
   }
-  NOTREACHED();
+  NOTREACHED() << "OnAccountPreselected() called with unknown credential_id "
+               << base::HexEncode(credential_id);
+}
+
+void AuthenticatorRequestDialogModel::OnAccountPreselectedIndex(size_t index) {
+  // User selected one of the platform authenticator credentials enumerated in
+  // Conditional or regular modal UI prior to collecting user verification.
+  // Run `account_preselected_callback_` to narrow the request to the selected
+  // credential and dispatch to the platform authenticator.
+  const device::DiscoverableCredentialMetadata& cred = creds().at(index);
+  DCHECK(account_preselected_callback_);
+  account_preselected_callback_.Run(cred.cred_id);
+  ephemeral_state_.creds_.clear();
+  if (transport_availability()->has_win_native_api_authenticator) {
+    HideDialogAndDispatchToNativeWindowsApi();
+  } else {
+    HideDialogAndDispatchToPlatformAuthenticator();
+  }
 }
 
 void AuthenticatorRequestDialogModel::SetSelectedAuthenticatorForTesting(
@@ -952,11 +977,8 @@
 }
 
 void AuthenticatorRequestDialogModel::StartConditionalMediationRequest() {
-  ephemeral_state_.creds_ = {};
-  for (const auto& cred :
-       transport_availability_.recognized_platform_authenticator_credentials) {
-    ephemeral_state_.creds_.emplace_back(cred);
-  }
+  ephemeral_state_.creds_ =
+      transport_availability_.recognized_platform_authenticator_credentials;
 
   if (conditional_ui_user_list_callback_) {
     std::move(conditional_ui_user_list_callback_).Run(ephemeral_state_.creds_);
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h
index c37e24b..7125bdb 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.h
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -121,6 +121,7 @@
 
     // Account selection,
     kSelectAccount,
+    kPreSelectAccount,
 
     // Attestation permission requests.
     kAttestationPermissionRequest,
@@ -495,9 +496,15 @@
   // |responses()|.
   void OnAccountSelected(size_t index);
 
-  // Called when an account from |ephemeral_state_.creds_| is selected from the
-  // Conditional UI prompt.
-  void OnAccountPreselected(const std::vector<uint8_t>& id);
+  // OnAccountPreselected is called when the user selects a discoverable
+  // credential from a platform authenticator prior to providing user
+  // authentication. `crededential_id` must match one of the credentials in
+  // `creds()`.
+  void OnAccountPreselected(const std::vector<uint8_t>& credential_id);
+
+  // Like `OnAccountPreselected()`, but this takes an index into `creds()`
+  // instead of a credential ID.
+  void OnAccountPreselectedIndex(size_t index);
 
   void SetSelectedAuthenticatorForTesting(AuthenticatorReference authenticator);
 
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
index 5d14ce9..62d6f8a 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -784,7 +784,7 @@
 
   // After preselecting an account, the request should be dispatched to the
   // platform authenticator.
-  model.OnAccountPreselected({1, 2, 3, 4});
+  model.OnAccountPreselected(cred_1.cred_id);
   task_environment_.FastForwardUntilNoTasksRemain();
   EXPECT_EQ(preselect_num_called, 1);
   EXPECT_EQ(request_num_called, 1);
@@ -843,3 +843,60 @@
   model.RemoveObserver(&mock_observer);
 }
 #endif  // BUILDFLAG(IS_WIN)
+
+class AuthenticatorRequestDialogModelPreselectCredentialTest
+    : public AuthenticatorRequestDialogModelTest {
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_{
+      device::kWebAuthnNewDiscoverableCredentialsUi};
+};
+
+TEST_F(AuthenticatorRequestDialogModelPreselectCredentialTest,
+       PreSelectWithEmptyAllowList) {
+  AuthenticatorRequestDialogModel model(/*web_contents=*/nullptr);
+  int preselect_num_called = 0;
+  model.SetAccountPreselectedCallback(base::BindLambdaForTesting(
+      [&preselect_num_called](std::vector<uint8_t> credential_id) {
+        EXPECT_EQ(credential_id, std::vector<uint8_t>({0}));
+        ++preselect_num_called;
+      }));
+  int request_num_called = 0;
+  model.SetRequestCallback(base::BindLambdaForTesting(
+      [&request_num_called](const std::string& authenticator_id) {
+        EXPECT_EQ(authenticator_id, "internal-authenticator");
+        ++request_num_called;
+      }));
+
+  model.saved_authenticators().AddAuthenticator(
+      AuthenticatorReference(/*device_id=*/"usb-authenticator",
+                             AuthenticatorTransport::kUsbHumanInterfaceDevice));
+  model.saved_authenticators().AddAuthenticator(AuthenticatorReference(
+      /*device_id=*/"internal-authenticator",
+      AuthenticatorTransport::kInternal));
+
+  TransportAvailabilityInfo transports_info;
+  transports_info.request_type = device::FidoRequestType::kGetAssertion;
+  transports_info.available_transports = kAllTransports;
+  transports_info.has_empty_allow_list = true;
+  transports_info.has_platform_authenticator_credential = device::
+      FidoRequestHandlerBase::RecognizedCredential::kHasRecognizedCredential;
+  constexpr char kRpId[] = "example.com";
+  device::DiscoverableCredentialMetadata cred_1(
+      kRpId, {0}, device::PublicKeyCredentialUserEntity({1, 2, 3, 4}));
+  device::DiscoverableCredentialMetadata cred_2(
+      kRpId, {1}, device::PublicKeyCredentialUserEntity({5, 6, 7, 8}));
+  transports_info.recognized_platform_authenticator_credentials = {cred_1,
+                                                                   cred_2};
+  model.StartFlow(std::move(transports_info),
+                  /*is_conditional_mediation=*/false,
+                  /*prefer_native_api=*/false);
+  EXPECT_EQ(model.current_step(), Step::kPreSelectAccount);
+  EXPECT_EQ(request_num_called, 0);
+
+  // After preselecting an account, the request should be dispatched to the
+  // platform authenticator.
+  model.OnAccountPreselected(cred_1.cred_id);
+  task_environment_.FastForwardUntilNoTasksRemain();
+  EXPECT_EQ(preselect_num_called, 1);
+  EXPECT_EQ(request_num_called, 1);
+}
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index c8083f6..ed46050d 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -795,6 +795,12 @@
     return;
   }
 
+  if (g_observer) {
+    g_observer->AccountSelectorShown(responses);
+    std::move(callback).Run(std::move(responses.at(0)));
+    return;
+  }
+
   dialog_model_->SelectAccount(std::move(responses), std::move(callback));
 }
 
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
index 5c85e8c7..e8717dd3 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -116,6 +116,10 @@
         base::span<const uint8_t> experiments,
         AuthenticatorRequestDialogModel::ExperimentServerLinkSheet,
         AuthenticatorRequestDialogModel::ExperimentServerLinkTitle) = 0;
+
+    virtual void AccountSelectorShown(
+        const std::vector<device::AuthenticatorGetAssertionResponse>&
+            responses) {}
   };
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
diff --git a/chrome/browser/webauthn/chrome_webauthn_browsertest.cc b/chrome/browser/webauthn/chrome_webauthn_browsertest.cc
index 365cc5a..8a7062e7 100644
--- a/chrome/browser/webauthn/chrome_webauthn_browsertest.cc
+++ b/chrome/browser/webauthn/chrome_webauthn_browsertest.cc
@@ -196,7 +196,16 @@
         AuthenticatorRequestDialogModel::ExperimentServerLinkTitle exp_title)
         override {}
 
+    void AccountSelectorShown(
+        const std::vector<device::AuthenticatorGetAssertionResponse>& responses)
+        override {
+      for (const auto& response : responses) {
+        accounts_.emplace_back(base::HexEncode(response.credential->id));
+      }
+    }
+
     raw_ptr<ChromeAuthenticatorRequestDelegate> delegate_ = nullptr;
+    std::vector<std::string> accounts_;
 
    private:
     State state_ = kHasNotShowedUI;
@@ -279,6 +288,8 @@
   std::string result;
   ASSERT_TRUE(message_queue.WaitForMessage(&result));
   EXPECT_EQ(result, "\"webauthn: OK\"");
+  EXPECT_EQ(observer_->accounts_.size(), 1u);
+  EXPECT_EQ(observer_->accounts_.at(0), "01020304");
 }
 
 // WebAuthnCableExtension exercises code paths where a server sends a caBLEv2
@@ -652,7 +663,6 @@
 
     void UIShown(ChromeAuthenticatorRequestDelegate* delegate) override {
       parent_->model() = delegate->dialog_model();
-      LOG(ERROR) << static_cast<void*>(parent_->model());
 
       for (const auto& name : parent_->model()->paired_phone_names()) {
         parent_->trace() << "UINAME: " << name << std::endl;
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 035f2cc..b781c73 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1657562389-472f956ec6c7d4ffbfd747ceda9a6bf3abef291d.profdata
+chrome-linux-main-1657605582-b379c8e4a10b0b2b4c2de7014afcfe8fc3522c96.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index cb8b761..ac2cfd6b0 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1657562389-aeaa8927d590d2fae34b96efcdf7fddb896bfcb5.profdata
+chrome-mac-arm-main-1657583981-c7c49cb23b569bccbeec8d4935e8f120de589acf.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 6a3394a..4a4a02d0 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1657562389-a4a592b96e8b5ff3b7954c36212b45a9d8e0b2d6.profdata
+chrome-mac-main-1657583981-67a62b34bb0bef0897b387923802bab5de86c088.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index b8269d5d..88dd6c9 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1657551400-4fafcf5c094d420801dee41ec4760ca6c9575e0c.profdata
+chrome-win32-main-1657605582-bdc130366ec7159114a1a1b2e8a38655c40bb3c5.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 8468844..38d4c177c 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1657562389-962685416d94d413e1c6b654ae8d7d9c0e267b8a.profdata
+chrome-win64-main-1657605582-47e0361cb85e7ff0c81010686edfcb8bd22908f4.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 5b6d500..f835030 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -67,7 +67,7 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-const base::Feature kAppProvisioningStatic{"AppDeduplicationService",
+const base::Feature kAppProvisioningStatic{"AppProvisioningStatic",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
diff --git a/chrome/common/extensions/api/identity.idl b/chrome/common/extensions/api/identity.idl
index 7d40c3a..aec69f94 100644
--- a/chrome/common/extensions/api/identity.idl
+++ b/chrome/common/extensions/api/identity.idl
@@ -89,8 +89,15 @@
     boolean? interactive;
   };
 
-  callback GetAuthTokenCallback = void (optional DOMString token,
-                                        optional DOMString[] grantedScopes);
+  dictionary GetAuthTokenResult {
+    // The specific token associated with the request.
+    DOMString? token;
+
+    // A list of OAuth2 scopes granted to the extension.
+    DOMString[]? grantedScopes;
+  };
+
+  callback GetAuthTokenCallback = void (GetAuthTokenResult result);
   callback GetAccountsCallback = void (AccountInfo[] accounts);
   callback GetProfileUserInfoCallback = void (ProfileUserInfo userInfo);
   callback InvalidateAuthTokenCallback = void ();
@@ -120,14 +127,19 @@
     // context. In particular, do not use <code>getAuthToken</code>
     // interactively when your app is first launched.
     //
+    // Note: When called with a callback, instead of returning an object this
+    // function will return the two properties as separate arguments passed to
+    // the callback.
+    //
     // |details| : Token options.
     // |callback| : Called with an OAuth2 access token as specified by the
     // manifest, or undefined if there was an error. The
     // <code>grantedScopes</code> parameter is populated since Chrome 87. When
     // available, this parameter contains the list of granted scopes
     // corresponding with the returned token.
-    static void getAuthToken(optional TokenDetails details,
-                             optional GetAuthTokenCallback callback);
+    [supportsPromises] static void getAuthToken(
+        optional TokenDetails details,
+        optional GetAuthTokenCallback callback);
 
     // Retrieves email address and obfuscated gaia id of the user
     // signed into a profile.
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index e036f81..98ee478 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -379,6 +379,7 @@
 const char kOsUIAccountMigrationWelcomeURL[] = "os://account-migration-welcome";
 const char kOsUIAddSupervisionURL[] = "os://add-supervision";
 const char kOsUIAppDisabledURL[] = "os://app-disabled";
+const char kOsUIAppServiceInternalsURL[] = "os://app-service-internals";
 const char kOsUICrashesURL[] = "os://crashes";
 const char kOsUICreditsURL[] = "os://credits";
 const char kOsUIDeviceLogURL[] = "os://device-log";
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index 379e3c5f..06d24f4c2 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -353,6 +353,7 @@
 extern const char kOsUIAccountMigrationWelcomeURL[];
 extern const char kOsUIAddSupervisionURL[];
 extern const char kOsUIAppDisabledURL[];
+extern const char kOsUIAppServiceInternalsURL[];
 extern const char kOsUICrashesURL[];
 extern const char kOsUICreditsURL[];
 extern const char kOsUIDeviceLogURL[];
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
index 431e7f5..0ad8a99 100644
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -302,6 +302,8 @@
       "extensions/chrome_extensions_renderer_client.h",
       "extensions/extension_hooks_delegate.cc",
       "extensions/extension_hooks_delegate.h",
+      "extensions/identity_hooks_delegate.cc",
+      "extensions/identity_hooks_delegate.h",
       "extensions/media_galleries_custom_bindings.cc",
       "extensions/media_galleries_custom_bindings.h",
       "extensions/notifications_native_handler.cc",
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
index 8fa5894..5f82ebe 100644
--- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
+++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -15,6 +15,7 @@
 #include "chrome/grit/renderer_resources.h"
 #include "chrome/renderer/extensions/app_hooks_delegate.h"
 #include "chrome/renderer/extensions/extension_hooks_delegate.h"
+#include "chrome/renderer/extensions/identity_hooks_delegate.h"
 #include "chrome/renderer/extensions/media_galleries_custom_bindings.h"
 #include "chrome/renderer/extensions/notifications_native_handler.h"
 #include "chrome/renderer/extensions/page_capture_custom_bindings.h"
@@ -243,6 +244,8 @@
   bindings->GetHooksForAPI("tabs")->SetDelegate(
       std::make_unique<extensions::TabsHooksDelegate>(
           bindings_system->messaging_service()));
+  bindings->GetHooksForAPI("identity")
+      ->SetDelegate(std::make_unique<extensions::IdentityHooksDelegate>());
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   bindings->GetHooksForAPI("accessibilityPrivate")
       ->SetDelegate(
diff --git a/chrome/renderer/extensions/identity_hooks_delegate.cc b/chrome/renderer/extensions/identity_hooks_delegate.cc
new file mode 100644
index 0000000..b572dfa
--- /dev/null
+++ b/chrome/renderer/extensions/identity_hooks_delegate.cc
@@ -0,0 +1,72 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/extensions/identity_hooks_delegate.h"
+
+#include "base/bind.h"
+#include "base/check.h"
+#include "extensions/renderer/bindings/api_binding_types.h"
+#include "extensions/renderer/v8_helpers.h"
+
+namespace extensions {
+
+namespace {
+constexpr char kGetAuthToken[] = "identity.getAuthToken";
+
+// Function that, for callback based API calls, will make the values associated
+// with each property on the return object a separate argument in a new result
+// vector it returns instead.
+// Note: This is to allow the promise version of the API to return a
+// single object, while still supporting the previous callback version which
+// expects multiple parameters to be passed to the callback.
+std::vector<v8::Local<v8::Value>> MassageGetAuthTokenResults(
+    const std::vector<v8::Local<v8::Value>>& result_args,
+    v8::Local<v8::Context> context,
+    binding::AsyncResponseType async_type) {
+  // If this is not a callback based API call, we don't need to modify anything.
+  if (async_type != binding::AsyncResponseType::kCallback) {
+    return result_args;
+  }
+
+  DCHECK_EQ(1u, result_args.size());
+  DCHECK(result_args[0]->IsObject());
+  v8::Local<v8::Object> result_obj = result_args[0].As<v8::Object>();
+
+  // The object sent back has two properties on it which we need to split into
+  // two separate arguments"
+  v8::Local<v8::Value> token;
+  bool success = v8_helpers::GetProperty(context, result_obj, "token", &token);
+  DCHECK(success);
+  v8::Local<v8::Value> granted_scopes;
+  success = v8_helpers::GetProperty(context, result_obj, "grantedScopes",
+                                    &granted_scopes);
+  DCHECK(success);
+  std::vector<v8::Local<v8::Value>> new_args{token, granted_scopes};
+
+  return new_args;
+}
+
+}  // namespace
+
+using RequestResult = APIBindingHooks::RequestResult;
+
+IdentityHooksDelegate::IdentityHooksDelegate() = default;
+IdentityHooksDelegate::~IdentityHooksDelegate() = default;
+
+RequestResult IdentityHooksDelegate::HandleRequest(
+    const std::string& method_name,
+    const APISignature* signature,
+    v8::Local<v8::Context> context,
+    std::vector<v8::Local<v8::Value>>* arguments,
+    const APITypeReferenceMap& refs) {
+  // Only add the result handler for the getAuthToken function.
+  if (method_name != kGetAuthToken)
+    return RequestResult(RequestResult::NOT_HANDLED);
+
+  return RequestResult(RequestResult::NOT_HANDLED,
+                       v8::Local<v8::Function>() /*custom_callback*/,
+                       base::BindOnce(MassageGetAuthTokenResults));
+}
+
+}  // namespace extensions
diff --git a/chrome/renderer/extensions/identity_hooks_delegate.h b/chrome/renderer/extensions/identity_hooks_delegate.h
new file mode 100644
index 0000000..c04ccb2
--- /dev/null
+++ b/chrome/renderer/extensions/identity_hooks_delegate.h
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_EXTENSIONS_IDENTITY_HOOKS_DELEGATE_H_
+#define CHROME_RENDERER_EXTENSIONS_IDENTITY_HOOKS_DELEGATE_H_
+
+#include <vector>
+
+#include "extensions/renderer/bindings/api_binding_hooks_delegate.h"
+#include "extensions/renderer/bindings/api_signature.h"
+#include "v8/include/v8-forward.h"
+
+namespace extensions {
+
+// Custom native hooks for the identity API.
+class IdentityHooksDelegate : public APIBindingHooksDelegate {
+ public:
+  IdentityHooksDelegate();
+
+  IdentityHooksDelegate(const IdentityHooksDelegate&) = delete;
+  IdentityHooksDelegate& operator=(const IdentityHooksDelegate&) = delete;
+
+  ~IdentityHooksDelegate() override;
+
+  // APIBindingHooksDelegate:
+  APIBindingHooks::RequestResult HandleRequest(
+      const std::string& method_name,
+      const APISignature* signature,
+      v8::Local<v8::Context> context,
+      std::vector<v8::Local<v8::Value>>* arguments,
+      const APITypeReferenceMap& refs) override;
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_RENDERER_EXTENSIONS_IDENTITY_HOOKS_DELEGATE_H_
diff --git a/chrome/renderer/extensions/identity_hooks_delegate_unittest.cc b/chrome/renderer/extensions/identity_hooks_delegate_unittest.cc
new file mode 100644
index 0000000..544c677
--- /dev/null
+++ b/chrome/renderer/extensions/identity_hooks_delegate_unittest.cc
@@ -0,0 +1,91 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/extensions/identity_hooks_delegate.h"
+
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_builder.h"
+#include "extensions/common/mojom/frame.mojom.h"
+#include "extensions/renderer/bindings/api_binding_test_util.h"
+#include "extensions/renderer/native_extension_bindings_system.h"
+#include "extensions/renderer/native_extension_bindings_system_test_base.h"
+#include "extensions/renderer/script_context.h"
+
+namespace extensions {
+
+using IdentityHooksDelegateTest = NativeExtensionBindingsSystemUnittest;
+
+// Tests that the result modifier used in the getAuthToken handle request hook
+// results in callback-based calls getting a response with multiple arguments
+// and promise-based calls getting a response with a single object.
+TEST_F(IdentityHooksDelegateTest, GetAuthToken) {
+  // Initialize bindings system.
+  bindings_system()
+      ->api_system()
+      ->GetHooksForAPI("identity")
+      ->SetDelegate(std::make_unique<IdentityHooksDelegate>());
+  // Register extension.
+  scoped_refptr<const Extension> extension = ExtensionBuilder("testExtension")
+                                                 .SetManifestVersion(3)
+                                                 .AddPermission("identity")
+                                                 .Build();
+  RegisterExtension(extension);
+  v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = MainContext();
+  ScriptContext* script_context = CreateScriptContext(
+      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
+  script_context->set_url(extension->url());
+  bindings_system()->UpdateBindingsForContext(script_context);
+
+  constexpr char kFakeAPIResponse[] =
+      R"([{"token": "foo", "grantedScopes": ["bar"]}])";
+
+  // Calling getAuthToken without a callback should return a promise that gets
+  // fulfilled with an object with the results as properties on it.
+  {
+    v8::Local<v8::Function> func = FunctionFromString(
+        context, "(function() { return chrome.identity.getAuthToken(); })");
+    v8::Local<v8::Value> result = RunFunction(func, context, 0, nullptr);
+    v8::Local<v8::Promise> promise;
+    ASSERT_TRUE(GetValueAs(result, &promise));
+    EXPECT_EQ(v8::Promise::kPending, promise->State());
+
+    bindings_system()->HandleResponse(last_params().request_id,
+                                      /*success=*/true,
+                                      ListValueFromString(kFakeAPIResponse),
+                                      /*error=*/std::string());
+
+    EXPECT_EQ(v8::Promise::kFulfilled, promise->State());
+    // Note that the object here differs slightly from the response, in that it
+    // is not array wrapped and the keys become alphabetized.
+    EXPECT_EQ(R"({"grantedScopes":["bar"],"token":"foo"})",
+              V8ToString(promise->Result(), context));
+  }
+
+  // Calling getAuthToken with a callback should end up with the callback being
+  // called with multiple parameters rather than a single object.
+  {
+    constexpr char kFunctionCall[] =
+        R"((function(api) {
+             chrome.identity.getAuthToken((token, grantedScopes) => {
+               this.argument1 = token;
+               this.argument2 = grantedScopes;
+             });
+           }))";
+    v8::Local<v8::Function> func = FunctionFromString(context, kFunctionCall);
+    RunFunctionOnGlobal(func, context, 0, nullptr);
+
+    bindings_system()->HandleResponse(last_params().request_id,
+                                      /*success=*/true,
+                                      ListValueFromString(kFakeAPIResponse),
+                                      /*error=*/std::string());
+
+    EXPECT_EQ(R"("foo")", GetStringPropertyFromObject(context->Global(),
+                                                      context, "argument1"));
+    EXPECT_EQ(R"(["bar"])", GetStringPropertyFromObject(context->Global(),
+                                                        context, "argument2"));
+  }
+}
+
+}  // namespace extensions
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 0b3a4b7..6fe81c3 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4133,6 +4133,8 @@
         "//chrome/services/wilco_dtc_supportd/public/mojom",
         "//chromeos:test_support",
         "//chromeos/ash/components/assistant:buildflags",
+        "//chromeos/ash/components/dbus/attestation",
+        "//chromeos/ash/components/dbus/attestation:attestation_proto",
         "//chromeos/ash/components/dbus/authpolicy",
         "//chromeos/ash/components/dbus/biod",
         "//chromeos/ash/components/dbus/biod:biod_proto",
@@ -4158,8 +4160,6 @@
         "//chromeos/components/quick_answers/public/cpp:cpp",
         "//chromeos/components/remote_apps/mojom:mojom",
         "//chromeos/dbus:test_support",
-        "//chromeos/dbus/attestation",
-        "//chromeos/dbus/attestation:attestation_proto",
         "//chromeos/dbus/cros_disks",
         "//chromeos/dbus/cros_disks",
         "//chromeos/dbus/cryptohome",
@@ -4617,7 +4617,6 @@
     ]
 
     data_deps = [
-      "//build/lacros:lacros_version_metadata",
       "//chrome:packed_resources",
       "//testing/buildbot/filters:lacros_chrome_browsertests_filters",
     ]
@@ -4732,7 +4731,6 @@
     ]
 
     data_deps = [
-      "//build/lacros:lacros_version_metadata",
       "//chrome:packed_resources",
       "//testing/buildbot/filters:lacros_chrome_browsertests_filters",
     ]
@@ -7293,6 +7291,7 @@
       "//chrome/services/sharing/public/cpp",
       "//chrome/services/sharing/public/cpp:unit_tests",
       "//chromeos/ash/components/assistant:buildflags",
+      "//chromeos/ash/components/dbus/attestation",
       "//chromeos/ash/components/dbus/cicerone",
       "//chromeos/ash/components/dbus/concierge",
       "//chromeos/ash/components/dbus/image_loader",
@@ -7308,7 +7307,6 @@
       "//chromeos/components/sync_wifi",
       "//chromeos/constants",
       "//chromeos/dbus",
-      "//chromeos/dbus/attestation",
       "//chromeos/dbus/cros_disks",
       "//chromeos/dbus/debug_daemon",
       "//chromeos/dbus/hermes",
@@ -7811,6 +7809,7 @@
       "../renderer/extensions/chrome_native_extension_bindings_system_unittest.cc",
       "../renderer/extensions/custom_types_unittest.cc",
       "../renderer/extensions/extension_hooks_delegate_unittest.cc",
+      "../renderer/extensions/identity_hooks_delegate_unittest.cc",
       "../renderer/extensions/renderer_permissions_policy_delegate_unittest.cc",
       "../renderer/extensions/tabs_hooks_delegate_unittest.cc",
     ]
@@ -9635,11 +9634,6 @@
         "chrome/test/data/perf/frame_rate/content/googleblog/images/bse%e2%80%99s+solar+energy+development+center..jpg",
       ]
     }
-
-    if (is_chromeos_lacros && !is_chromeos_device) {
-      # For support version skew testing.
-      data_deps += [ "//build/lacros:lacros_version_metadata" ]
-    }
   }
 }
 
diff --git a/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts
index 98050d2b..00addd20 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts
@@ -150,13 +150,19 @@
       'sets aria-selected attribute if image name matches currently selected',
       async () => {
         personalizationStore.data.wallpaper.local = {
-          images: wallpaperProvider.localImages,
-          data: wallpaperProvider.localImageData,
+          images: [
+            {path: '/test/LocalImage0.png'}, {path: '/test/LocalImage1.png'}
+          ],
+          data: {
+            '/test/LocalImage0.png': 'data://localimage0data',
+            '/test/LocalImage1.png': 'data://localimage1data',
+          },
         };
         // Done loading.
         personalizationStore.data.wallpaper.loading.local = {
           images: false,
-          data: {'LocalImage0.png': false, 'LocalImage1.png': false},
+          data:
+              {'/test/LocalImage0.png': false, '/test/LocalImage1.png': false},
         };
 
         localImagesElement = initElement(LocalImages, {hidden: false});
@@ -173,7 +179,7 @@
             image => image.getAttribute('aria-selected') === 'false'));
 
         personalizationStore.data.wallpaper.currentSelected = {
-          key: 'LocalImage1.png'
+          key: '/test/LocalImage1.png'
         };
         personalizationStore.notifyObservers();
 
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js
index b4100c59..6e5c0c4 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js
+++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_component_browsertest.js
@@ -10,6 +10,7 @@
 GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']);
 
 GEN('#include "ash/constants/ash_features.h"');
+GEN('#include "ash/public/cpp/style/dark_light_mode_controller.h"');
 GEN('#include "chromeos/constants/chromeos_features.h"');
 GEN('#include "content/public/test/browser_test.h"');
 
@@ -21,6 +22,14 @@
   get featureList() {
     return {enabled: ['ash::features::kWallpaperGooglePhotosIntegration']};
   }
+
+  get testGenPreamble() {
+    // Force light mode in test to reduce randomness.
+    return () => {
+      GEN('ash::DarkLightModeController::Get()');
+      GEN('->SetDarkModeEnabledForTest(false);');
+    };
+  }
 };
 
 [['AmbientPreviewTest', 'ambient_preview_element_test.js'],
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
index 0abbe50..e2abe57e 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
@@ -774,7 +774,7 @@
       return image.assetId.toString();
     }
     if (isFilePath(image)) {
-      return image.path.substr(image.path.lastIndexOf('/') + 1);
+      return image.path;
     }
     assertNotReached('unknown wallpaper type');
   }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts
index 161482bb..72103e85 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts
@@ -69,7 +69,7 @@
     this.images_ = [
       {
         assetId: BigInt(0),
-        attribution: ['Image 0'],
+        attribution: ['Image 0 dark'],
         url: {url: 'https://images.googleusercontent.com/0'},
         unitId: BigInt(1),
         type: OnlineImageType.kDark,
@@ -79,11 +79,11 @@
         attribution: ['Image 2'],
         url: {url: 'https://images.googleusercontent.com/2'},
         unitId: BigInt(2),
-        type: OnlineImageType.kDark,
+        type: OnlineImageType.kUnknown,
       },
       {
         assetId: BigInt(1),
-        attribution: ['Image 1'],
+        attribution: ['Image 0 light'],
         url: {url: 'https://images.googleusercontent.com/1'},
         unitId: BigInt(1),
         type: OnlineImageType.kLight,
@@ -98,7 +98,7 @@
     };
 
     this.currentWallpaper = {
-      attribution: ['Image 0'],
+      attribution: ['Image 0 light'],
       layout: WallpaperLayout.kCenter,
       key: '1',
       type: WallpaperType.kOnline,
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts
index e37f9839c..e735535 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts
@@ -5,17 +5,16 @@
 import 'chrome://personalization/strings.m.js';
 import 'chrome://webui-test/mojo_webui_test_support.js';
 
-import {getDarkLightImageTiles, getRegularImageTiles, IFrameApi, PersonalizationRouter, WallpaperImages, WallpaperLayout, WallpaperType} from 'chrome://personalization/trusted/personalization_app.js';
-import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {assertDeepEquals, assertEquals} from 'chrome://webui-test/chai_assert.js';
-import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/test_util.js';
+import {OnlineImageType, PersonalizationRouter, WallpaperImages} from 'chrome://personalization/trusted/personalization_app.js';
+import {assertDeepEquals, assertEquals, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {waitAfterNextRender} from 'chrome://webui-test/test_util.js';
 
-import {baseSetup, initElement, setupTestIFrameApi, teardownElement} from './personalization_app_test_utils.js';
+import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js';
 import {TestPersonalizationStore} from './test_personalization_store.js';
 import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js';
 
 suite('WallpaperImagesTest', function() {
-  let wallpaperImagesElement: WallpaperImages|null = null;
+  let wallpaperImagesElement: WallpaperImages|null;
   let wallpaperProvider: TestWallpaperProvider;
   let personalizationStore: TestPersonalizationStore;
 
@@ -28,80 +27,91 @@
   teardown(async () => {
     await teardownElement(wallpaperImagesElement);
     wallpaperImagesElement = null;
-    await flushTasks();
   });
 
-  test('send current wallpaper asset id', async () => {
-    const testProxy = setupTestIFrameApi();
-
-    // Set the current wallpaper as an online wallpaper.
-    // The currentSelected asset id should be sent to iframe.
-    personalizationStore.data.wallpaper.currentSelected =
-        wallpaperProvider.currentWallpaper;
-
-    wallpaperImagesElement =
-        initElement(WallpaperImages, {collectionId: 'id_0'});
-
-    const imagesGrid = wallpaperImagesElement.$.imagesGrid;
-
-    // Wait for iframe to receive data.
-    let [target, data] =
-        await testProxy.whenCalled('sendCurrentWallpaperAssetId') as
-        Parameters<IFrameApi['sendCurrentWallpaperAssetId']>;
-
-    assertEquals(imagesGrid, target);
-    assertDeepEquals(
-        BigInt(personalizationStore.data.wallpaper.currentSelected.key), data);
-
-    testProxy.resetResolver('sendCurrentWallpaperAssetId');
-
-    // Set the current wallpaper as a daily refresh wallpaper.
-    // The currentSelected asset id should be sent to iframe.
-    personalizationStore.data.wallpaper.currentSelected = {
-      attribution: ['Image 1'],
-      layout: WallpaperLayout.kCenter,
-      key: '2',
-      type: WallpaperType.kDaily,
-      url: {url: 'https://images.googleusercontent.com/1'},
+  async function createWithDefaultData() {
+    const collectionId = wallpaperProvider.collections![0]!.id;
+    personalizationStore.data.wallpaper = {
+      ...personalizationStore.data.wallpaper,
+      backdrop: {
+        collections: wallpaperProvider.collections,
+        images: {[collectionId]: wallpaperProvider.images},
+      },
+      loading: {
+        ...personalizationStore.data.wallpaper.loading,
+        collections: false,
+        images: {[collectionId]: false},
+      },
+      currentSelected: wallpaperProvider.currentWallpaper,
     };
-    personalizationStore.notifyObservers();
+    const element = initElement(WallpaperImages, {collectionId});
+    await waitAfterNextRender(element);
+    return element;
+  }
 
-    // Wait for iframe to receive data.
-    [target, data] =
-        await testProxy.whenCalled('sendCurrentWallpaperAssetId') as
-        Parameters<IFrameApi['sendCurrentWallpaperAssetId']>;
-    assertEquals(imagesGrid, target);
-    assertDeepEquals(
-        BigInt(personalizationStore.data.wallpaper.currentSelected.key), data);
+  test('sets aria-selected for current wallpaper asset id', async () => {
+    wallpaperImagesElement = await createWithDefaultData();
+    const selectedElement: HTMLDivElement =
+        wallpaperImagesElement.shadowRoot!.querySelector(
+            `.photo-inner-container[aria-selected='true']`)!;
 
-    testProxy.resetResolver('sendCurrentWallpaperAssetId');
+    assertEquals(
+        selectedElement!.dataset['assetId'],
+        personalizationStore.data.wallpaper.currentSelected.key,
+        'aria selected element has correct asset id');
 
-    // Set the current wallpaper not as an online wallpaper.
-    // No asset id is sent to iframe.
-    personalizationStore.data.wallpaper.currentSelected = {
-      attribution: ['Image 2'],
-      layout: WallpaperLayout.kCenter,
-      key: '3',
-      type: WallpaperType.kDefault,
-      url: {url: 'https://images.googleusercontent.com/2'},
-    };
-    personalizationStore.notifyObservers();
+    const notSelectedElements: HTMLDivElement[] =
+        Array.from(wallpaperImagesElement.shadowRoot!.querySelectorAll(
+            `.photo-inner-container[aria-selected='false']`));
 
-    // Wait for iframe to receive data.
-    [target, data] =
-        await testProxy.whenCalled('sendCurrentWallpaperAssetId') as
-        Parameters<IFrameApi['sendCurrentWallpaperAssetId']>;
-    assertEquals(imagesGrid, target);
-    assertEquals(undefined, data);
+    const uniqueUnitIds =
+        new Set(wallpaperProvider.images!.map(img => img.unitId));
+
+    assertEquals(
+        uniqueUnitIds.size - 1, notSelectedElements.length,
+        'correct number of non-selected elements');
+
+    for (const notSelected of notSelectedElements) {
+      assertTrue(
+          notSelected.dataset['assetId']!.length > 0,
+          'not selected elements have an assetId');
+
+      assertNotEquals(
+          wallpaperProvider.currentWallpaper.key,
+          notSelected.dataset['assetId'],
+          'not selected elements have a different assetId');
+    }
   });
 
-  test('displays images for current collection id', async () => {
-    loadTimeData.overrideValues({isDarkLightModeEnabled: false});
+  test('displays images for current collectionId', async () => {
     personalizationStore.data.wallpaper.backdrop.images = {
-      'id_0': wallpaperProvider.images,
+      'id_0': [
+        {
+          assetId: BigInt(1),
+          attribution: ['Image 0-1'],
+          unitId: BigInt(1),
+          url: {url: 'https://id_0-1/'},
+        },
+        {
+          assetId: BigInt(2),
+          attribution: ['Image 0-2'],
+          unitId: BigInt(2),
+          url: {url: 'https://id_0-2/'},
+        },
+      ],
       'id_1': [
-        {assetId: BigInt(10), url: {url: 'https://id_1-0/'}},
-        {assetId: BigInt(20), url: {url: 'https://id_1-1/'}},
+        {
+          assetId: BigInt(10),
+          attribution: ['Image 1-10'],
+          unitId: BigInt(10),
+          url: {url: 'https://id_1-10/'},
+        },
+        {
+          assetId: BigInt(20),
+          attribution: ['Image 1-20'],
+          unitId: BigInt(20),
+          url: {url: 'https://id_1-20/'},
+        },
       ],
     };
     personalizationStore.data.wallpaper.backdrop.collections =
@@ -112,138 +122,93 @@
     };
     personalizationStore.data.wallpaper.loading.collections = false;
 
-    const testProxy = setupTestIFrameApi();
     wallpaperImagesElement =
         initElement(WallpaperImages, {collectionId: 'id_0'});
-
-    const imagesGrid = wallpaperImagesElement.$.imagesGrid;
-
-    // Wait for iframe to receive data.
-    let [target, data] = await testProxy.whenCalled('sendImageTiles') as
-        Parameters<IFrameApi['sendImageTiles']>;
-    assertEquals(imagesGrid, target);
-    assertDeepEquals(
-        getRegularImageTiles(
-            personalizationStore.data.wallpaper.backdrop.images['id_0']),
-        data);
-    // Wait for a render to happen.
     await waitAfterNextRender(wallpaperImagesElement);
 
-    testProxy.resetResolver('sendImageTiles');
+    assertDeepEquals(
+        ['1', '2'],
+        Array
+            .from(
+                wallpaperImagesElement.shadowRoot!
+                    .querySelectorAll<HTMLDivElement>('.photo-inner-container'))
+            .map(elem => elem.dataset['assetId']),
+        'expected asset ids are displayed for collectionId `id_0`');
+
     wallpaperImagesElement.collectionId = 'id_1';
-
-    // Wait for iframe to receive new data.
-    [target, data] = await testProxy.whenCalled('sendImageTiles') as
-        Parameters<IFrameApi['sendImageTiles']>;
-
     await waitAfterNextRender(wallpaperImagesElement);
 
-    assertEquals(imagesGrid, target);
     assertDeepEquals(
-        getRegularImageTiles(
-            personalizationStore.data.wallpaper.backdrop.images['id_1']),
-        data);
+        ['10', '20'],
+        Array
+            .from(
+                wallpaperImagesElement.shadowRoot!
+                    .querySelectorAll<HTMLDivElement>('.photo-inner-container'))
+            .map(elem => elem.dataset['assetId']),
+        'expected asset ids are displayed for collectionId `id_1`');
   });
 
-  test('display dark/light tile for personalization hub', async () => {
-    loadTimeData.overrideValues({isDarkLightModeEnabled: true});
-    personalizationStore.data.wallpaper.backdrop.images = {
-      'id_0': wallpaperProvider.images,
-      'id_1': [
-        {assetId: BigInt(10), url: {url: 'https://id_1-0/'}},
-        {assetId: BigInt(20), url: {url: 'https://id_1-1/'}},
-      ],
-    };
-    personalizationStore.data.wallpaper.backdrop.collections =
-        wallpaperProvider.collections;
-    personalizationStore.data.wallpaper.loading.images = {
-      'id_0': false,
-      'id_1': false
-    };
-    personalizationStore.data.wallpaper.loading.collections = false;
+  test('displays dark light tile for images with same unitId', async () => {
+    wallpaperImagesElement = await createWithDefaultData();
 
-    const testProxy = setupTestIFrameApi();
-    wallpaperImagesElement =
-        initElement(WallpaperImages, {collectionId: 'id_0'});
+    const elements =
+        Array.from(wallpaperImagesElement.shadowRoot!.querySelectorAll(
+            '.photo-inner-container'));
 
-    const imagesGrid = wallpaperImagesElement.$.imagesGrid;
-
-    // Wait for images-grid to receive data.
-    let [target, data] = await testProxy.whenCalled('sendImageTiles') as
-        Parameters<IFrameApi['sendImageTiles']>;
-    assertEquals(imagesGrid, target);
-    const tiles = getDarkLightImageTiles(
-        wallpaperImagesElement.isDarkModeActive,
-        personalizationStore.data.wallpaper.backdrop.images['id_0']);
-    assertDeepEquals(tiles, data);
-    assertEquals(data[0]!.preview.length, 2);
-    // Check that light variant comes before dark variant.
-    assertEquals(
-        data[0]!.preview[0]!.url, 'https://images.googleusercontent.com/1');
-    assertEquals(
-        data[0]!.preview[1]!.url, 'https://images.googleusercontent.com/0');
-    // Wait for a render to happen.
-    await waitAfterNextRender(wallpaperImagesElement);
-
-    testProxy.resetResolver('sendImageTiles');
-    wallpaperImagesElement.collectionId = 'id_1';
-
-    // Wait for iframe to receive new data.
-    [target, data] = await testProxy.whenCalled('sendImageTiles') as
-        Parameters<IFrameApi['sendImageTiles']>;
-
-    await waitAfterNextRender(wallpaperImagesElement);
-
-    assertEquals(imagesGrid, target);
     assertDeepEquals(
-        getDarkLightImageTiles(
-            wallpaperImagesElement.isDarkModeActive,
-            personalizationStore.data.wallpaper.backdrop.images['id_1']),
-        data);
+        ['Image 0 light', 'Image 2'], elements.map(elem => elem.ariaLabel),
+        'elements have correct aria labels for light mode');
+
+    assertDeepEquals(
+        [
+          'chrome://image/?https://images.googleusercontent.com/1',
+          'chrome://image/?https://images.googleusercontent.com/0',
+        ],
+        Array.from(elements[0]!.querySelectorAll('img')).map(img => img.src),
+        'dark/light mode image has dark light variant urls');
+
+    assertEquals(
+        OnlineImageType.kLight,
+        wallpaperProvider.images!
+            .find(image => image.url.url.endsWith('.com/1'))!.type,
+        'light image is first');
+
+    assertDeepEquals(
+        ['chrome://image/?https://images.googleusercontent.com/2'],
+        Array.from(elements[1]!.querySelectorAll('img')).map(img => img.src),
+        'image 2 does not have dark light mode variants');
   });
 
-  test('navigates back to main page on loading failure', async () => {
-    const reloadPromise = new Promise<void>((resolve) => {
+  test('selects an image when clicked', async () => {
+    wallpaperImagesElement = await createWithDefaultData();
+    wallpaperImagesElement.shadowRoot!
+        .querySelector<HTMLDivElement>(
+            `.photo-inner-container[data-asset-id='2']`)!.click();
+    const [assetId, previewMode] =
+        await wallpaperProvider.whenCalled('selectWallpaper');
+    assertEquals(2n, assetId, 'correct asset id is passed');
+    assertEquals(
+        wallpaperProvider.isInTabletModeResponse, previewMode,
+        'preview mode is same as tablet mode');
+  });
+
+  test('redirects to wallpaper page if no images', async () => {
+    const reloadOriginal = PersonalizationRouter.reloadAtWallpaper;
+    const reloadPromise = new Promise<void>(resolve => {
       PersonalizationRouter.reloadAtWallpaper = resolve;
     });
-
-    personalizationStore.data.wallpaper.backdrop.collections =
-        wallpaperProvider.collections;
-    personalizationStore.data.wallpaper.backdrop.images = {'id_0': null};
-    personalizationStore.data.wallpaper.loading = {
-      collections: false,
-      images: {'id_0': true}
-    };
-
-    wallpaperImagesElement =
-        initElement(WallpaperImages, {collectionId: 'id_0'});
-
-    // Simulate finish loading. Images still null. Should bail and reload
-    // application.
-    personalizationStore.data.wallpaper.loading = {images: {'id_0': false}};
+    wallpaperImagesElement = await createWithDefaultData();
+    // Set all collections to have null images.
+    personalizationStore.data.wallpaper.backdrop.images =
+        Object.keys(personalizationStore.data.wallpaper.backdrop.images)
+            .reduce((result, next) => {
+              result[next] = null;
+              return result;
+            }, {} as Record<string, null>);
     personalizationStore.notifyObservers();
 
     await reloadPromise;
-  });
 
-  test('navigates back to main page on unknown collection id', async () => {
-    const reloadPromise = new Promise<void>((resolve) => {
-      PersonalizationRouter.reloadAtWallpaper = resolve;
-    });
-
-    personalizationStore.data.wallpaper.backdrop.collections =
-        wallpaperProvider.collections;
-    personalizationStore.data.wallpaper.backdrop.images = {
-      'id_0': wallpaperProvider.images
-    };
-    personalizationStore.data.wallpaper.loading = {
-      collections: false,
-      images: {'id_0': false},
-    };
-
-    wallpaperImagesElement =
-        initElement(WallpaperImages, {collectionId: 'unknown_id'});
-
-    await reloadPromise;
+    PersonalizationRouter.reloadAtWallpaper = reloadOriginal;
   });
 });
diff --git a/chrome/test/data/webui/cr_components/color_change_listener_test.ts b/chrome/test/data/webui/cr_components/color_change_listener_test.ts
index 9876c46e..03da7db9 100644
--- a/chrome/test/data/webui/cr_components/color_change_listener_test.ts
+++ b/chrome/test/data/webui/cr_components/color_change_listener_test.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import {COLORS_CSS_SELECTOR, refreshColorCss} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js';
-import {assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 suite('ColorChangeListenerTest', () => {
   setup(() => {
@@ -25,7 +25,9 @@
     const secondHref = colorCssNode.getAttribute('href');
     assertTrue(!!secondHref);
     assertTrue(secondHref.startsWith('chrome://theme/colors.css'));
-    assertTrue(!!new URL(secondHref).search);
+    const params = new URLSearchParams(new URL(secondHref).search);
+    assertTrue(!!params.get('version'));
+    assertEquals('ui', params.get('sets'));
 
     assertNotEquals(initialHref, secondHref);
 
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
index 77e5482..960bc5d7d 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
@@ -34,23 +34,35 @@
   }
 
   test('updateFontName', () => {
-    chrome.readAnything.setFontNameForTesting('Standard');
-    assertFontName('Roboto, Arial, sans-serif');
+    chrome.readAnything.setFontNameForTesting('Standard font');
+    assertFontName('"Standard font"');
 
-    chrome.readAnything.setFontNameForTesting('Sans-serif');
-    assertFontName('Roboto, Tahoma, sans-serif');
+    chrome.readAnything.setFontNameForTesting('Sans');
+    assertFontName('Sans');
 
     chrome.readAnything.setFontNameForTesting('Serif');
-    assertFontName('Didot, Georgia, serif');
+    assertFontName('serif');
 
     chrome.readAnything.setFontNameForTesting('Arial');
-    assertFontName('Arial, Verdona, sans-serif');
+    assertFontName('Arial');
 
-    chrome.readAnything.setFontNameForTesting('Open Sans');
-    assertFontName('"Open Sans", Courier, sans-serif');
+    chrome.readAnything.setFontNameForTesting('Roboto');
+    assertFontName('Roboto');
 
-    chrome.readAnything.setFontNameForTesting('Calibri');
-    assertFontName('Calibri, "Times New Roman", serif');
+    chrome.readAnything.setFontNameForTesting('Courier New');
+    assertFontName('"Courier New"');
+
+    chrome.readAnything.setFontNameForTesting('Comic Sans MS');
+    assertFontName('"Comic Sans MS"');
+
+    chrome.readAnything.setFontNameForTesting('Webdings');
+    assertFontName('Webdings');
+
+    chrome.readAnything.setFontNameForTesting('Impact');
+    assertFontName('Impact');
+
+    chrome.readAnything.setFontNameForTesting('foo_bar_baz');
+    assertFontName('"Standard font"');
   });
 
   test('updateContent paragraph', () => {
diff --git a/chrome/test/data/xr/e2e_test_files/html/webxr_test_camera_access.html b/chrome/test/data/xr/e2e_test_files/html/webxr_test_camera_access.html
index 18fea99..b83357df 100644
--- a/chrome/test/data/xr/e2e_test_files/html/webxr_test_camera_access.html
+++ b/chrome/test/data/xr/e2e_test_files/html/webxr_test_camera_access.html
@@ -25,11 +25,16 @@
       let ranAtLeastOnce = false;
       let pixels = null;
 
+      // Override canvas and context from webxr_boilerplate.js, we want to play
+      // with WebGL2 here (at least one test case requires it).
+      webglCanvas = document.getElementById('webgl-canvas');
+      webglCanvas.addEventListener('webglcontextcreationerror', function(e) {
+        console.log(e.statusMessage || 'Unknown error');
+      }, false);
+      gl = webglCanvas.getContext('webgl2', {xrCompatible: true});
+      assert_not_equals(gl, null, "We need a WebGL2 context!")
+
       function stepStartStoringCameraTexture(numCalls) {
-        const webglCanvas = document.getElementById('webgl-canvas');
-        const gl = webglCanvas.getContext('webgl', {
-                xrCompatible: true
-            });
         const sessionInfo = sessionInfos[sessionTypes.AR];
         const referenceSpace = sessionInfo.currentRefSpace;
         const glBinding = new XRWebGLBinding(sessionInfo.currentSession, gl);
@@ -66,10 +71,6 @@
       }
 
       function stepStartStoreAndDeleteCameraTexture() {
-        const webglCanvas = document.getElementById('webgl-canvas');
-        const gl = webglCanvas.getContext('webgl', {
-                xrCompatible: true
-            });
         const sessionInfo = sessionInfos[sessionTypes.AR];
         const referenceSpace = sessionInfo.currentRefSpace;
         const glBinding = new XRWebGLBinding(sessionInfo.currentSession, gl);
@@ -85,6 +86,8 @@
                 ranAtLeastOnce = true;
                 cameraImageTexture = glBinding.getCameraImage(view.camera);
                 gl.deleteTexture(cameraImageTexture);
+                const error = gl.getError();
+                assert_equals(error, gl.INVALID_OPERATION);
               }
             }
           }
@@ -98,10 +101,6 @@
       }
 
       function stepConfirmCameraTextureIsNotNull() {
-        const webglCanvas = document.getElementById('webgl-canvas');
-        const gl = webglCanvas.getContext('webgl', {
-                xrCompatible: true
-            });
         const sessionInfo = sessionInfos[sessionTypes.AR];
         const referenceSpace = sessionInfo.currentRefSpace;
         const glBinding = new XRWebGLBinding(sessionInfo.currentSession, gl);
@@ -140,10 +139,6 @@
       }
 
       function stepCheckCameraTextureLifetimeLimitedToOneFrame() {
-        const webglCanvas = document.getElementById('webgl-canvas');
-        const gl = webglCanvas.getContext('webgl', {
-          xrCompatible: true
-        });
         const sessionInfo = sessionInfos[sessionTypes.AR];
         const referenceSpace = sessionInfo.currentRefSpace;
         const glBinding = new XRWebGLBinding(sessionInfo.currentSession, gl);
@@ -152,7 +147,6 @@
         const attachmentPoint = gl.COLOR_ATTACHMENT0;
         const level = 0;
 
-
         // Assign pixels array non-zero values.
         pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
         pixels.fill(0);
@@ -172,7 +166,7 @@
              && numPosesFound < MAX_NUM_FRAMES_WITH_POSES) {
 
               const view = pose.views.find(v => v.camera != null);
-              if (view == undefined) return;
+              if (!view) return;
 
               cameraImageTexture = glBinding.getCameraImage(view.camera);
 
@@ -237,6 +231,83 @@
 
         return false;
       }
+
+      function stepCheckOpaqueTextures() {
+        const ext = gl.getExtension('WEBGL_compressed_texture_etc');
+
+        const sessionInfo = sessionInfos[sessionTypes.AR];
+        const referenceSpace = sessionInfo.currentRefSpace;
+        const glBinding = new XRWebGLBinding(sessionInfo.currentSession, gl);
+
+        const assert_invalid_operation = (cb, message) => {
+          cb();
+          const error = gl.getError();
+          assert_equals(error, gl.INVALID_OPERATION, message);
+        }
+
+        onARFrameCallback = (session, frame) => {
+          const pose = frame.getViewerPose(referenceSpace);
+          if (pose) {
+            numPosesFound++;
+
+            gl.bindFramebuffer(gl.FRAMEBUFFER, session.renderState.baseLayer.framebuffer);
+            gl.clearColor(0, 0, 0, 0);
+            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+            for (let view of pose.views) {
+              if (view.camera) {
+                ranAtLeastOnce = true;
+                cameraImageTexture = glBinding.getCameraImage(view.camera);
+                assert_not_equals(cameraImageTexture, null, "Camera texture must be present");
+
+                // gl.deleteTexture():
+                assert_invalid_operation(
+                  () => gl.deleteTexture(cameraImageTexture),
+                  "deleteTexture()");
+
+                // gl.texImage2D():
+                assert_invalid_operation(
+                  () => {
+                    gl.bindTexture(gl.TEXTURE_2D, cameraImageTexture);
+                    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, view.camera.width,
+                                  view.camera.height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
+                                  (new Uint32Array(view.camera.width * view.camera.height)).fill(0));
+                  }, "texImage2D()");
+
+                // gl.compressedTexImage2D():
+                assert_invalid_operation(
+                  () => {
+                    gl.bindTexture(gl.TEXTURE_2D, cameraImageTexture);
+                    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
+                                            view.camera.width, view.camera.height, 0,
+                                            (new Uint32Array(view.camera.width * view.camera.height)).fill(0));
+                  }, "compressedTexImage2D()");
+
+                // gl.copyTexImage2D():
+                assert_invalid_operation(
+                  () => {
+                    gl.bindTexture(gl.TEXTURE_2D, cameraImageTexture);
+                    gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0,
+                                      view.camera.width, view.camera.height, 0);
+                  }, "copyTexImage2D()");
+
+                // gl.texStorage2D():
+                assert_invalid_operation(
+                  () => {
+                    gl.bindTexture(gl.TEXTURE_2D, cameraImageTexture);
+                    gl.texStorage2D(gl.TEXTURE_2D, 0, gl.RGBA, view.camera.width, view.camera.height);
+                  }, "texStorage2D()");
+              }
+            }
+          }
+
+          if (numPosesFound > MIN_NUM_FRAMES_WITH_POSES) {
+            onARFrameCallback = null;
+            assert_true(ranAtLeastOnce);
+            done();
+          }
+        };
+      }
     </script>
   </body>
 </html>
\ No newline at end of file
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc
index f2d7c62..8c2ad3e 100644
--- a/chrome/utility/services.cc
+++ b/chrome/utility/services.cc
@@ -353,9 +353,9 @@
 }
 
 auto RunLocalSearchService(
-    mojo::PendingReceiver<ash::local_search_service::mojom::LocalSearchService>
-        receiver) {
-  return std::make_unique<ash::local_search_service::LocalSearchService>(
+    mojo::PendingReceiver<
+        chromeos::local_search_service::mojom::LocalSearchService> receiver) {
+  return std::make_unique<chromeos::local_search_service::LocalSearchService>(
       std::move(receiver));
 }
 
diff --git a/chromeos/ash/components/dbus/attestation/BUILD.gn b/chromeos/ash/components/dbus/attestation/BUILD.gn
new file mode 100644
index 0000000..d51a829
--- /dev/null
+++ b/chromeos/ash/components/dbus/attestation/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/chromeos/ui_mode.gni")
+import("//third_party/protobuf/proto_library.gni")
+
+assert(is_chromeos_ash, "Non-ChromeOS builds cannot depend on //chromeos/ash")
+
+component("attestation") {
+  output_name = "ash_dbus_attestation"
+  defines = [ "IS_ASH_DBUS_ATTESTATION_IMPL" ]
+
+  deps = [
+    ":attestation_proto",
+    "//base",
+    "//chromeos/dbus/constants:constants",
+    "//dbus",
+  ]
+
+  sources = [
+    "attestation_client.cc",
+    "attestation_client.h",
+    "fake_attestation_client.cc",
+    "fake_attestation_client.h",
+  ]
+}
+
+proto_library("attestation_proto") {
+  sources = [
+    "//third_party/cros_system_api/dbus/attestation/attestation_ca.proto",
+    "//third_party/cros_system_api/dbus/attestation/interface.proto",
+    "//third_party/cros_system_api/dbus/attestation/keystore.proto",
+  ]
+
+  proto_out_dir = "chromeos/ash/components/dbus/attestation"
+}
diff --git a/chromeos/ash/components/dbus/attestation/attestation_client.cc b/chromeos/ash/components/dbus/attestation/attestation_client.cc
new file mode 100644
index 0000000..5412f6e
--- /dev/null
+++ b/chromeos/ash/components/dbus/attestation/attestation_client.cc
@@ -0,0 +1,350 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+
+#include <utility>
+
+#include <google/protobuf/message_lite.h>
+
+#include "base/bind.h"
+#include "base/check_op.h"
+#include "base/command_line.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/dbus/constants/dbus_switches.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_path.h"
+#include "dbus/object_proxy.h"
+#include "third_party/cros_system_api/dbus/attestation/dbus-constants.h"
+
+namespace ash {
+namespace {
+
+// Values for the attestation server switch.
+const char kAttestationServerDefault[] = "default";
+const char kAttestationServerTest[] = "test";
+
+// An arbitrary timeout for getting a certificate.
+constexpr base::TimeDelta kGetCertificateTimeout = base::Seconds(80);
+
+AttestationClient* g_instance = nullptr;
+
+// Tries to parse a proto message from |response| into |proto|.
+// Returns false if |response| is nullptr or the message cannot be parsed.
+bool ParseProto(dbus::Response* response,
+                google::protobuf::MessageLite* proto) {
+  if (!response) {
+    LOG(ERROR) << "Failed to call attestationd";
+    return false;
+  }
+
+  dbus::MessageReader reader(response);
+  if (!reader.PopArrayOfBytesAsProto(proto)) {
+    LOG(ERROR) << "Failed to parse response message from attestationd";
+    return false;
+  }
+
+  return true;
+}
+
+// "Real" implementation of AttestationClient talking to the Attestation daemon
+// on the Chrome OS side.
+class AttestationClientImpl : public AttestationClient {
+ public:
+  AttestationClientImpl() = default;
+  ~AttestationClientImpl() override = default;
+
+  // Not copyable or movable.
+  AttestationClientImpl(const AttestationClientImpl&) = delete;
+  AttestationClientImpl& operator=(const AttestationClientImpl&) = delete;
+  AttestationClientImpl(AttestationClientImpl&&) = delete;
+  AttestationClientImpl& operator=(AttestationClientImpl&&) = delete;
+
+  // AttestationClient overrides:
+  void GetKeyInfo(const ::attestation::GetKeyInfoRequest& request,
+                  GetKeyInfoCallback callback) override {
+    CallProtoMethod(attestation::kGetKeyInfo, request, std::move(callback));
+  }
+
+  void GetEndorsementInfo(
+      const ::attestation::GetEndorsementInfoRequest& request,
+      GetEndorsementInfoCallback callback) override {
+    CallProtoMethod(attestation::kGetEndorsementInfo, request,
+                    std::move(callback));
+  }
+
+  void GetAttestationKeyInfo(
+      const ::attestation::GetAttestationKeyInfoRequest& request,
+      GetAttestationKeyInfoCallback callback) override {
+    CallProtoMethod(attestation::kGetAttestationKeyInfo, request,
+                    std::move(callback));
+  }
+
+  void ActivateAttestationKey(
+      const ::attestation::ActivateAttestationKeyRequest& request,
+      ActivateAttestationKeyCallback callback) override {
+    CallProtoMethod(attestation::kActivateAttestationKey, request,
+                    std::move(callback));
+  }
+
+  void CreateCertifiableKey(
+      const ::attestation::CreateCertifiableKeyRequest& request,
+      CreateCertifiableKeyCallback callback) override {
+    CallProtoMethod(attestation::kCreateCertifiableKey, request,
+                    std::move(callback));
+  }
+
+  void Decrypt(const ::attestation::DecryptRequest& request,
+               DecryptCallback callback) override {
+    CallProtoMethod(attestation::kDecrypt, request, std::move(callback));
+  }
+
+  void Sign(const ::attestation::SignRequest& request,
+            SignCallback callback) override {
+    CallProtoMethod(attestation::kSign, request, std::move(callback));
+  }
+
+  void RegisterKeyWithChapsToken(
+      const ::attestation::RegisterKeyWithChapsTokenRequest& request,
+      RegisterKeyWithChapsTokenCallback callback) override {
+    CallProtoMethod(attestation::kRegisterKeyWithChapsToken, request,
+                    std::move(callback));
+  }
+
+  void GetEnrollmentPreparations(
+      const ::attestation::GetEnrollmentPreparationsRequest& request,
+      GetEnrollmentPreparationsCallback callback) override {
+    CallProtoMethod(attestation::kGetEnrollmentPreparations, request,
+                    std::move(callback));
+  }
+
+  void GetStatus(const ::attestation::GetStatusRequest& request,
+                 GetStatusCallback callback) override {
+    CallProtoMethod(attestation::kGetStatus, request, std::move(callback));
+  }
+
+  void Verify(const ::attestation::VerifyRequest& request,
+              VerifyCallback callback) override {
+    CallProtoMethod(attestation::kVerify, request, std::move(callback));
+  }
+
+  void CreateEnrollRequest(
+      const ::attestation::CreateEnrollRequestRequest& request,
+      CreateEnrollRequestCallback callback) override {
+    CallProtoMethod(attestation::kCreateEnrollRequest, request,
+                    std::move(callback));
+  }
+
+  void FinishEnroll(const ::attestation::FinishEnrollRequest& request,
+                    FinishEnrollCallback callback) override {
+    CallProtoMethod(attestation::kFinishEnroll, request, std::move(callback));
+  }
+
+  void CreateCertificateRequest(
+      const ::attestation::CreateCertificateRequestRequest& request,
+      CreateCertificateRequestCallback callback) override {
+    CallProtoMethod(attestation::kCreateCertificateRequest, request,
+                    std::move(callback));
+  }
+
+  void FinishCertificateRequest(
+      const ::attestation::FinishCertificateRequestRequest& request,
+      FinishCertificateRequestCallback callback) override {
+    CallProtoMethod(attestation::kFinishCertificateRequest, request,
+                    std::move(callback));
+  }
+
+  void Enroll(const ::attestation::EnrollRequest& request,
+              EnrollCallback callback) override {
+    CallProtoMethod(attestation::kEnroll, request, std::move(callback));
+  }
+
+  void GetCertificate(const ::attestation::GetCertificateRequest& request,
+                      GetCertificateCallback callback) override {
+    CallProtoMethodWithTimeout(attestation::kGetCertificate,
+                               kGetCertificateTimeout.InMilliseconds(), request,
+                               std::move(callback));
+  }
+
+  void SignEnterpriseChallenge(
+      const ::attestation::SignEnterpriseChallengeRequest& request,
+      SignEnterpriseChallengeCallback callback) override {
+    CallProtoMethod(attestation::kSignEnterpriseChallenge, request,
+                    std::move(callback));
+  }
+
+  void SignSimpleChallenge(
+      const ::attestation::SignSimpleChallengeRequest& request,
+      SignSimpleChallengeCallback callback) override {
+    CallProtoMethod(attestation::kSignSimpleChallenge, request,
+                    std::move(callback));
+  }
+
+  void SetKeyPayload(const ::attestation::SetKeyPayloadRequest& request,
+                     SetKeyPayloadCallback callback) override {
+    CallProtoMethod(attestation::kSetKeyPayload, request, std::move(callback));
+  }
+
+  void DeleteKeys(const ::attestation::DeleteKeysRequest& request,
+                  DeleteKeysCallback callback) override {
+    CallProtoMethod(attestation::kDeleteKeys, request, std::move(callback));
+  }
+
+  void ResetIdentity(const ::attestation::ResetIdentityRequest& request,
+                     ResetIdentityCallback callback) override {
+    CallProtoMethod(attestation::kResetIdentity, request, std::move(callback));
+  }
+
+  void GetEnrollmentId(const ::attestation::GetEnrollmentIdRequest& request,
+                       GetEnrollmentIdCallback callback) override {
+    CallProtoMethod(attestation::kGetEnrollmentId, request,
+                    std::move(callback));
+  }
+
+  void GetCertifiedNvIndex(
+      const ::attestation::GetCertifiedNvIndexRequest& request,
+      GetCertifiedNvIndexCallback callback) override {
+    CallProtoMethod(attestation::kGetCertifiedNvIndex, request,
+                    std::move(callback));
+  }
+
+  void Init(dbus::Bus* bus) {
+    proxy_ = bus->GetObjectProxy(
+        ::attestation::kAttestationServiceName,
+        dbus::ObjectPath(attestation::kAttestationServicePath));
+  }
+
+ private:
+  TestInterface* GetTestInterface() override { return nullptr; }
+
+  // Calls attestationd's |method_name| method, passing in |request| as input
+  // with |timeout_ms|. Once the (asynchronous) call finishes, |callback| is
+  // called with the response proto.
+  template <typename RequestType, typename ReplyType>
+  void CallProtoMethodWithTimeout(
+      const char* method_name,
+      int timeout_ms,
+      const RequestType& request,
+      base::OnceCallback<void(const ReplyType&)> callback) {
+    dbus::MethodCall method_call(attestation::kAttestationInterface,
+                                 method_name);
+    dbus::MessageWriter writer(&method_call);
+    if (!writer.AppendProtoAsArrayOfBytes(request)) {
+      ReplyType reply;
+      reply.set_status(attestation::STATUS_INVALID_PARAMETER);
+      base::ThreadTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE, base::BindOnce(std::move(callback), reply));
+      return;
+    }
+    // Bind with the weak pointer of |this| so the response is not
+    // handled once |this| is already destroyed.
+    proxy_->CallMethod(
+        &method_call, timeout_ms,
+        base::BindOnce(&AttestationClientImpl::HandleResponse<ReplyType>,
+                       weak_factory_.GetWeakPtr(), std::move(callback)));
+  }
+
+  // Calls attestationd's |method_name| method, passing in |request| as input
+  // with the default timeout. Once the (asynchronous) call finishes, |callback|
+  // is called with the response proto.
+  template <typename RequestType, typename ReplyType>
+  void CallProtoMethod(const char* method_name,
+                       const RequestType& request,
+                       base::OnceCallback<void(const ReplyType&)> callback) {
+    CallProtoMethodWithTimeout(method_name,
+                               dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, request,
+                               std::move(callback));
+  }
+
+  // Parses the response proto message from |response| and calls |callback| with
+  // the decoded message. Calls |callback| with an |STATUS_DBUS_ERROR| message
+  // on error, including timeout.
+  template <typename ReplyType>
+  void HandleResponse(base::OnceCallback<void(const ReplyType&)> callback,
+                      dbus::Response* response) {
+    ReplyType reply_proto;
+    if (!ParseProto(response, &reply_proto))
+      reply_proto.set_status(attestation::STATUS_DBUS_ERROR);
+    std::move(callback).Run(reply_proto);
+  }
+
+  // D-Bus proxy for the Attestation daemon, not owned.
+  dbus::ObjectProxy* proxy_ = nullptr;
+
+  base::WeakPtrFactory<AttestationClientImpl> weak_factory_{this};
+};
+
+}  // namespace
+
+AttestationClient::AttestationClient() {
+  CHECK(!g_instance);
+  g_instance = this;
+}
+
+AttestationClient::~AttestationClient() {
+  CHECK_EQ(this, g_instance);
+  g_instance = nullptr;
+}
+
+// static
+void AttestationClient::Initialize(dbus::Bus* bus) {
+  CHECK(bus);
+  (new AttestationClientImpl())->Init(bus);
+}
+
+// static
+void AttestationClient::InitializeFake() {
+  new FakeAttestationClient();
+}
+
+// static
+void AttestationClient::Shutdown() {
+  CHECK(g_instance);
+  delete g_instance;
+  // The destructor resets |g_instance|.
+  DCHECK(!g_instance);
+}
+
+// static
+AttestationClient* AttestationClient::Get() {
+  return g_instance;
+}
+
+// static
+bool AttestationClient::IsAttestationPrepared(
+    const ::attestation::GetEnrollmentPreparationsReply& reply) {
+  if (reply.status() != ::attestation::STATUS_SUCCESS) {
+    return false;
+  }
+  for (const auto& preparation : reply.enrollment_preparations()) {
+    if (preparation.second) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// static
+::attestation::VAType AttestationClient::GetVerifiedAccessServerType() {
+  std::string value =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          chromeos::switches::kAttestationServer);
+  if (value.empty() || value == kAttestationServerDefault) {
+    return ::attestation::DEFAULT_VA;
+  }
+  if (value == kAttestationServerTest) {
+    return ::attestation::TEST_VA;
+  }
+  LOG(WARNING) << "Invalid Verified Access server value: " << value
+               << ". Using default.";
+  return attestation::DEFAULT_VA;
+}
+
+}  // namespace ash
diff --git a/chromeos/ash/components/dbus/attestation/attestation_client.h b/chromeos/ash/components/dbus/attestation/attestation_client.h
new file mode 100644
index 0000000..50883d1
--- /dev/null
+++ b/chromeos/ash/components/dbus/attestation/attestation_client.h
@@ -0,0 +1,333 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
+#define CHROMEOS_ASH_COMPONENTS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
+
+#include <deque>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/component_export.h"
+#include "base/time/time.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
+
+namespace dbus {
+class Bus;
+}
+
+namespace ash {
+
+// AttestationClient is used to communicate with the org.chromium.Attestation
+// service. All method should be called from the origin thread (UI thread) which
+// initializes the DBusThreadManager instance.
+class COMPONENT_EXPORT(ASH_DBUS_ATTESTATION) AttestationClient {
+ public:
+  using GetKeyInfoCallback =
+      base::OnceCallback<void(const ::attestation::GetKeyInfoReply&)>;
+  using GetEndorsementInfoCallback =
+      base::OnceCallback<void(const ::attestation::GetEndorsementInfoReply&)>;
+  using GetAttestationKeyInfoCallback = base::OnceCallback<void(
+      const ::attestation::GetAttestationKeyInfoReply&)>;
+  using ActivateAttestationKeyCallback = base::OnceCallback<void(
+      const ::attestation::ActivateAttestationKeyReply&)>;
+  using CreateCertifiableKeyCallback =
+      base::OnceCallback<void(const ::attestation::CreateCertifiableKeyReply&)>;
+  using DecryptCallback =
+      base::OnceCallback<void(const ::attestation::DecryptReply&)>;
+  using SignCallback =
+      base::OnceCallback<void(const ::attestation::SignReply&)>;
+  using RegisterKeyWithChapsTokenCallback = base::OnceCallback<void(
+      const ::attestation::RegisterKeyWithChapsTokenReply&)>;
+  using GetEnrollmentPreparationsCallback = base::OnceCallback<void(
+      const ::attestation::GetEnrollmentPreparationsReply&)>;
+  using GetStatusCallback =
+      base::OnceCallback<void(const ::attestation::GetStatusReply&)>;
+  using VerifyCallback =
+      base::OnceCallback<void(const ::attestation::VerifyReply&)>;
+  using CreateEnrollRequestCallback =
+      base::OnceCallback<void(const ::attestation::CreateEnrollRequestReply&)>;
+  using FinishEnrollCallback =
+      base::OnceCallback<void(const ::attestation::FinishEnrollReply&)>;
+  using CreateCertificateRequestCallback = base::OnceCallback<void(
+      const ::attestation::CreateCertificateRequestReply&)>;
+  using FinishCertificateRequestCallback = base::OnceCallback<void(
+      const ::attestation::FinishCertificateRequestReply&)>;
+  using EnrollCallback =
+      base::OnceCallback<void(const ::attestation::EnrollReply&)>;
+  using GetCertificateCallback =
+      base::OnceCallback<void(const ::attestation::GetCertificateReply&)>;
+  using SignEnterpriseChallengeCallback = base::OnceCallback<void(
+      const ::attestation::SignEnterpriseChallengeReply&)>;
+  using SignSimpleChallengeCallback =
+      base::OnceCallback<void(const ::attestation::SignSimpleChallengeReply&)>;
+  using SetKeyPayloadCallback =
+      base::OnceCallback<void(const ::attestation::SetKeyPayloadReply&)>;
+  using DeleteKeysCallback =
+      base::OnceCallback<void(const ::attestation::DeleteKeysReply&)>;
+  using ResetIdentityCallback =
+      base::OnceCallback<void(const ::attestation::ResetIdentityReply&)>;
+  using GetEnrollmentIdCallback =
+      base::OnceCallback<void(const ::attestation::GetEnrollmentIdReply&)>;
+  using GetCertifiedNvIndexCallback =
+      base::OnceCallback<void(const ::attestation::GetCertifiedNvIndexReply&)>;
+
+  // Interface with testing functionality. Accessed through GetTestInterface(),
+  // only implemented in the fake implementation.
+  class TestInterface {
+   public:
+    // Sets the preparation status to |is_prepared|. If no injected sequence by
+    // |ConfigureEnrollmentPreparationsSequence| the enrollment preparations
+    // always returns |is_prepared|.
+    virtual void ConfigureEnrollmentPreparations(bool is_prepared) = 0;
+    // Injects |sequence| of enrollment preparations. Once injected, the
+    // returned enrollment preparations status will be the element popped from
+    // the |sequence| one-by-one until all the elements are consumed.
+    virtual void ConfigureEnrollmentPreparationsSequence(
+        std::deque<bool> sequence) = 0;
+    // Injects a bad status to `GetEnrollmentPreparations()` calls. By design,
+    // this only accepts bad status so |STATUS_SUCCESS| is seen as an illegal
+    // input and abort the program. To recover the fake behavior to successful
+    // calls, call ConfigureEnrollmentPreparations(Sequence)?.
+    virtual void ConfigureEnrollmentPreparationsStatus(
+        ::attestation::AttestationStatus status) = 0;
+
+    // Gets the mutable |GetStatusReply| that is returned when queried.
+    virtual ::attestation::GetStatusReply* mutable_status_reply() = 0;
+
+    // Allowlists |request| so the certificate requests that comes in afterwards
+    // will get a fake certificate. If any alias of |request| has been
+    // allowlisted this functions performs no-ops.
+    virtual void AllowlistCertificateRequest(
+        const ::attestation::GetCertificateRequest& request) = 0;
+
+    // Gets the history of `DeleteKeys()` requests.
+    virtual const std::vector<::attestation::DeleteKeysRequest>&
+    delete_keys_history() const = 0;
+
+    // Clears the request history of `DeleteKeys()`.
+    virtual void ClearDeleteKeysHistory() = 0;
+
+    // Sets returned enrollment ids, when ignoring/not ignoring cache,
+    // respectively.
+    virtual void set_enrollment_id_ignore_cache(const std::string& id) = 0;
+    virtual void set_cached_enrollment_id(const std::string& id) = 0;
+    // Sets the returned status of `GetEnrollmentId()` to be D-Bus error for
+    // `count` times to emulate D-Bus late availability.
+    virtual void set_enrollment_id_dbus_error_count(int count) = 0;
+
+    // Gets the reply to the key info query as a fake database.
+    virtual ::attestation::GetKeyInfoReply* GetMutableKeyInfoReply(
+        const std::string& username,
+        const std::string& label) = 0;
+    // Sets the returned status of `GetKeyInfo()` to be D-Bus error for
+    // `count` times to emulate D-Bus late availability.
+    virtual void set_key_info_dbus_error_count(int count) = 0;
+    // Gets the remaining count of `GetKeyInfo()` replying D-Bus error.
+    virtual int key_info_dbus_error_count() const = 0;
+
+    // Verifies if `signed_data` is signed against `challenge`.
+    virtual bool VerifySimpleChallengeResponse(
+        const std::string& challenge,
+        const ::attestation::SignedData& signed_data) = 0;
+
+    // Sets the status code returned by `SignSimpleChallenge()`.
+    virtual void set_sign_simple_challenge_status(
+        ::attestation::AttestationStatus status) = 0;
+    // Allowlists the key used to sign simple challenge.
+    virtual void AllowlistSignSimpleChallengeKey(const std::string& username,
+                                                 const std::string& label) = 0;
+
+    // Sets the status code returned by `Sign()`.
+    virtual void set_sign_status(::attestation::AttestationStatus status) = 0;
+
+    // Sets the status code returned by `RegisterKeyWithChapsToken()`.
+    virtual void set_register_key_status(
+        ::attestation::AttestationStatus status) = 0;
+    // Allowlists the key allowed to be registered to the key store.
+    virtual void AllowlistRegisterKey(const std::string& username,
+                                      const std::string& label) = 0;
+
+    // Sets the status code returned by `SignEnterpriseChallenge()`.
+    virtual void set_sign_enterprise_challenge_status(
+        ::attestation::AttestationStatus status) = 0;
+    // Allowlists the key used to sign enterprise challenge. Note that
+    // `include_signed_public_key` and `challenge` are ignored for key
+    // comparison because they are are part of the key but the inputs for
+    // signature generation.
+    virtual void AllowlistSignEnterpriseChallengeKey(
+        const ::attestation::SignEnterpriseChallengeRequest& request) = 0;
+    // Signs the enterprise `challenge` with this class the same way the
+    // enterprise challenge is signed.
+    virtual std::string GetEnterpriseChallengeFakeSignature(
+        const std::string& challenge,
+        bool include_spkac) const = 0;
+    // Sets the delay to the time we reply to `SignEnterpriseChallenge()`.
+    virtual void set_sign_enterprise_challenge_delay(
+        const base::TimeDelta& delay) = 0;
+
+    // Sets the allowed ACA type for the legacy attestation flow. The enroll
+    // request can be created/finished only if the ACA type matches the set ACA
+    // type. By default, it is default ACA.
+    virtual void set_aca_type_for_legacy_flow(
+        ::attestation::ACAType aca_type) = 0;
+
+    // Sets the status code returned by `CreateEnrollRequestRequest()`.
+    virtual void set_enroll_request_status(
+        ::attestation::AttestationStatus status) = 0;
+    // Gets the fake enroll request when the status is configured to be good.
+    virtual std::string GetFakePcaEnrollRequest() const = 0;
+    // Gets the fake enroll response that is accepted by `FinishEnroll()`.
+    virtual std::string GetFakePcaEnrollResponse() const = 0;
+
+    // Allowlists the request that has `username`, `request_origin`, `profile`,
+    // and `key_type`, so the certificate requests that comes in afterwards will
+    // be successfully created.
+    virtual void AllowlistLegacyCreateCertificateRequest(
+        const std::string& username,
+        const std::string& request_origin,
+        ::attestation::CertificateProfile profile,
+        ::attestation::KeyType key_type) = 0;
+    // Sets the status code returned by `CreateCertificateRequest()`.
+    virtual void set_cert_request_status(
+        ::attestation::AttestationStatus status) = 0;
+    // Gets the fake certificate request when the status is configured to be
+    // good.
+    virtual std::string GetFakePcaCertRequest() const = 0;
+    // Gets the fake enroll response that is accepted by
+    // `FinishCertificateRequest()`.
+    virtual std::string GetFakePcaCertResponse() const = 0;
+    // Gets the fake certificate that is returned by
+    // successful `FinishCertificateRequest()`.
+    virtual std::string GetFakeCertificate() const = 0;
+  };
+
+  // Not copyable or movable.
+  AttestationClient(const AttestationClient&) = delete;
+  AttestationClient& operator=(const AttestationClient&) = delete;
+  AttestationClient(AttestationClient&&) = delete;
+  AttestationClient& operator=(AttestationClient&&) = delete;
+
+  // Creates and initializes the global instance. |bus| must not be null.
+  static void Initialize(dbus::Bus* bus);
+
+  // Creates and initializes a fake global instance if not already created.
+  static void InitializeFake();
+
+  // Destroys the global instance.
+  static void Shutdown();
+
+  // Returns the global instance which may be null if not initialized.
+  static AttestationClient* Get();
+
+  // Checks if |reply| indicates the attestation service is prepared with any
+  // ACA.
+  static bool IsAttestationPrepared(
+      const ::attestation::GetEnrollmentPreparationsReply& reply);
+
+  // Gets the verified access server type from command-line arguments.
+  static ::attestation::VAType GetVerifiedAccessServerType();
+
+  // Attestation daemon D-Bus method calls. See org.chromium.Attestation.xml and
+  // the corresponding protobuf definitions in Chromium OS code for the
+  // documentation of the methods and request/ messages.
+
+  virtual void GetKeyInfo(const ::attestation::GetKeyInfoRequest& request,
+                          GetKeyInfoCallback callback) = 0;
+
+  virtual void GetEndorsementInfo(
+      const ::attestation::GetEndorsementInfoRequest& request,
+      GetEndorsementInfoCallback callback) = 0;
+
+  virtual void GetAttestationKeyInfo(
+      const ::attestation::GetAttestationKeyInfoRequest& request,
+      GetAttestationKeyInfoCallback callback) = 0;
+
+  virtual void ActivateAttestationKey(
+      const ::attestation::ActivateAttestationKeyRequest& request,
+      ActivateAttestationKeyCallback callback) = 0;
+
+  virtual void CreateCertifiableKey(
+      const ::attestation::CreateCertifiableKeyRequest& request,
+      CreateCertifiableKeyCallback callback) = 0;
+
+  virtual void Decrypt(const ::attestation::DecryptRequest& request,
+                       DecryptCallback callback) = 0;
+
+  virtual void Sign(const ::attestation::SignRequest& request,
+                    SignCallback callback) = 0;
+
+  virtual void RegisterKeyWithChapsToken(
+      const ::attestation::RegisterKeyWithChapsTokenRequest& request,
+      RegisterKeyWithChapsTokenCallback callback) = 0;
+
+  virtual void GetEnrollmentPreparations(
+      const ::attestation::GetEnrollmentPreparationsRequest& request,
+      GetEnrollmentPreparationsCallback callback) = 0;
+
+  virtual void GetStatus(const ::attestation::GetStatusRequest& request,
+                         GetStatusCallback callback) = 0;
+
+  virtual void Verify(const ::attestation::VerifyRequest& request,
+                      VerifyCallback callback) = 0;
+
+  virtual void CreateEnrollRequest(
+      const ::attestation::CreateEnrollRequestRequest& request,
+      CreateEnrollRequestCallback callback) = 0;
+
+  virtual void FinishEnroll(const ::attestation::FinishEnrollRequest& request,
+                            FinishEnrollCallback callback) = 0;
+
+  virtual void CreateCertificateRequest(
+      const ::attestation::CreateCertificateRequestRequest& request,
+      CreateCertificateRequestCallback callback) = 0;
+
+  virtual void FinishCertificateRequest(
+      const ::attestation::FinishCertificateRequestRequest& request,
+      FinishCertificateRequestCallback callback) = 0;
+
+  virtual void Enroll(const ::attestation::EnrollRequest& request,
+                      EnrollCallback callback) = 0;
+
+  virtual void GetCertificate(
+      const ::attestation::GetCertificateRequest& request,
+      GetCertificateCallback callback) = 0;
+
+  virtual void SignEnterpriseChallenge(
+      const ::attestation::SignEnterpriseChallengeRequest& request,
+      SignEnterpriseChallengeCallback callback) = 0;
+
+  virtual void SignSimpleChallenge(
+      const ::attestation::SignSimpleChallengeRequest& request,
+      SignSimpleChallengeCallback callback) = 0;
+
+  virtual void SetKeyPayload(const ::attestation::SetKeyPayloadRequest& request,
+                             SetKeyPayloadCallback callback) = 0;
+
+  virtual void DeleteKeys(const ::attestation::DeleteKeysRequest& request,
+                          DeleteKeysCallback callback) = 0;
+
+  virtual void ResetIdentity(const ::attestation::ResetIdentityRequest& request,
+                             ResetIdentityCallback callback) = 0;
+
+  virtual void GetEnrollmentId(
+      const ::attestation::GetEnrollmentIdRequest& request,
+      GetEnrollmentIdCallback callback) = 0;
+
+  virtual void GetCertifiedNvIndex(
+      const ::attestation::GetCertifiedNvIndexRequest& request,
+      GetCertifiedNvIndexCallback callback) = 0;
+
+  // Returns an interface for testing (fake only), or returns nullptr.
+  virtual TestInterface* GetTestInterface() = 0;
+
+ protected:
+  // Initialize/Shutdown should be used instead.
+  AttestationClient();
+  virtual ~AttestationClient();
+};
+
+}  // namespace ash
+
+#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
diff --git a/chromeos/ash/components/dbus/attestation/fake_attestation_client.cc b/chromeos/ash/components/dbus/attestation/fake_attestation_client.cc
new file mode 100644
index 0000000..07368d06
--- /dev/null
+++ b/chromeos/ash/components/dbus/attestation/fake_attestation_client.cc
@@ -0,0 +1,566 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/ash/components/dbus/attestation/fake_attestation_client.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "third_party/cros_system_api/dbus/attestation/dbus-constants.h"
+
+namespace ash {
+namespace {
+
+constexpr int kCertificateNotAssigned = 0;
+constexpr char kFakeCertPrefix[] = "fake cert";
+constexpr char kResponseSuffix[] = "_response";
+constexpr char kSignatureSuffix[] = "_signature";
+constexpr char kEnterpriseChallengeResponseSuffix[] = "enterprise_challenge";
+constexpr char kIncludeSpkacSuffix[] = "_with_spkac";
+constexpr char kFakePcaEnrollRequest[] = "fake enroll request";
+constexpr char kFakePcaEnrollResponse[] = "fake enroll response";
+constexpr char kFakePcaCertRequest[] = "fake cert request";
+constexpr char kFakePcaCertResponse[] = "fake cert response";
+constexpr char kFakeCertificate[] = "fake certificate";
+
+// Posts `callback` on the current thread's task runner, passing it the
+// `reply` message.
+template <class ReplyType>
+void PostProtoResponse(base::OnceCallback<void(const ReplyType&)> callback,
+                       const ReplyType& reply) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(std::move(callback), reply));
+}
+
+// Posts `callback` on the current thread's task runner, passing it the
+// `reply` message with `delay`.
+template <class ReplyType>
+void PostProtoResponseWithDelay(
+    base::OnceCallback<void(const ReplyType&)> callback,
+    const ReplyType& reply,
+    const base::TimeDelta& delay) {
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, base::BindOnce(std::move(callback), reply), delay);
+}
+
+bool GetCertificateRequestEqual(::attestation::GetCertificateRequest r1,
+                                ::attestation::GetCertificateRequest r2) {
+  // To prevent regression from future expansion to |GetCertificateRequest|, we
+  // compare their serialized results so the difference doesn't get away from
+  // this function. We can't really make use of
+  // |google::protobuf::util::MessageDifferencer|, which doesn't apply to
+  // |MessageLite|.
+
+  // |shall_trigger_enrollment| and |forced| shouldn't affect the whilelisting.
+  r1.clear_forced();
+  r2.clear_forced();
+  r1.clear_shall_trigger_enrollment();
+  r2.clear_shall_trigger_enrollment();
+  return r1.SerializeAsString() == r2.SerializeAsString();
+}
+
+}  // namespace
+
+FakeAttestationClient::FakeAttestationClient() {
+  status_reply_.set_enrolled(true);
+}
+
+FakeAttestationClient::~FakeAttestationClient() = default;
+
+void FakeAttestationClient::GetKeyInfo(
+    const ::attestation::GetKeyInfoRequest& request,
+    GetKeyInfoCallback callback) {
+  ::attestation::GetKeyInfoReply reply;
+  if (key_info_dbus_error_count_ > 0) {
+    reply.set_status(::attestation::STATUS_DBUS_ERROR);
+    key_info_dbus_error_count_--;
+  } else {
+    auto iter = key_info_database_.find(request);
+    if (iter != key_info_database_.end()) {
+      reply = iter->second;
+    } else {
+      reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
+    }
+  }
+
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::GetEndorsementInfo(
+    const ::attestation::GetEndorsementInfoRequest& request,
+    GetEndorsementInfoCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::GetAttestationKeyInfo(
+    const ::attestation::GetAttestationKeyInfoRequest& request,
+    GetAttestationKeyInfoCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::ActivateAttestationKey(
+    const ::attestation::ActivateAttestationKeyRequest& request,
+    ActivateAttestationKeyCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::CreateCertifiableKey(
+    const ::attestation::CreateCertifiableKeyRequest& request,
+    CreateCertifiableKeyCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::Decrypt(
+    const ::attestation::DecryptRequest& request,
+    DecryptCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::Sign(const ::attestation::SignRequest& request,
+                                 SignCallback callback) {
+  ::attestation::SignReply reply;
+  reply.set_status(sign_status_);
+  if (reply.status() == ::attestation::STATUS_SUCCESS) {
+    reply.set_signature(kSignatureSuffix);
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::RegisterKeyWithChapsToken(
+    const ::attestation::RegisterKeyWithChapsTokenRequest& request,
+    RegisterKeyWithChapsTokenCallback callback) {
+  ::attestation::RegisterKeyWithChapsTokenReply reply;
+  if (allowlisted_register_keys_.count(
+          {request.username(), request.key_label()}) == 0) {
+    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
+  } else {
+    reply.set_status(register_key_status_);
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::GetEnrollmentPreparations(
+    const ::attestation::GetEnrollmentPreparationsRequest& request,
+    GetEnrollmentPreparationsCallback callback) {
+  ::attestation::GetEnrollmentPreparationsReply reply;
+  reply.set_status(preparations_status_);
+
+  if (reply.status() == ::attestation::STATUS_SUCCESS) {
+    bool is_prepared = is_prepared_;
+    // Override the state if there is a customized sequence.
+    if (!preparation_sequences_.empty()) {
+      is_prepared = preparation_sequences_.front();
+      preparation_sequences_.pop_front();
+    }
+    if (is_prepared) {
+      std::vector<::attestation::ACAType> prepared_types;
+      // As we do in the attestation service, if the ACA type is not specified,
+      // returns the statuses with all the possible ACA types.
+      if (request.has_aca_type()) {
+        prepared_types = {request.aca_type()};
+      } else {
+        prepared_types = {::attestation::DEFAULT_ACA, ::attestation::TEST_ACA};
+      }
+      for (const auto& type : prepared_types) {
+        (*reply.mutable_enrollment_preparations())[type] = true;
+      }
+    }
+  }
+
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::GetStatus(
+    const ::attestation::GetStatusRequest& request,
+    GetStatusCallback callback) {
+  PostProtoResponse(std::move(callback), status_reply_);
+}
+
+void FakeAttestationClient::Verify(const ::attestation::VerifyRequest& request,
+                                   VerifyCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::CreateEnrollRequest(
+    const ::attestation::CreateEnrollRequestRequest& request,
+    CreateEnrollRequestCallback callback) {
+  ::attestation::CreateEnrollRequestReply reply;
+  reply.set_status(enroll_request_status_);
+  if (aca_type_for_legacy_mode_ != request.aca_type()) {
+    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
+  }
+  if (reply.status() == ::attestation::STATUS_SUCCESS) {
+    reply.set_pca_request(GetFakePcaEnrollRequest());
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::FinishEnroll(
+    const ::attestation::FinishEnrollRequest& request,
+    FinishEnrollCallback callback) {
+  ::attestation::FinishEnrollReply reply;
+  reply.set_status(request.pca_response() == GetFakePcaEnrollResponse()
+                       ? ::attestation::STATUS_SUCCESS
+                       : ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
+  if (aca_type_for_legacy_mode_ != request.aca_type()) {
+    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::CreateCertificateRequest(
+    const ::attestation::CreateCertificateRequestRequest& request,
+    CreateCertificateRequestCallback callback) {
+  ::attestation::CreateCertificateRequestReply reply;
+  reply.set_status(cert_request_status_);
+  if (aca_type_for_legacy_mode_ != request.aca_type()) {
+    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
+  }
+  if (reply.status() != ::attestation::STATUS_SUCCESS) {
+    PostProtoResponse(std::move(callback), reply);
+    return;
+  }
+  for (const auto& req : allowlisted_create_requests_) {
+    if (req.username() == request.username() &&
+        req.request_origin() == request.request_origin() &&
+        req.certificate_profile() == request.certificate_profile() &&
+        req.key_type() == request.key_type()) {
+      reply.set_pca_request(GetFakePcaCertRequest());
+      PostProtoResponse(std::move(callback), reply);
+      return;
+    }
+  }
+  reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::FinishCertificateRequest(
+    const ::attestation::FinishCertificateRequestRequest& request,
+    FinishCertificateRequestCallback callback) {
+  ::attestation::FinishCertificateRequestReply reply;
+  if (request.pca_response() != GetFakePcaCertResponse()) {
+    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
+  }
+  if (reply.status() == ::attestation::STATUS_SUCCESS) {
+    reply.set_certificate(GetFakeCertificate());
+    // Also, insert the certificate into the fake database.
+    GetMutableKeyInfoReply(request.username(), request.key_label())
+        ->set_certificate(GetFakeCertificate());
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::Enroll(const ::attestation::EnrollRequest& request,
+                                   EnrollCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::GetCertificate(
+    const ::attestation::GetCertificateRequest& request,
+    GetCertificateCallback callback) {
+  ::attestation::GetCertificateReply reply;
+  reply.set_status(
+      ::attestation::AttestationStatus::STATUS_UNEXPECTED_DEVICE_ERROR);
+
+  if (request.shall_trigger_enrollment()) {
+    status_reply_.set_enrolled(true);
+  }
+  if (!status_reply_.enrolled()) {
+    PostProtoResponse(std::move(callback), reply);
+    return;
+  }
+
+  for (size_t i = 0; i < allowlisted_requests_.size(); ++i) {
+    if (GetCertificateRequestEqual(allowlisted_requests_[i], request)) {
+      if (request.forced() ||
+          certificate_indices_[i] == kCertificateNotAssigned) {
+        ++certificate_count_;
+        certificate_indices_[i] = certificate_count_;
+      }
+      reply.set_status(::attestation::AttestationStatus::STATUS_SUCCESS);
+      reply.set_certificate(kFakeCertPrefix +
+                            base::NumberToString(certificate_indices_[i]));
+      break;
+    }
+  }
+
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::SignEnterpriseChallenge(
+    const ::attestation::SignEnterpriseChallengeRequest& request,
+    SignEnterpriseChallengeCallback callback) {
+  ::attestation::SignEnterpriseChallengeReply reply;
+  if (allowlisted_sign_enterprise_challenge_keys_.count(request) == 0) {
+    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
+  } else {
+    reply.set_status(sign_enterprise_challenge_status_);
+  }
+  if (reply.status() == ::attestation::STATUS_SUCCESS) {
+    reply.set_challenge_response(GetEnterpriseChallengeFakeSignature(
+        request.challenge(), request.include_signed_public_key()));
+  }
+  PostProtoResponseWithDelay(std::move(callback), reply,
+                             sign_enterprise_challenge_delay_);
+}
+
+void FakeAttestationClient::SignSimpleChallenge(
+    const ::attestation::SignSimpleChallengeRequest& request,
+    SignSimpleChallengeCallback callback) {
+  ::attestation::SignSimpleChallengeReply reply;
+  if (allowlisted_sign_simple_challenge_keys_.count(
+          {request.username(), request.key_label()}) == 0) {
+    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
+  } else {
+    reply.set_status(sign_simple_challenge_status_);
+  }
+  if (reply.status() == ::attestation::STATUS_SUCCESS) {
+    ::attestation::SignedData signed_data;
+    signed_data.set_data(request.challenge() + kResponseSuffix);
+    signed_data.set_signature(request.challenge() + kSignatureSuffix);
+    reply.set_challenge_response(signed_data.SerializeAsString());
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::SetKeyPayload(
+    const ::attestation::SetKeyPayloadRequest& request,
+    SetKeyPayloadCallback callback) {
+  ::attestation::GetKeyInfoRequest get_key_info_request;
+  get_key_info_request.set_username(request.username());
+  get_key_info_request.set_key_label(request.key_label());
+  auto iter = key_info_database_.find(get_key_info_request);
+  ::attestation::SetKeyPayloadReply reply;
+  if (iter == key_info_database_.end()) {
+    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
+  } else {
+    iter->second.set_payload(request.payload());
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::DeleteKeys(
+    const ::attestation::DeleteKeysRequest& request,
+    DeleteKeysCallback callback) {
+  delete_keys_history_.push_back(request);
+  ::attestation::DeleteKeysReply reply;
+  reply.set_status(::attestation::STATUS_SUCCESS);
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::ResetIdentity(
+    const ::attestation::ResetIdentityRequest& request,
+    ResetIdentityCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::GetEnrollmentId(
+    const ::attestation::GetEnrollmentIdRequest& request,
+    GetEnrollmentIdCallback callback) {
+  ::attestation::GetEnrollmentIdReply reply;
+  if (enrollment_id_dbus_error_count_ != 0) {
+    reply.set_status(::attestation::STATUS_DBUS_ERROR);
+    enrollment_id_dbus_error_count_--;
+  } else {
+    reply.set_status(::attestation::STATUS_SUCCESS);
+    reply.set_enrollment_id(request.ignore_cache() ? enrollment_id_ignore_cache_
+                                                   : enrollment_id_);
+  }
+  PostProtoResponse(std::move(callback), reply);
+}
+
+void FakeAttestationClient::GetCertifiedNvIndex(
+    const ::attestation::GetCertifiedNvIndexRequest& request,
+    GetCertifiedNvIndexCallback callback) {
+  NOTIMPLEMENTED();
+}
+
+void FakeAttestationClient::ConfigureEnrollmentPreparations(bool is_prepared) {
+  preparations_status_ = ::attestation::STATUS_SUCCESS;
+  is_prepared_ = is_prepared;
+}
+
+void FakeAttestationClient::ConfigureEnrollmentPreparationsSequence(
+    std::deque<bool> sequence) {
+  preparations_status_ = ::attestation::STATUS_SUCCESS;
+  preparation_sequences_ = std::move(sequence);
+}
+
+void FakeAttestationClient::ConfigureEnrollmentPreparationsStatus(
+    ::attestation::AttestationStatus status) {
+  CHECK_NE(status, ::attestation::STATUS_SUCCESS);
+  preparations_status_ = status;
+}
+
+::attestation::GetStatusReply* FakeAttestationClient::mutable_status_reply() {
+  return &status_reply_;
+}
+
+void FakeAttestationClient::AllowlistCertificateRequest(
+    const ::attestation::GetCertificateRequest& request) {
+  for (const auto& req : allowlisted_requests_) {
+    if (GetCertificateRequestEqual(req, request)) {
+      return;
+    }
+  }
+  allowlisted_requests_.push_back(request);
+  certificate_indices_.push_back(kCertificateNotAssigned);
+}
+
+const std::vector<::attestation::DeleteKeysRequest>&
+FakeAttestationClient::delete_keys_history() const {
+  return delete_keys_history_;
+}
+
+void FakeAttestationClient::ClearDeleteKeysHistory() {
+  delete_keys_history_.clear();
+}
+
+void FakeAttestationClient::set_enrollment_id_ignore_cache(
+    const std::string& id) {
+  enrollment_id_ignore_cache_ = id;
+}
+
+void FakeAttestationClient::set_cached_enrollment_id(const std::string& id) {
+  enrollment_id_ = id;
+}
+
+void FakeAttestationClient::set_enrollment_id_dbus_error_count(int count) {
+  enrollment_id_dbus_error_count_ = count;
+}
+
+::attestation::GetKeyInfoReply* FakeAttestationClient::GetMutableKeyInfoReply(
+    const std::string& username,
+    const std::string& label) {
+  ::attestation::GetKeyInfoRequest request;
+  request.set_username(username);
+  request.set_key_label(label);
+  // If there doesn't exist the entry yet, just create a new one.
+  return &(key_info_database_[request]);
+}
+
+void FakeAttestationClient::set_key_info_dbus_error_count(int count) {
+  key_info_dbus_error_count_ = count;
+}
+
+int FakeAttestationClient::key_info_dbus_error_count() const {
+  return key_info_dbus_error_count_;
+}
+
+bool FakeAttestationClient::VerifySimpleChallengeResponse(
+    const std::string& challenge,
+    const ::attestation::SignedData& signed_data) {
+  return signed_data.data() == challenge + kResponseSuffix &&
+         signed_data.signature() == challenge + kSignatureSuffix;
+}
+
+void FakeAttestationClient::set_sign_simple_challenge_status(
+    ::attestation::AttestationStatus status) {
+  sign_simple_challenge_status_ = status;
+}
+
+void FakeAttestationClient::set_sign_status(
+    ::attestation::AttestationStatus status) {
+  sign_status_ = status;
+}
+
+void FakeAttestationClient::AllowlistSignSimpleChallengeKey(
+    const std::string& username,
+    const std::string& label) {
+  allowlisted_sign_simple_challenge_keys_.insert({username, label});
+}
+
+void FakeAttestationClient::set_register_key_status(
+    ::attestation::AttestationStatus status) {
+  register_key_status_ = status;
+}
+
+void FakeAttestationClient::AllowlistRegisterKey(const std::string& username,
+                                                 const std::string& label) {
+  allowlisted_register_keys_.insert({username, label});
+}
+
+void FakeAttestationClient::set_sign_enterprise_challenge_status(
+    ::attestation::AttestationStatus status) {
+  sign_enterprise_challenge_status_ = status;
+}
+
+void FakeAttestationClient::AllowlistSignEnterpriseChallengeKey(
+    const ::attestation::SignEnterpriseChallengeRequest& request) {
+  allowlisted_sign_enterprise_challenge_keys_.insert(request);
+}
+
+std::string FakeAttestationClient::GetEnterpriseChallengeFakeSignature(
+    const std::string& challenge,
+    bool include_spkac) const {
+  std::string challenge_response =
+      challenge + kEnterpriseChallengeResponseSuffix;
+  if (include_spkac) {
+    challenge_response += kIncludeSpkacSuffix;
+  }
+  return challenge_response;
+}
+
+void FakeAttestationClient::set_sign_enterprise_challenge_delay(
+    const base::TimeDelta& delay) {
+  sign_enterprise_challenge_delay_ = delay;
+}
+
+void FakeAttestationClient::set_aca_type_for_legacy_flow(
+    ::attestation::ACAType aca_type) {
+  aca_type_for_legacy_mode_ = aca_type;
+}
+
+void FakeAttestationClient::set_enroll_request_status(
+    ::attestation::AttestationStatus status) {
+  enroll_request_status_ = status;
+}
+
+std::string FakeAttestationClient::GetFakePcaEnrollRequest() const {
+  return kFakePcaEnrollRequest;
+}
+
+std::string FakeAttestationClient::GetFakePcaEnrollResponse() const {
+  return kFakePcaEnrollResponse;
+}
+
+void FakeAttestationClient::AllowlistLegacyCreateCertificateRequest(
+    const std::string& username,
+    const std::string& request_origin,
+    ::attestation::CertificateProfile profile,
+    ::attestation::KeyType key_type) {
+  ::attestation::CreateCertificateRequestRequest request;
+  request.set_username(username);
+  request.set_request_origin(request_origin);
+  request.set_certificate_profile(profile);
+  request.set_key_type(key_type);
+  allowlisted_create_requests_.push_back(request);
+}
+
+void FakeAttestationClient::set_cert_request_status(
+    ::attestation::AttestationStatus status) {
+  cert_request_status_ = status;
+}
+
+std::string FakeAttestationClient::GetFakePcaCertRequest() const {
+  return kFakePcaCertRequest;
+}
+
+std::string FakeAttestationClient::GetFakePcaCertResponse() const {
+  return kFakePcaCertResponse;
+}
+
+std::string FakeAttestationClient::GetFakeCertificate() const {
+  return kFakeCertificate;
+}
+
+AttestationClient::TestInterface* FakeAttestationClient::GetTestInterface() {
+  return this;
+}
+
+}  // namespace ash
diff --git a/chromeos/ash/components/dbus/attestation/fake_attestation_client.h b/chromeos/ash/components/dbus/attestation/fake_attestation_client.h
new file mode 100644
index 0000000..8852c51
--- /dev/null
+++ b/chromeos/ash/components/dbus/attestation/fake_attestation_client.h
@@ -0,0 +1,260 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_ATTESTATION_FAKE_ATTESTATION_CLIENT_H_
+#define CHROMEOS_ASH_COMPONENTS_DBUS_ATTESTATION_FAKE_ATTESTATION_CLIENT_H_
+
+#include "chromeos/ash/components/dbus/attestation/attestation_client.h"
+
+#include <deque>
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/component_export.h"
+#include "base/time/time.h"
+#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
+#include "dbus/object_proxy.h"
+
+namespace ash {
+
+class COMPONENT_EXPORT(ASH_DBUS_ATTESTATION) FakeAttestationClient
+    : public AttestationClient,
+      public AttestationClient::TestInterface {
+ public:
+  FakeAttestationClient();
+  ~FakeAttestationClient() override;
+
+  // Not copyable or movable.
+  FakeAttestationClient(const FakeAttestationClient&) = delete;
+  FakeAttestationClient& operator=(const FakeAttestationClient&) = delete;
+  FakeAttestationClient(FakeAttestationClient&&) = delete;
+  FakeAttestationClient& operator=(FakeAttestationClient&&) = delete;
+
+  // AttestationClient:
+  void GetKeyInfo(const ::attestation::GetKeyInfoRequest& request,
+                  GetKeyInfoCallback callback) override;
+  void GetEndorsementInfo(
+      const ::attestation::GetEndorsementInfoRequest& request,
+      GetEndorsementInfoCallback callback) override;
+  void GetAttestationKeyInfo(
+      const ::attestation::GetAttestationKeyInfoRequest& request,
+      GetAttestationKeyInfoCallback callback) override;
+  void ActivateAttestationKey(
+      const ::attestation::ActivateAttestationKeyRequest& request,
+      ActivateAttestationKeyCallback callback) override;
+  void CreateCertifiableKey(
+      const ::attestation::CreateCertifiableKeyRequest& request,
+      CreateCertifiableKeyCallback callback) override;
+  void Decrypt(const ::attestation::DecryptRequest& request,
+               DecryptCallback callback) override;
+  void Sign(const ::attestation::SignRequest& request,
+            SignCallback callback) override;
+  void RegisterKeyWithChapsToken(
+      const ::attestation::RegisterKeyWithChapsTokenRequest& request,
+      RegisterKeyWithChapsTokenCallback callback) override;
+  void GetEnrollmentPreparations(
+      const ::attestation::GetEnrollmentPreparationsRequest& request,
+      GetEnrollmentPreparationsCallback callback) override;
+  void GetStatus(const ::attestation::GetStatusRequest& request,
+                 GetStatusCallback callback) override;
+  void Verify(const ::attestation::VerifyRequest& request,
+              VerifyCallback callback) override;
+  void CreateEnrollRequest(
+      const ::attestation::CreateEnrollRequestRequest& request,
+      CreateEnrollRequestCallback callback) override;
+  void FinishEnroll(const ::attestation::FinishEnrollRequest& request,
+                    FinishEnrollCallback callback) override;
+  void CreateCertificateRequest(
+      const ::attestation::CreateCertificateRequestRequest& request,
+      CreateCertificateRequestCallback callback) override;
+  void FinishCertificateRequest(
+      const ::attestation::FinishCertificateRequestRequest& request,
+      FinishCertificateRequestCallback callback) override;
+  void Enroll(const ::attestation::EnrollRequest& request,
+              EnrollCallback callback) override;
+  void GetCertificate(const ::attestation::GetCertificateRequest& request,
+                      GetCertificateCallback callback) override;
+  void SignEnterpriseChallenge(
+      const ::attestation::SignEnterpriseChallengeRequest& request,
+      SignEnterpriseChallengeCallback callback) override;
+  void SignSimpleChallenge(
+      const ::attestation::SignSimpleChallengeRequest& request,
+      SignSimpleChallengeCallback callback) override;
+  void SetKeyPayload(const ::attestation::SetKeyPayloadRequest& request,
+                     SetKeyPayloadCallback callback) override;
+  void DeleteKeys(const ::attestation::DeleteKeysRequest& request,
+                  DeleteKeysCallback callback) override;
+  void ResetIdentity(const ::attestation::ResetIdentityRequest& request,
+                     ResetIdentityCallback callback) override;
+  void GetEnrollmentId(const ::attestation::GetEnrollmentIdRequest& request,
+                       GetEnrollmentIdCallback callback) override;
+  void GetCertifiedNvIndex(
+      const ::attestation::GetCertifiedNvIndexRequest& request,
+      GetCertifiedNvIndexCallback callback) override;
+
+  // AttestationClient::TestInterface:
+  void ConfigureEnrollmentPreparations(bool is_prepared) override;
+  void ConfigureEnrollmentPreparationsSequence(
+      std::deque<bool> sequence) override;
+  void ConfigureEnrollmentPreparationsStatus(
+      ::attestation::AttestationStatus status) override;
+  ::attestation::GetStatusReply* mutable_status_reply() override;
+  void AllowlistCertificateRequest(
+      const ::attestation::GetCertificateRequest& request) override;
+  const std::vector<::attestation::DeleteKeysRequest>& delete_keys_history()
+      const override;
+  void ClearDeleteKeysHistory() override;
+  void set_enrollment_id_ignore_cache(const std::string& id) override;
+  void set_cached_enrollment_id(const std::string& id) override;
+  void set_enrollment_id_dbus_error_count(int count) override;
+  ::attestation::GetKeyInfoReply* GetMutableKeyInfoReply(
+      const std::string& username,
+      const std::string& label) override;
+  void set_key_info_dbus_error_count(int count) override;
+  int key_info_dbus_error_count() const override;
+  bool VerifySimpleChallengeResponse(
+      const std::string& challenge,
+      const ::attestation::SignedData& signed_data) override;
+  void set_sign_simple_challenge_status(
+      ::attestation::AttestationStatus status) override;
+  void AllowlistSignSimpleChallengeKey(const std::string& username,
+                                       const std::string& label) override;
+  void set_sign_status(::attestation::AttestationStatus status) override;
+  void set_register_key_status(
+      ::attestation::AttestationStatus status) override;
+  void AllowlistRegisterKey(const std::string& username,
+                            const std::string& label) override;
+  void set_sign_enterprise_challenge_status(
+      ::attestation::AttestationStatus status) override;
+  void AllowlistSignEnterpriseChallengeKey(
+      const ::attestation::SignEnterpriseChallengeRequest& request) override;
+  std::string GetEnterpriseChallengeFakeSignature(
+      const std::string& challenge,
+      bool include_spkac) const override;
+  void set_sign_enterprise_challenge_delay(
+      const base::TimeDelta& delay) override;
+  void set_aca_type_for_legacy_flow(::attestation::ACAType aca_type) override;
+  void set_enroll_request_status(
+      ::attestation::AttestationStatus status) override;
+  std::string GetFakePcaEnrollRequest() const override;
+  std::string GetFakePcaEnrollResponse() const override;
+  void AllowlistLegacyCreateCertificateRequest(
+      const std::string& username,
+      const std::string& request_origin,
+      ::attestation::CertificateProfile profile,
+      ::attestation::KeyType key_type) override;
+  void set_cert_request_status(
+      ::attestation::AttestationStatus status) override;
+  std::string GetFakePcaCertRequest() const override;
+  std::string GetFakePcaCertResponse() const override;
+  std::string GetFakeCertificate() const override;
+
+  AttestationClient::TestInterface* GetTestInterface() override;
+
+ private:
+  ::attestation::AttestationStatus preparations_status_ =
+      ::attestation::STATUS_SUCCESS;
+  bool is_prepared_ = true;
+  std::deque<bool> preparation_sequences_;
+
+  ::attestation::GetStatusReply status_reply_;
+
+  // Maintains the allowlisted certificate requests.
+  std::vector<::attestation::GetCertificateRequest> allowlisted_requests_;
+
+  // Maintains the allowlisted legacy create-certificate requests.
+  std::vector<::attestation::CreateCertificateRequestRequest>
+      allowlisted_create_requests_;
+
+  // Maintains the numbers assigned to the allowlisted requests.
+  std::vector<int> certificate_indices_;
+  // The count of certificates that has been issued.
+  int certificate_count_ = 0;
+
+  // Maintains the input request history of `DeleteKeys()`.
+  std::vector<::attestation::DeleteKeysRequest> delete_keys_history_;
+
+  // Maintains building components reply to `GetEnrollmentId()`.
+  std::string enrollment_id_;
+  std::string enrollment_id_ignore_cache_;
+  int enrollment_id_dbus_error_count_ = 0;
+
+  class GetKeyInfoRequestComparator {
+   public:
+    bool operator()(const ::attestation::GetKeyInfoRequest& r1,
+                    const ::attestation::GetKeyInfoRequest& r2) const {
+      return r1.username() == r2.username() ? r1.key_label() < r2.key_label()
+                                            : r1.username() < r2.username();
+    }
+  };
+  // The fake key info database. std::map is chosen because we don't have to
+  // implement the hash function for the `GetKeyInfoRequest`, which could be
+  // expensive and contributes unreasonable overhead at smaller scale, anyway.
+  std::map<::attestation::GetKeyInfoRequest,
+           ::attestation::GetKeyInfoReply,
+           GetKeyInfoRequestComparator>
+      key_info_database_;
+  int key_info_dbus_error_count_ = 0;
+
+  // The status returned by `SignSimpleChallenge()`.
+  ::attestation::AttestationStatus sign_simple_challenge_status_ =
+      ::attestation::STATUS_SUCCESS;
+  // The status returned by `Sign()`.
+  ::attestation::AttestationStatus sign_status_ = ::attestation::STATUS_SUCCESS;
+  // The table of username-label pairs of which keys can perform simple sign
+  // challenge.
+  std::set<std::pair<std::string, std::string>>
+      allowlisted_sign_simple_challenge_keys_;
+
+  // The status returned by `RegisterKeyWithChapsToken()`.
+  ::attestation::AttestationStatus register_key_status_ =
+      ::attestation::STATUS_SUCCESS;
+  // The table of username-label pairs of which keys can be registered to the
+  // key store.
+  std::set<std::pair<std::string, std::string>> allowlisted_register_keys_;
+
+  // The status returned by `SignEnterpriseChallenge()`.
+  ::attestation::AttestationStatus sign_enterprise_challenge_status_ =
+      ::attestation::STATUS_SUCCESS;
+
+  class SignEnterpriseChallengeRequestComparator {
+   public:
+    bool operator()(
+        const ::attestation::SignEnterpriseChallengeRequest& r1,
+        const ::attestation::SignEnterpriseChallengeRequest& r2) const {
+      // The inputs for signature generation `challenge()` and
+      // `include_signed_public_key()` are ignored.
+      return std::forward_as_tuple(r1.username(), r1.key_label(),
+                                   r1.key_name_for_spkac(), r1.domain(),
+                                   r1.device_id(), r1.va_type()) <
+             std::forward_as_tuple(r2.username(), r2.key_label(),
+                                   r2.key_name_for_spkac(), r2.domain(),
+                                   r2.device_id(), r2.va_type());
+    }
+  };
+  // The table of `SignEnterpriseChallenge` which can sign enterprise
+  // challenge.
+  std::set<::attestation::SignEnterpriseChallengeRequest,
+           SignEnterpriseChallengeRequestComparator>
+      allowlisted_sign_enterprise_challenge_keys_;
+  // The delay the reply of `SignEnterpriseChallenge()` is posted with.
+  base::TimeDelta sign_enterprise_challenge_delay_;
+
+  // The allowed ACA type for legacy attestation flow.
+  ::attestation::ACAType aca_type_for_legacy_mode_ = ::attestation::DEFAULT_ACA;
+
+  // The status returned by `CreateEnrollRequest()`.
+  ::attestation::AttestationStatus enroll_request_status_ =
+      ::attestation::STATUS_SUCCESS;
+  // The status returned by `CreateCertificateRequest()`.
+  ::attestation::AttestationStatus cert_request_status_ =
+      ::attestation::STATUS_SUCCESS;
+};
+
+}  // namespace ash
+
+#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_ATTESTATION_FAKE_ATTESTATION_CLIENT_H_
diff --git a/chromeos/ash/components/dbus/cicerone/cicerone_client.cc b/chromeos/ash/components/dbus/cicerone/cicerone_client.cc
index 5deea896..495d59d8 100644
--- a/chromeos/ash/components/dbus/cicerone/cicerone_client.cc
+++ b/chromeos/ash/components/dbus/cicerone/cicerone_client.cc
@@ -647,6 +647,52 @@
                        weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
+  void AttachUsbToContainer(
+      const vm_tools::cicerone::AttachUsbToContainerRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::AttachUsbToContainerResponse>
+          callback) override {
+    dbus::MethodCall method_call(
+        vm_tools::cicerone::kVmCiceroneInterface,
+        vm_tools::cicerone::kAttachUsbToContainerMethod);
+    dbus::MessageWriter writer(&method_call);
+
+    if (!writer.AppendProtoAsArrayOfBytes(request)) {
+      LOG(ERROR) << "Failed to encode AttachUsbToContainerRequest protobuf";
+      base::ThreadTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
+      return;
+    }
+
+    cicerone_proxy_->CallMethod(
+        &method_call, kDefaultTimeout.InMilliseconds(),
+        base::BindOnce(&CiceroneClientImpl::OnDBusProtoResponse<
+                           vm_tools::cicerone::AttachUsbToContainerResponse>,
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  }
+
+  void DetachUsbFromContainer(
+      const vm_tools::cicerone::DetachUsbFromContainerRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::DetachUsbFromContainerResponse>
+          callback) override {
+    dbus::MethodCall method_call(
+        vm_tools::cicerone::kVmCiceroneInterface,
+        vm_tools::cicerone::kDetachUsbFromContainerMethod);
+    dbus::MessageWriter writer(&method_call);
+
+    if (!writer.AppendProtoAsArrayOfBytes(request)) {
+      LOG(ERROR) << "Failed to encode DetachUsbFromContainerRequest protobuf";
+      base::ThreadTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
+      return;
+    }
+
+    cicerone_proxy_->CallMethod(
+        &method_call, kDefaultTimeout.InMilliseconds(),
+        base::BindOnce(&CiceroneClientImpl::OnDBusProtoResponse<
+                           vm_tools::cicerone::DetachUsbFromContainerResponse>,
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  }
+
   void FileSelected(
       const vm_tools::cicerone::FileSelectedSignal& signal) override {
     dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
diff --git a/chromeos/ash/components/dbus/cicerone/cicerone_client.h b/chromeos/ash/components/dbus/cicerone/cicerone_client.h
index 182efd55..f108c8e 100644
--- a/chromeos/ash/components/dbus/cicerone/cicerone_client.h
+++ b/chromeos/ash/components/dbus/cicerone/cicerone_client.h
@@ -353,6 +353,20 @@
       DBusMethodCallback<vm_tools::cicerone::GetVshSessionResponse>
           callback) = 0;
 
+  // Attaches a USB device to a LXD container.
+  // |callback| is called when the method completes.
+  virtual void AttachUsbToContainer(
+      const vm_tools::cicerone::AttachUsbToContainerRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::AttachUsbToContainerResponse>
+          callback) = 0;
+
+  // Detaches a USB device from a LXD container.
+  // |callback| is called when the method completes.
+  virtual void DetachUsbFromContainer(
+      const vm_tools::cicerone::DetachUsbFromContainerRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::DetachUsbFromContainerResponse>
+          callback) = 0;
+
   // Send signal with files user has selected in SelectFile dialog. This is sent
   // in response to VmApplicationsServiceProvider::SelectFile().
   virtual void FileSelected(
diff --git a/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.cc b/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.cc
index bb4e707..f0a6a80 100644
--- a/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.cc
+++ b/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.cc
@@ -461,6 +461,24 @@
       base::BindOnce(std::move(callback), get_vsh_session_response_));
 }
 
+void FakeCiceroneClient::AttachUsbToContainer(
+    const vm_tools::cicerone::AttachUsbToContainerRequest& request,
+    DBusMethodCallback<vm_tools::cicerone::AttachUsbToContainerResponse>
+        callback) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(std::move(callback), attach_usb_to_container_response_));
+}
+
+void FakeCiceroneClient::DetachUsbFromContainer(
+    const vm_tools::cicerone::DetachUsbFromContainerRequest& request,
+    DBusMethodCallback<vm_tools::cicerone::DetachUsbFromContainerResponse>
+        callback) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::BindOnce(std::move(callback), detach_usb_from_container_response_));
+}
+
 void FakeCiceroneClient::FileSelected(
     const vm_tools::cicerone::FileSelectedSignal& signal) {}
 
diff --git a/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h b/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h
index 701d8e9..05e9a4c 100644
--- a/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h
+++ b/chromeos/ash/components/dbus/cicerone/fake_cicerone_client.h
@@ -149,6 +149,14 @@
       const vm_tools::cicerone::GetVshSessionRequest& request,
       DBusMethodCallback<vm_tools::cicerone::GetVshSessionResponse> callback)
       override;
+  void AttachUsbToContainer(
+      const vm_tools::cicerone::AttachUsbToContainerRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::AttachUsbToContainerResponse>
+          callback) override;
+  void DetachUsbFromContainer(
+      const vm_tools::cicerone::DetachUsbFromContainerRequest& request,
+      DBusMethodCallback<vm_tools::cicerone::DetachUsbFromContainerResponse>
+          callback) override;
   void FileSelected(
       const vm_tools::cicerone::FileSelectedSignal& signal) override;
   void WaitForServiceToBeAvailable(
@@ -341,6 +349,18 @@
       vm_tools::cicerone::GetVshSessionResponse get_vsh_session_response) {
     get_vsh_session_response_ = std::move(get_vsh_session_response);
   }
+  void set_attach_usb_to_container_response(
+      vm_tools::cicerone::AttachUsbToContainerResponse
+          attach_usb_to_container_response) {
+    attach_usb_to_container_response_ =
+        std::move(attach_usb_to_container_response);
+  }
+  void set_detach_usb_from_container_response(
+      vm_tools::cicerone::DetachUsbFromContainerResponse
+          detach_usb_from_container_response) {
+    detach_usb_from_container_response_ =
+        std::move(detach_usb_from_container_response);
+  }
 
   void set_send_container_starting_signal_delay(base::TimeDelta delay) {
     send_container_starting_signal_delay_ = delay;
@@ -498,6 +518,10 @@
   vm_tools::cicerone::AddFileWatchResponse add_file_watch_response_;
   vm_tools::cicerone::RemoveFileWatchResponse remove_file_watch_response_;
   vm_tools::cicerone::GetVshSessionResponse get_vsh_session_response_;
+  vm_tools::cicerone::AttachUsbToContainerResponse
+      attach_usb_to_container_response_;
+  vm_tools::cicerone::DetachUsbFromContainerResponse
+      detach_usb_from_container_response_;
 
   base::TimeDelta send_container_starting_signal_delay_;
   base::TimeDelta send_container_started_signal_delay_;
diff --git a/chromeos/ash/components/local_search_service/content_extraction_utils.cc b/chromeos/ash/components/local_search_service/content_extraction_utils.cc
index 90c31c6..2eba372 100644
--- a/chromeos/ash/components/local_search_service/content_extraction_utils.cc
+++ b/chromeos/ash/components/local_search_service/content_extraction_utils.cc
@@ -19,11 +19,11 @@
 #include "chromeos/components/string_matching/tokenized_string.h"
 #include "third_party/icu/source/i18n/unicode/translit.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
-
-using ::chromeos::string_matching::TokenizedString;
+using chromeos::string_matching::TokenizedString;
 
 std::unique_ptr<icu::Transliterator> CreateDiacriticRemover() {
   UErrorCode status = U_ZERO_ERROR;
@@ -182,5 +182,5 @@
 
   return base::i18n::UnicodeStringToString16(source);
 }
-
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/content_extraction_utils.h b/chromeos/ash/components/local_search_service/content_extraction_utils.h
index e4b660d..b1d300d1 100644
--- a/chromeos/ash/components/local_search_service/content_extraction_utils.h
+++ b/chromeos/ash/components/local_search_service/content_extraction_utils.h
@@ -9,7 +9,8 @@
 
 #include "chromeos/ash/components/local_search_service/shared_structs.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 // Given a list of tokens, returns a list of tokens where each token has a
 // unique content.
@@ -40,6 +41,7 @@
 std::u16string Normalizer(const std::u16string& word,
                           bool remove_hyphen = true);
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_CONTENT_EXTRACTION_UTILS_H_
diff --git a/chromeos/ash/components/local_search_service/content_extraction_utils_unittest.cc b/chromeos/ash/components/local_search_service/content_extraction_utils_unittest.cc
index 7a7fe47..cf28340 100644
--- a/chromeos/ash/components/local_search_service/content_extraction_utils_unittest.cc
+++ b/chromeos/ash/components/local_search_service/content_extraction_utils_unittest.cc
@@ -8,12 +8,11 @@
 #include "chromeos/ash/components/local_search_service/shared_structs.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
-
 constexpr double kDefaultWeight = 1.0;
-
 }  // namespace
 
 TEST(ContentExtractionUtilsTest, ConsolidateTokenTest) {
@@ -133,4 +132,5 @@
       u"day la mot trinh duyet tuyet voi va muotma");
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/index.cc b/chromeos/ash/components/local_search_service/index.cc
index e598bb9..e286893 100644
--- a/chromeos/ash/components/local_search_service/index.cc
+++ b/chromeos/ash/components/local_search_service/index.cc
@@ -7,7 +7,8 @@
 #include "base/metrics/histogram_functions.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -119,4 +120,5 @@
   std::move(callback).Run();
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/index.h b/chromeos/ash/components/local_search_service/index.h
index 6f41291..f736e45c 100644
--- a/chromeos/ash/components/local_search_service/index.h
+++ b/chromeos/ash/components/local_search_service/index.h
@@ -14,7 +14,8 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 class Index : public mojom::Index {
  public:
@@ -71,6 +72,7 @@
   mojo::ReceiverSet<mojom::Index> receivers_;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_H_
diff --git a/chromeos/ash/components/local_search_service/inverted_index.cc b/chromeos/ash/components/local_search_service/inverted_index.cc
index 6c3b38f..3ab4aeb 100644
--- a/chromeos/ash/components/local_search_service/inverted_index.cc
+++ b/chromeos/ash/components/local_search_service/inverted_index.cc
@@ -16,7 +16,8 @@
 #include "base/task/thread_pool.h"
 #include "chromeos/ash/components/local_search_service/search_utils.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -163,7 +164,6 @@
                       std::move(terms_to_be_updated)),
       std::move(tfidf_cache));
 }
-
 }  // namespace
 
 InvertedIndex::InvertedIndex() {
@@ -367,4 +367,5 @@
   std::move(callback).Run();
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/inverted_index.h b/chromeos/ash/components/local_search_service/inverted_index.h
index f621d271..eaf004a 100644
--- a/chromeos/ash/components/local_search_service/inverted_index.h
+++ b/chromeos/ash/components/local_search_service/inverted_index.h
@@ -17,8 +17,8 @@
 #include "base/task/sequenced_task_runner.h"
 #include "chromeos/ash/components/local_search_service/shared_structs.h"
 
-namespace ash::local_search_service {
-
+namespace chromeos {
+namespace local_search_service {
 // A posting is a list of WeightedPosition.
 using Posting = std::vector<WeightedPosition>;
 
@@ -160,6 +160,7 @@
   base::WeakPtrFactory<InvertedIndex> weak_ptr_factory_{this};
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_INVERTED_INDEX_H_
diff --git a/chromeos/ash/components/local_search_service/inverted_index_search.cc b/chromeos/ash/components/local_search_service/inverted_index_search.cc
index d74f8bd..934876b 100644
--- a/chromeos/ash/components/local_search_service/inverted_index_search.cc
+++ b/chromeos/ash/components/local_search_service/inverted_index_search.cc
@@ -22,11 +22,12 @@
 #include "chromeos/components/string_matching/tokenized_string.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
-using ::chromeos::string_matching::TokenizedString;
+using chromeos::string_matching::TokenizedString;
 using ExtractedContent =
     std::vector<std::pair<std::string, std::vector<Token>>>;
 
@@ -213,4 +214,5 @@
   inverted_index_->UpdateDocuments(documents, std::move(callback));
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/inverted_index_search.h b/chromeos/ash/components/local_search_service/inverted_index_search.h
index 9699243a..0dff014b0 100644
--- a/chromeos/ash/components/local_search_service/inverted_index_search.h
+++ b/chromeos/ash/components/local_search_service/inverted_index_search.h
@@ -16,7 +16,8 @@
 #include "chromeos/ash/components/local_search_service/index.h"
 #include "chromeos/ash/components/local_search_service/shared_structs.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 class InvertedIndex;
 
@@ -72,6 +73,7 @@
   base::WeakPtrFactory<InvertedIndexSearch> weak_ptr_factory_{this};
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_INVERTED_INDEX_SEARCH_H_
diff --git a/chromeos/ash/components/local_search_service/inverted_index_search_unittest.cc b/chromeos/ash/components/local_search_service/inverted_index_search_unittest.cc
index 0f1220b..9861d0e 100644
--- a/chromeos/ash/components/local_search_service/inverted_index_search_unittest.cc
+++ b/chromeos/ash/components/local_search_service/inverted_index_search_unittest.cc
@@ -9,10 +9,10 @@
 #include "chromeos/ash/components/local_search_service/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
-
 // This is (data-id, content-ids).
 using ResultWithIds = std::pair<std::string, std::vector<std::string>>;
 
@@ -438,4 +438,5 @@
               /*expected_number_positions=*/1);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/inverted_index_unittest.cc b/chromeos/ash/components/local_search_service/inverted_index_unittest.cc
index 36e438edc..38b3ae45 100644
--- a/chromeos/ash/components/local_search_service/inverted_index_unittest.cc
+++ b/chromeos/ash/components/local_search_service/inverted_index_unittest.cc
@@ -17,7 +17,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -575,4 +576,5 @@
   }
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/linear_map_search.cc b/chromeos/ash/components/local_search_service/linear_map_search.cc
index 5233292b..1153aae 100644
--- a/chromeos/ash/components/local_search_service/linear_map_search.cc
+++ b/chromeos/ash/components/local_search_service/linear_map_search.cc
@@ -15,12 +15,14 @@
 #include "chromeos/components/string_matching/tokenized_string.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
-using ::chromeos::string_matching::FuzzyTokenizedStringMatch;
-using ::chromeos::string_matching::TokenizedString;
+using chromeos::string_matching::FuzzyTokenizedStringMatch;
+using chromeos::string_matching::TokenizedString;
+
 using Positions = std::vector<local_search_service::Position>;
 using TokenizedStringWithId =
     std::pair<std::string, std::unique_ptr<TokenizedString>>;
@@ -191,4 +193,5 @@
   return results;
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/linear_map_search.h b/chromeos/ash/components/local_search_service/linear_map_search.h
index b718dd6..3635ce1 100644
--- a/chromeos/ash/components/local_search_service/linear_map_search.h
+++ b/chromeos/ash/components/local_search_service/linear_map_search.h
@@ -13,11 +13,13 @@
 #include "chromeos/ash/components/local_search_service/index.h"
 #include "chromeos/ash/components/local_search_service/shared_structs.h"
 
-namespace chromeos::string_matching {
-class TokenizedString;
-}
+namespace chromeos {
 
-namespace ash::local_search_service {
+namespace string_matching {
+class TokenizedString;
+}  // namespace string_matching
+
+namespace local_search_service {
 
 // A map from key to a vector of (tag-id, tokenized tag).
 typedef std::map<
@@ -61,6 +63,7 @@
   KeyToTagVector data_;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_LINEAR_MAP_SEARCH_H_
diff --git a/chromeos/ash/components/local_search_service/linear_map_search_unittest.cc b/chromeos/ash/components/local_search_service/linear_map_search_unittest.cc
index 464dc711..f95cbf7 100644
--- a/chromeos/ash/components/local_search_service/linear_map_search_unittest.cc
+++ b/chromeos/ash/components/local_search_service/linear_map_search_unittest.cc
@@ -16,7 +16,8 @@
 #include "chromeos/ash/components/local_search_service/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -280,4 +281,5 @@
   GetSizeAndCheckResults(index_.get(), 1u);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/local_search_service.cc b/chromeos/ash/components/local_search_service/local_search_service.cc
index 68f244dd..ef734936 100644
--- a/chromeos/ash/components/local_search_service/local_search_service.cc
+++ b/chromeos/ash/components/local_search_service/local_search_service.cc
@@ -6,7 +6,8 @@
 #include "chromeos/ash/components/local_search_service/inverted_index_search.h"
 #include "chromeos/ash/components/local_search_service/linear_map_search.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 LocalSearchService::LocalSearchService(
     mojo::PendingReceiver<mojom::LocalSearchService> receiver)
@@ -50,4 +51,5 @@
   std::move(callback).Run(absl::nullopt);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/local_search_service.h b/chromeos/ash/components/local_search_service/local_search_service.h
index 2e19a33..a32ae10 100644
--- a/chromeos/ash/components/local_search_service/local_search_service.h
+++ b/chromeos/ash/components/local_search_service/local_search_service.h
@@ -12,7 +12,8 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 class LocalSearchService : public mojom::LocalSearchService {
  public:
@@ -33,6 +34,7 @@
   std::map<IndexId, std::unique_ptr<Index>> indices_;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_H_
diff --git a/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.cc b/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.cc
index 48245380..2057c81 100644
--- a/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.cc
+++ b/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.cc
@@ -6,7 +6,8 @@
 
 #include <memory>
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 LocalSearchServiceProviderForTesting::LocalSearchServiceProviderForTesting() {
   LocalSearchServiceProvider::Set(this);
@@ -21,4 +22,5 @@
   service_ = std::make_unique<LocalSearchService>(std::move(receiver));
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.h b/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.h
index 913a3f3..29547e54 100644
--- a/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.h
+++ b/chromeos/ash/components/local_search_service/local_search_service_provider_for_testing.h
@@ -8,7 +8,8 @@
 #include "chromeos/ash/components/local_search_service/local_search_service.h"
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 // An implementation that runs LocalSearchService in-process for testing
 // purpose.
@@ -25,6 +26,7 @@
   std::unique_ptr<LocalSearchService> service_;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_PROVIDER_FOR_TESTING_H_
diff --git a/chromeos/ash/components/local_search_service/local_search_service_provider_unittest.cc b/chromeos/ash/components/local_search_service/local_search_service_provider_unittest.cc
index 2e051ac..fe151b9 100644
--- a/chromeos/ash/components/local_search_service/local_search_service_provider_unittest.cc
+++ b/chromeos/ash/components/local_search_service/local_search_service_provider_unittest.cc
@@ -9,7 +9,8 @@
 #include "base/test/task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 class LocalSearchServiceProviderTest : public testing::Test {
  public:
@@ -62,4 +63,5 @@
   EXPECT_EQ(num_items, 0u);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/local_search_service_proxy_unittest.cc b/chromeos/ash/components/local_search_service/local_search_service_proxy_unittest.cc
index 5a5bb91..220a631 100644
--- a/chromeos/ash/components/local_search_service/local_search_service_proxy_unittest.cc
+++ b/chromeos/ash/components/local_search_service/local_search_service_proxy_unittest.cc
@@ -12,7 +12,8 @@
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 class LocalSearchServiceProxyTest : public testing::Test {
  public:
@@ -82,4 +83,5 @@
   CheckReporter(/*is_null_expected*/ true);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/local_search_service_unittest.cc b/chromeos/ash/components/local_search_service/local_search_service_unittest.cc
index d8402d0..9d06db1 100644
--- a/chromeos/ash/components/local_search_service/local_search_service_unittest.cc
+++ b/chromeos/ash/components/local_search_service/local_search_service_unittest.cc
@@ -11,10 +11,9 @@
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
-
+namespace chromeos {
+namespace local_search_service {
 namespace {
-
 // (content-id, content).
 using ContentWithId = std::pair<std::string, std::string>;
 
@@ -163,4 +162,5 @@
   IndexGetSizeAndCheckResults(&third_index_remote, 0u);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/oop_local_search_service_provider.cc b/chromeos/ash/components/local_search_service/oop_local_search_service_provider.cc
index 490d6ab..8622781 100644
--- a/chromeos/ash/components/local_search_service/oop_local_search_service_provider.cc
+++ b/chromeos/ash/components/local_search_service/oop_local_search_service_provider.cc
@@ -7,7 +7,8 @@
 #include "chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom.h"
 #include "content/public/browser/service_process_host.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 OopLocalSearchServiceProvider::OopLocalSearchServiceProvider() {
   LocalSearchServiceProvider::Set(this);
@@ -25,4 +26,5 @@
                                .Pass());
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/oop_local_search_service_provider.h b/chromeos/ash/components/local_search_service/oop_local_search_service_provider.h
index 5d0b23c..003fdd0 100644
--- a/chromeos/ash/components/local_search_service/oop_local_search_service_provider.h
+++ b/chromeos/ash/components/local_search_service/oop_local_search_service_provider.h
@@ -7,8 +7,8 @@
 
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.h"
 #include "chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom-forward.h"
-
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 // An implementation that runs LocalSearchService in the LSS service
 // process.
@@ -22,6 +22,7 @@
       mojo::PendingReceiver<mojom::LocalSearchService> receiver) override;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_OOP_LOCAL_SEARCH_SERVICE_PROVIDER_H_
diff --git a/chromeos/ash/components/local_search_service/pref_names.cc b/chromeos/ash/components/local_search_service/pref_names.cc
index 423ba14..cf699e4 100644
--- a/chromeos/ash/components/local_search_service/pref_names.cc
+++ b/chromeos/ash/components/local_search_service/pref_names.cc
@@ -4,7 +4,9 @@
 
 #include "chromeos/ash/components/local_search_service/pref_names.h"
 
-namespace ash::local_search_service::prefs {
+namespace chromeos {
+namespace local_search_service {
+namespace prefs {
 
 // TODO(thanhdng): clean this up after LSS is sandboxed.
 const char kLocalSearchServiceSyncMetricsDailySample[] =
@@ -25,4 +27,6 @@
 const char kLocalSearchServiceMetricsPersonalizationCount[] =
     "local_search_service.metrics.personalization_count";
 
-}  // namespace ash::local_search_service::prefs
+}  // namespace prefs
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/pref_names.h b/chromeos/ash/components/local_search_service/pref_names.h
index 86fc082..668ae24 100644
--- a/chromeos/ash/components/local_search_service/pref_names.h
+++ b/chromeos/ash/components/local_search_service/pref_names.h
@@ -5,7 +5,9 @@
 #ifndef CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_PREF_NAMES_H_
 #define CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_PREF_NAMES_H_
 
-namespace ash::local_search_service::prefs {
+namespace chromeos {
+namespace local_search_service {
+namespace prefs {
 
 // Integer pref used by the metrics::DailyEvent owned by
 // local_search_service::SearchMetricsReporter.
@@ -24,6 +26,8 @@
 extern const char kLocalSearchServiceSyncMetricsHelpAppCount[];
 extern const char kLocalSearchServiceSyncMetricsHelpAppLauncherCount[];
 
-}  // namespace ash::local_search_service::prefs
+}  // namespace prefs
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_PREF_NAMES_H_
diff --git a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.cc b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.cc
index 66cd5aac..39c4db4 100644
--- a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.cc
+++ b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.cc
@@ -6,7 +6,8 @@
 
 #include "chromeos/ash/components/local_search_service/local_search_service.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -22,4 +23,5 @@
   return g_provider;
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.h b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.h
index 218e899..8bc49f0 100644
--- a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.h
+++ b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_provider.h
@@ -8,7 +8,8 @@
 #include "chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom-forward.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 // LocalSearchServiceProvider creates an instance of LocalSearchService
 // and runs in LSS service process or in process (depending on the
@@ -31,6 +32,7 @@
       mojo::PendingReceiver<mojom::LocalSearchService> receiver) = 0;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_PUBLIC_CPP_LOCAL_SEARCH_SERVICE_PROVIDER_H_
diff --git a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.cc b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.cc
index 175fffb..ac80156 100644
--- a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.cc
+++ b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.cc
@@ -11,7 +11,8 @@
 #include "chromeos/ash/components/local_search_service/oop_local_search_service_provider.h"
 #include "components/prefs/pref_service.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -78,4 +79,5 @@
   return service_.get();
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h
index 8a3b4a791..63839c46 100644
--- a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h
+++ b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h
@@ -15,7 +15,8 @@
 
 class PrefService;
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 class LocalSearchServiceProxy : public KeyedService {
  public:
@@ -49,11 +50,14 @@
   std::unique_ptr<SearchMetricsReporter> reporter_;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
-// TODO(https://crbug.com/1164001): remove after the migration is finished.
-namespace chromeos::local_search_service {
-using ::ash::local_search_service::LocalSearchServiceProxy;
-}
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace local_search_service {
+using ::chromeos::local_search_service::LocalSearchServiceProxy;
+}  // namespace local_search_service
+}  // namespace ash
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_PUBLIC_CPP_LOCAL_SEARCH_SERVICE_PROXY_H_
diff --git a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.cc b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.cc
index 2936a56..b6c38bd 100644
--- a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.cc
+++ b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.cc
@@ -8,7 +8,8 @@
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -57,4 +58,5 @@
   return new LocalSearchServiceProxy();
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h
index 86e73ac..ddca5641 100644
--- a/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h
+++ b/chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h
@@ -10,8 +10,8 @@
 
 class PrefService;
 
-namespace ash::local_search_service {
-
+namespace chromeos {
+namespace local_search_service {
 class LocalSearchServiceProxy;
 
 class LocalSearchServiceProxyFactory
@@ -41,6 +41,14 @@
       content::BrowserContext* context) const override;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
+
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace local_search_service {
+using ::chromeos::local_search_service::LocalSearchServiceProxyFactory;
+}  // namespace local_search_service
+}  // namespace ash
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_PUBLIC_CPP_LOCAL_SEARCH_SERVICE_PROXY_FACTORY_H_
diff --git a/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn b/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn
index 1ce3d23e..decdb4ab 100644
--- a/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn
+++ b/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn
@@ -23,36 +23,36 @@
     {
       types = [
         {
-          mojom = "ash.local_search_service.mojom.IndexId"
-          cpp = "::ash::local_search_service::IndexId"
+          mojom = "chromeos.local_search_service.mojom.IndexId"
+          cpp = "::chromeos::local_search_service::IndexId"
         },
         {
-          mojom = "ash.local_search_service.mojom.Content"
-          cpp = "::ash::local_search_service::Content"
+          mojom = "chromeos.local_search_service.mojom.Content"
+          cpp = "::chromeos::local_search_service::Content"
         },
         {
-          mojom = "ash.local_search_service.mojom.Data"
-          cpp = "::ash::local_search_service::Data"
+          mojom = "chromeos.local_search_service.mojom.Data"
+          cpp = "::chromeos::local_search_service::Data"
         },
         {
-          mojom = "ash.local_search_service.mojom.SearchParams"
-          cpp = "::ash::local_search_service::SearchParams"
+          mojom = "chromeos.local_search_service.mojom.SearchParams"
+          cpp = "::chromeos::local_search_service::SearchParams"
         },
         {
-          mojom = "ash.local_search_service.mojom.Position"
-          cpp = "::ash::local_search_service::Position"
+          mojom = "chromeos.local_search_service.mojom.Position"
+          cpp = "::chromeos::local_search_service::Position"
         },
         {
-          mojom = "ash.local_search_service.mojom.Result"
-          cpp = "::ash::local_search_service::Result"
+          mojom = "chromeos.local_search_service.mojom.Result"
+          cpp = "::chromeos::local_search_service::Result"
         },
         {
-          mojom = "ash.local_search_service.mojom.ResponseStatus"
-          cpp = "::ash::local_search_service::ResponseStatus"
+          mojom = "chromeos.local_search_service.mojom.ResponseStatus"
+          cpp = "::chromeos::local_search_service::ResponseStatus"
         },
         {
-          mojom = "ash.local_search_service.mojom.Backend"
-          cpp = "::ash::local_search_service::Backend"
+          mojom = "chromeos.local_search_service.mojom.Backend"
+          cpp = "::chromeos::local_search_service::Backend"
         },
       ]
       traits_headers = [ "//chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.h" ]
diff --git a/chromeos/ash/components/local_search_service/public/mojom/index.mojom b/chromeos/ash/components/local_search_service/public/mojom/index.mojom
index 68f4544d..5f136be6 100644
--- a/chromeos/ash/components/local_search_service/public/mojom/index.mojom
+++ b/chromeos/ash/components/local_search_service/public/mojom/index.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-module ash.local_search_service.mojom;
+module chromeos.local_search_service.mojom;
 
 import "chromeos/ash/components/local_search_service/public/mojom/types.mojom";
 import "mojo/public/mojom/base/string16.mojom";
diff --git a/chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom b/chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom
index d34948a..5209df2e 100644
--- a/chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom
+++ b/chromeos/ash/components/local_search_service/public/mojom/local_search_service.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-module ash.local_search_service.mojom;
+module chromeos.local_search_service.mojom;
 
 import "chromeos/ash/components/local_search_service/public/mojom/index.mojom";
 import "chromeos/ash/components/local_search_service/public/mojom/types.mojom";
diff --git a/chromeos/ash/components/local_search_service/public/mojom/types.mojom b/chromeos/ash/components/local_search_service/public/mojom/types.mojom
index edeac8a..8e968b36 100644
--- a/chromeos/ash/components/local_search_service/public/mojom/types.mojom
+++ b/chromeos/ash/components/local_search_service/public/mojom/types.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-module ash.local_search_service.mojom;
+module chromeos.local_search_service.mojom;
 
 import "mojo/public/mojom/base/string16.mojom";
 
diff --git a/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.cc b/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.cc
index 669040fb..a64212b 100644
--- a/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.cc
+++ b/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.cc
@@ -9,41 +9,41 @@
 namespace mojo {
 
 // static
-ash::local_search_service::mojom::IndexId
-EnumTraits<ash::local_search_service::mojom::IndexId,
-           ash::local_search_service::IndexId>::
-    ToMojom(ash::local_search_service::IndexId input) {
+chromeos::local_search_service::mojom::IndexId
+EnumTraits<chromeos::local_search_service::mojom::IndexId,
+           chromeos::local_search_service::IndexId>::
+    ToMojom(chromeos::local_search_service::IndexId input) {
   switch (input) {
-    case ash::local_search_service::IndexId::kCrosSettings:
-      return ash::local_search_service::mojom::IndexId::kCrosSettings;
-    case ash::local_search_service::IndexId::kHelpApp:
-      return ash::local_search_service::mojom::IndexId::kHelpApp;
-    case ash::local_search_service::IndexId::kHelpAppLauncher:
-      return ash::local_search_service::mojom::IndexId::kHelpAppLauncher;
-    case ash::local_search_service::IndexId::kPersonalization:
-      return ash::local_search_service::mojom::IndexId::kPersonalization;
+    case chromeos::local_search_service::IndexId::kCrosSettings:
+      return chromeos::local_search_service::mojom::IndexId::kCrosSettings;
+    case chromeos::local_search_service::IndexId::kHelpApp:
+      return chromeos::local_search_service::mojom::IndexId::kHelpApp;
+    case chromeos::local_search_service::IndexId::kHelpAppLauncher:
+      return chromeos::local_search_service::mojom::IndexId::kHelpAppLauncher;
+    case chromeos::local_search_service::IndexId::kPersonalization:
+      return chromeos::local_search_service::mojom::IndexId::kPersonalization;
   }
   NOTREACHED();
-  return ash::local_search_service::mojom::IndexId::kCrosSettings;
+  return chromeos::local_search_service::mojom::IndexId::kCrosSettings;
 }
 
 // static
-bool EnumTraits<ash::local_search_service::mojom::IndexId,
-                ash::local_search_service::IndexId>::
-    FromMojom(ash::local_search_service::mojom::IndexId input,
-              ash::local_search_service::IndexId* output) {
+bool EnumTraits<chromeos::local_search_service::mojom::IndexId,
+                chromeos::local_search_service::IndexId>::
+    FromMojom(chromeos::local_search_service::mojom::IndexId input,
+              chromeos::local_search_service::IndexId* output) {
   switch (input) {
-    case ash::local_search_service::mojom::IndexId::kCrosSettings:
-      *output = ash::local_search_service::IndexId::kCrosSettings;
+    case chromeos::local_search_service::mojom::IndexId::kCrosSettings:
+      *output = chromeos::local_search_service::IndexId::kCrosSettings;
       return true;
-    case ash::local_search_service::mojom::IndexId::kHelpApp:
-      *output = ash::local_search_service::IndexId::kHelpApp;
+    case chromeos::local_search_service::mojom::IndexId::kHelpApp:
+      *output = chromeos::local_search_service::IndexId::kHelpApp;
       return true;
-    case ash::local_search_service::mojom::IndexId::kHelpAppLauncher:
-      *output = ash::local_search_service::IndexId::kHelpAppLauncher;
+    case chromeos::local_search_service::mojom::IndexId::kHelpAppLauncher:
+      *output = chromeos::local_search_service::IndexId::kHelpAppLauncher;
       return true;
-    case ash::local_search_service::mojom::IndexId::kPersonalization:
-      *output = ash::local_search_service::IndexId::kPersonalization;
+    case chromeos::local_search_service::mojom::IndexId::kPersonalization:
+      *output = chromeos::local_search_service::IndexId::kPersonalization;
       return true;
   }
   NOTREACHED();
@@ -51,31 +51,31 @@
 }
 
 // static
-ash::local_search_service::mojom::Backend
-EnumTraits<ash::local_search_service::mojom::Backend,
-           ash::local_search_service::Backend>::
-    ToMojom(ash::local_search_service::Backend input) {
+chromeos::local_search_service::mojom::Backend
+EnumTraits<chromeos::local_search_service::mojom::Backend,
+           chromeos::local_search_service::Backend>::
+    ToMojom(chromeos::local_search_service::Backend input) {
   switch (input) {
-    case ash::local_search_service::Backend::kLinearMap:
-      return ash::local_search_service::mojom::Backend::kLinearMap;
-    case ash::local_search_service::Backend::kInvertedIndex:
-      return ash::local_search_service::mojom::Backend::kInvertedIndex;
+    case chromeos::local_search_service::Backend::kLinearMap:
+      return chromeos::local_search_service::mojom::Backend::kLinearMap;
+    case chromeos::local_search_service::Backend::kInvertedIndex:
+      return chromeos::local_search_service::mojom::Backend::kInvertedIndex;
   }
   NOTREACHED();
-  return ash::local_search_service::mojom::Backend::kLinearMap;
+  return chromeos::local_search_service::mojom::Backend::kLinearMap;
 }
 
 // static
-bool EnumTraits<ash::local_search_service::mojom::Backend,
-                ash::local_search_service::Backend>::
-    FromMojom(ash::local_search_service::mojom::Backend input,
-              ash::local_search_service::Backend* output) {
+bool EnumTraits<chromeos::local_search_service::mojom::Backend,
+                chromeos::local_search_service::Backend>::
+    FromMojom(chromeos::local_search_service::mojom::Backend input,
+              chromeos::local_search_service::Backend* output) {
   switch (input) {
-    case ash::local_search_service::mojom::Backend::kLinearMap:
-      *output = ash::local_search_service::Backend::kLinearMap;
+    case chromeos::local_search_service::mojom::Backend::kLinearMap:
+      *output = chromeos::local_search_service::Backend::kLinearMap;
       return true;
-    case ash::local_search_service::mojom::Backend::kInvertedIndex:
-      *output = ash::local_search_service::Backend::kInvertedIndex;
+    case chromeos::local_search_service::mojom::Backend::kInvertedIndex:
+      *output = chromeos::local_search_service::Backend::kInvertedIndex;
       return true;
   }
   NOTREACHED();
@@ -83,41 +83,41 @@
 }
 
 // static
-bool StructTraits<ash::local_search_service::mojom::ContentDataView,
-                  ash::local_search_service::Content>::
-    Read(ash::local_search_service::mojom::ContentDataView data,
-         ash::local_search_service::Content* out) {
+bool StructTraits<chromeos::local_search_service::mojom::ContentDataView,
+                  chromeos::local_search_service::Content>::
+    Read(chromeos::local_search_service::mojom::ContentDataView data,
+         chromeos::local_search_service::Content* out) {
   std::string id;
   std::u16string content;
   if (!data.ReadId(&id) || !data.ReadContent(&content))
     return false;
 
-  *out = ash::local_search_service::Content(id, content, data.weight());
+  *out = chromeos::local_search_service::Content(id, content, data.weight());
   return true;
 }
 
 // static
-bool StructTraits<ash::local_search_service::mojom::DataDataView,
-                  ash::local_search_service::Data>::
-    Read(ash::local_search_service::mojom::DataDataView data,
-         ash::local_search_service::Data* out) {
+bool StructTraits<chromeos::local_search_service::mojom::DataDataView,
+                  chromeos::local_search_service::Data>::
+    Read(chromeos::local_search_service::mojom::DataDataView data,
+         chromeos::local_search_service::Data* out) {
   std::string id;
-  std::vector<ash::local_search_service::Content> contents;
+  std::vector<chromeos::local_search_service::Content> contents;
   std::string locale;
   if (!data.ReadId(&id) || !data.ReadContents(&contents) ||
       !data.ReadLocale(&locale))
     return false;
 
-  *out = ash::local_search_service::Data(id, contents, locale);
+  *out = chromeos::local_search_service::Data(id, contents, locale);
   return true;
 }
 
 // static
-bool StructTraits<ash::local_search_service::mojom::SearchParamsDataView,
-                  ash::local_search_service::SearchParams>::
-    Read(ash::local_search_service::mojom::SearchParamsDataView data,
-         ash::local_search_service::SearchParams* out) {
-  *out = ash::local_search_service::SearchParams();
+bool StructTraits<chromeos::local_search_service::mojom::SearchParamsDataView,
+                  chromeos::local_search_service::SearchParams>::
+    Read(chromeos::local_search_service::mojom::SearchParamsDataView data,
+         chromeos::local_search_service::SearchParams* out) {
+  *out = chromeos::local_search_service::SearchParams();
   out->relevance_threshold = data.relevance_threshold();
   out->prefix_threshold = data.prefix_threshold();
   out->fuzzy_threshold = data.fuzzy_threshold();
@@ -125,11 +125,11 @@
 }
 
 // static
-bool StructTraits<ash::local_search_service::mojom::PositionDataView,
-                  ash::local_search_service::Position>::
-    Read(ash::local_search_service::mojom::PositionDataView data,
-         ash::local_search_service::Position* out) {
-  *out = ash::local_search_service::Position();
+bool StructTraits<chromeos::local_search_service::mojom::PositionDataView,
+                  chromeos::local_search_service::Position>::
+    Read(chromeos::local_search_service::mojom::PositionDataView data,
+         chromeos::local_search_service::Position* out) {
+  *out = chromeos::local_search_service::Position();
   if (!data.ReadContentId(&(out->content_id)))
     return false;
 
@@ -139,16 +139,16 @@
 }
 
 // static
-bool StructTraits<ash::local_search_service::mojom::ResultDataView,
-                  ash::local_search_service::Result>::
-    Read(ash::local_search_service::mojom::ResultDataView data,
-         ash::local_search_service::Result* out) {
+bool StructTraits<chromeos::local_search_service::mojom::ResultDataView,
+                  chromeos::local_search_service::Result>::
+    Read(chromeos::local_search_service::mojom::ResultDataView data,
+         chromeos::local_search_service::Result* out) {
   std::string id;
-  std::vector<ash::local_search_service::Position> positions;
+  std::vector<chromeos::local_search_service::Position> positions;
   if (!data.ReadId(&id) || !data.ReadPositions(&positions))
     return false;
 
-  *out = ash::local_search_service::Result();
+  *out = chromeos::local_search_service::Result();
   out->id = id;
   out->score = data.score();
   out->positions = positions;
@@ -156,41 +156,42 @@
 }
 
 // static
-ash::local_search_service::mojom::ResponseStatus
-EnumTraits<ash::local_search_service::mojom::ResponseStatus,
-           ash::local_search_service::ResponseStatus>::
-    ToMojom(ash::local_search_service::ResponseStatus input) {
+chromeos::local_search_service::mojom::ResponseStatus
+EnumTraits<chromeos::local_search_service::mojom::ResponseStatus,
+           chromeos::local_search_service::ResponseStatus>::
+    ToMojom(chromeos::local_search_service::ResponseStatus input) {
   switch (input) {
-    case ash::local_search_service::ResponseStatus::kUnknownError:
-      return ash::local_search_service::mojom::ResponseStatus::kUnknownError;
-    case ash::local_search_service::ResponseStatus::kSuccess:
-      return ash::local_search_service::mojom::ResponseStatus::kSuccess;
-    case ash::local_search_service::ResponseStatus::kEmptyQuery:
-      return ash::local_search_service::mojom::ResponseStatus::kEmptyQuery;
-    case ash::local_search_service::ResponseStatus::kEmptyIndex:
-      return ash::local_search_service::mojom::ResponseStatus::kEmptyIndex;
+    case chromeos::local_search_service::ResponseStatus::kUnknownError:
+      return chromeos::local_search_service::mojom::ResponseStatus::
+          kUnknownError;
+    case chromeos::local_search_service::ResponseStatus::kSuccess:
+      return chromeos::local_search_service::mojom::ResponseStatus::kSuccess;
+    case chromeos::local_search_service::ResponseStatus::kEmptyQuery:
+      return chromeos::local_search_service::mojom::ResponseStatus::kEmptyQuery;
+    case chromeos::local_search_service::ResponseStatus::kEmptyIndex:
+      return chromeos::local_search_service::mojom::ResponseStatus::kEmptyIndex;
   }
   NOTREACHED();
-  return ash::local_search_service::mojom::ResponseStatus::kUnknownError;
+  return chromeos::local_search_service::mojom::ResponseStatus::kUnknownError;
 }
 
 // static
-bool EnumTraits<ash::local_search_service::mojom::ResponseStatus,
-                ash::local_search_service::ResponseStatus>::
-    FromMojom(ash::local_search_service::mojom::ResponseStatus input,
-              ash::local_search_service::ResponseStatus* output) {
+bool EnumTraits<chromeos::local_search_service::mojom::ResponseStatus,
+                chromeos::local_search_service::ResponseStatus>::
+    FromMojom(chromeos::local_search_service::mojom::ResponseStatus input,
+              chromeos::local_search_service::ResponseStatus* output) {
   switch (input) {
-    case ash::local_search_service::mojom::ResponseStatus::kUnknownError:
-      *output = ash::local_search_service::ResponseStatus::kUnknownError;
+    case chromeos::local_search_service::mojom::ResponseStatus::kUnknownError:
+      *output = chromeos::local_search_service::ResponseStatus::kUnknownError;
       return true;
-    case ash::local_search_service::mojom::ResponseStatus::kSuccess:
-      *output = ash::local_search_service::ResponseStatus::kSuccess;
+    case chromeos::local_search_service::mojom::ResponseStatus::kSuccess:
+      *output = chromeos::local_search_service::ResponseStatus::kSuccess;
       return true;
-    case ash::local_search_service::mojom::ResponseStatus::kEmptyQuery:
-      *output = ash::local_search_service::ResponseStatus::kEmptyQuery;
+    case chromeos::local_search_service::mojom::ResponseStatus::kEmptyQuery:
+      *output = chromeos::local_search_service::ResponseStatus::kEmptyQuery;
       return true;
-    case ash::local_search_service::mojom::ResponseStatus::kEmptyIndex:
-      *output = ash::local_search_service::ResponseStatus::kEmptyIndex;
+    case chromeos::local_search_service::mojom::ResponseStatus::kEmptyIndex:
+      *output = chromeos::local_search_service::ResponseStatus::kEmptyIndex;
       return true;
   }
   NOTREACHED();
diff --git a/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.h b/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.h
index 86ca6eb6..1fa059d 100644
--- a/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.h
+++ b/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits.h
@@ -15,126 +15,130 @@
 namespace mojo {
 
 template <>
-struct EnumTraits<ash::local_search_service::mojom::IndexId,
-                  ash::local_search_service::IndexId> {
-  static ash::local_search_service::mojom::IndexId ToMojom(
-      ash::local_search_service::IndexId input);
-  static bool FromMojom(ash::local_search_service::mojom::IndexId input,
-                        ash::local_search_service::IndexId* output);
+struct EnumTraits<chromeos::local_search_service::mojom::IndexId,
+                  chromeos::local_search_service::IndexId> {
+  static chromeos::local_search_service::mojom::IndexId ToMojom(
+      chromeos::local_search_service::IndexId input);
+  static bool FromMojom(chromeos::local_search_service::mojom::IndexId input,
+                        chromeos::local_search_service::IndexId* output);
 };
 
 template <>
-struct EnumTraits<ash::local_search_service::mojom::Backend,
-                  ash::local_search_service::Backend> {
-  static ash::local_search_service::mojom::Backend ToMojom(
-      ash::local_search_service::Backend input);
-  static bool FromMojom(ash::local_search_service::mojom::Backend input,
-                        ash::local_search_service::Backend* output);
+struct EnumTraits<chromeos::local_search_service::mojom::Backend,
+                  chromeos::local_search_service::Backend> {
+  static chromeos::local_search_service::mojom::Backend ToMojom(
+      chromeos::local_search_service::Backend input);
+  static bool FromMojom(chromeos::local_search_service::mojom::Backend input,
+                        chromeos::local_search_service::Backend* output);
 };
 
 template <>
-struct StructTraits<ash::local_search_service::mojom::ContentDataView,
-                    ash::local_search_service::Content> {
+struct StructTraits<chromeos::local_search_service::mojom::ContentDataView,
+                    chromeos::local_search_service::Content> {
  public:
-  static std::string id(const ash::local_search_service::Content& c) {
+  static std::string id(const chromeos::local_search_service::Content& c) {
     return c.id;
   }
-  static std::u16string content(const ash::local_search_service::Content& c) {
+  static std::u16string content(
+      const chromeos::local_search_service::Content& c) {
     return c.content;
   }
-  static double weight(const ash::local_search_service::Content& c) {
+  static double weight(const chromeos::local_search_service::Content& c) {
     return c.weight;
   }
 
-  static bool Read(ash::local_search_service::mojom::ContentDataView data,
-                   ash::local_search_service::Content* out);
+  static bool Read(chromeos::local_search_service::mojom::ContentDataView data,
+                   chromeos::local_search_service::Content* out);
 };
 
 template <>
-struct StructTraits<ash::local_search_service::mojom::DataDataView,
-                    ash::local_search_service::Data> {
+struct StructTraits<chromeos::local_search_service::mojom::DataDataView,
+                    chromeos::local_search_service::Data> {
  public:
-  static std::string id(const ash::local_search_service::Data& d) {
+  static std::string id(const chromeos::local_search_service::Data& d) {
     return d.id;
   }
-  static std::vector<ash::local_search_service::Content> contents(
-      const ash::local_search_service::Data& d) {
+  static std::vector<chromeos::local_search_service::Content> contents(
+      const chromeos::local_search_service::Data& d) {
     return d.contents;
   }
 
-  static std::string locale(const ash::local_search_service::Data& d) {
+  static std::string locale(const chromeos::local_search_service::Data& d) {
     return d.locale;
   }
 
-  static bool Read(ash::local_search_service::mojom::DataDataView data,
-                   ash::local_search_service::Data* out);
+  static bool Read(chromeos::local_search_service::mojom::DataDataView data,
+                   chromeos::local_search_service::Data* out);
 };
 
 template <>
-struct StructTraits<ash::local_search_service::mojom::SearchParamsDataView,
-                    ash::local_search_service::SearchParams> {
+struct StructTraits<chromeos::local_search_service::mojom::SearchParamsDataView,
+                    chromeos::local_search_service::SearchParams> {
  public:
   static double relevance_threshold(
-      const ash::local_search_service::SearchParams& s) {
+      const chromeos::local_search_service::SearchParams& s) {
     return s.relevance_threshold;
   }
   static double prefix_threshold(
-      const ash::local_search_service::SearchParams& s) {
+      const chromeos::local_search_service::SearchParams& s) {
     return s.prefix_threshold;
   }
   static double fuzzy_threshold(
-      const ash::local_search_service::SearchParams& s) {
+      const chromeos::local_search_service::SearchParams& s) {
     return s.fuzzy_threshold;
   }
 
-  static bool Read(ash::local_search_service::mojom::SearchParamsDataView data,
-                   ash::local_search_service::SearchParams* out);
+  static bool Read(
+      chromeos::local_search_service::mojom::SearchParamsDataView data,
+      chromeos::local_search_service::SearchParams* out);
 };
 
 template <>
-struct StructTraits<ash::local_search_service::mojom::PositionDataView,
-                    ash::local_search_service::Position> {
+struct StructTraits<chromeos::local_search_service::mojom::PositionDataView,
+                    chromeos::local_search_service::Position> {
  public:
-  static std::string content_id(const ash::local_search_service::Position& p) {
+  static std::string content_id(
+      const chromeos::local_search_service::Position& p) {
     return p.content_id;
   }
-  static uint32_t start(const ash::local_search_service::Position& p) {
+  static uint32_t start(const chromeos::local_search_service::Position& p) {
     return p.start;
   }
-  static uint32_t length(const ash::local_search_service::Position& p) {
+  static uint32_t length(const chromeos::local_search_service::Position& p) {
     return p.length;
   }
 
-  static bool Read(ash::local_search_service::mojom::PositionDataView data,
-                   ash::local_search_service::Position* out);
+  static bool Read(chromeos::local_search_service::mojom::PositionDataView data,
+                   chromeos::local_search_service::Position* out);
 };
 
 template <>
-struct StructTraits<ash::local_search_service::mojom::ResultDataView,
-                    ash::local_search_service::Result> {
+struct StructTraits<chromeos::local_search_service::mojom::ResultDataView,
+                    chromeos::local_search_service::Result> {
  public:
-  static std::string id(const ash::local_search_service::Result& r) {
+  static std::string id(const chromeos::local_search_service::Result& r) {
     return r.id;
   }
-  static double score(const ash::local_search_service::Result& r) {
+  static double score(const chromeos::local_search_service::Result& r) {
     return r.score;
   }
-  static std::vector<ash::local_search_service::Position> positions(
-      const ash::local_search_service::Result& r) {
+  static std::vector<chromeos::local_search_service::Position> positions(
+      const chromeos::local_search_service::Result& r) {
     return r.positions;
   }
 
-  static bool Read(ash::local_search_service::mojom::ResultDataView data,
-                   ash::local_search_service::Result* out);
+  static bool Read(chromeos::local_search_service::mojom::ResultDataView data,
+                   chromeos::local_search_service::Result* out);
 };
 
 template <>
-struct EnumTraits<ash::local_search_service::mojom::ResponseStatus,
-                  ash::local_search_service::ResponseStatus> {
-  static ash::local_search_service::mojom::ResponseStatus ToMojom(
-      ash::local_search_service::ResponseStatus input);
-  static bool FromMojom(ash::local_search_service::mojom::ResponseStatus input,
-                        ash::local_search_service::ResponseStatus* out);
+struct EnumTraits<chromeos::local_search_service::mojom::ResponseStatus,
+                  chromeos::local_search_service::ResponseStatus> {
+  static chromeos::local_search_service::mojom::ResponseStatus ToMojom(
+      chromeos::local_search_service::ResponseStatus input);
+  static bool FromMojom(
+      chromeos::local_search_service::mojom::ResponseStatus input,
+      chromeos::local_search_service::ResponseStatus* out);
 };
 
 }  // namespace mojo
diff --git a/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits_unittest.cc b/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits_unittest.cc
index 609e8a6..d69a0c328 100644
--- a/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits_unittest.cc
+++ b/chromeos/ash/components/local_search_service/public/mojom/types_mojom_traits_unittest.cc
@@ -9,7 +9,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 TEST(LocalSearchMojomTraitsTest, ContentTraits) {
   Content input("id", u"content", 0.3);
@@ -103,4 +104,5 @@
   EXPECT_EQ(input.positions[1].length, output.positions[1].length);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/search_metrics_reporter.cc b/chromeos/ash/components/local_search_service/search_metrics_reporter.cc
index b9983f8..fb261c62 100644
--- a/chromeos/ash/components/local_search_service/search_metrics_reporter.cc
+++ b/chromeos/ash/components/local_search_service/search_metrics_reporter.cc
@@ -11,8 +11,8 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 
-namespace ash::local_search_service {
-
+namespace chromeos {
+namespace local_search_service {
 namespace {
 
 // Interval for asking metrics::DailyEvent to check whether a day has passed.
@@ -145,4 +145,5 @@
   }
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/search_metrics_reporter.h b/chromeos/ash/components/local_search_service/search_metrics_reporter.h
index 36f1a6f..df71613 100644
--- a/chromeos/ash/components/local_search_service/search_metrics_reporter.h
+++ b/chromeos/ash/components/local_search_service/search_metrics_reporter.h
@@ -15,7 +15,8 @@
 class PrefRegistrySimple;
 class PrefService;
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 // SearchMetricsReporter logs daily search requests to UMA.
 class SearchMetricsReporter : public mojom::SearchMetricsReporter {
@@ -74,6 +75,7 @@
       receivers_;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_SEARCH_METRICS_REPORTER_H_
diff --git a/chromeos/ash/components/local_search_service/search_metrics_reporter_unittest.cc b/chromeos/ash/components/local_search_service/search_metrics_reporter_unittest.cc
index f4ab7d7..0e6b3f47 100644
--- a/chromeos/ash/components/local_search_service/search_metrics_reporter_unittest.cc
+++ b/chromeos/ash/components/local_search_service/search_metrics_reporter_unittest.cc
@@ -14,7 +14,8 @@
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 class SearchMetricsReporterTest : public testing::Test {
  public:
@@ -133,4 +134,5 @@
                                        0);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/search_utils.cc b/chromeos/ash/components/local_search_service/search_utils.cc
index a2e19c2..3740086 100644
--- a/chromeos/ash/components/local_search_service/search_utils.cc
+++ b/chromeos/ash/components/local_search_service/search_utils.cc
@@ -21,7 +21,8 @@
 #include "chromeos/components/string_matching/tokenized_string.h"
 #include "third_party/icu/source/i18n/unicode/translit.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 float ExactPrefixMatchScore(const std::u16string& query,
                             const std::u16string& text) {
@@ -61,4 +62,5 @@
   return r1.score > r2.score;
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/search_utils.h b/chromeos/ash/components/local_search_service/search_utils.h
index 443bdc4..7e13af1 100644
--- a/chromeos/ash/components/local_search_service/search_utils.h
+++ b/chromeos/ash/components/local_search_service/search_utils.h
@@ -7,7 +7,8 @@
 
 #include <string>
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 struct Result;
 
@@ -31,6 +32,7 @@
 // Returns whether |r1| score is higher than |r2|'s.
 bool CompareResults(const Result& r1, const Result& r2);
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_SEARCH_UTILS_H_
diff --git a/chromeos/ash/components/local_search_service/search_utils_unittest.cc b/chromeos/ash/components/local_search_service/search_utils_unittest.cc
index 09acc64..0a4f35c 100644
--- a/chromeos/ash/components/local_search_service/search_utils_unittest.cc
+++ b/chromeos/ash/components/local_search_service/search_utils_unittest.cc
@@ -10,7 +10,8 @@
 #include "chromeos/ash/components/local_search_service/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 TEST(SearchUtilsTest, PrefixMatch) {
   // Query is a prefix of text, score is the ratio.
@@ -73,4 +74,5 @@
               0.001);
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/shared_structs.cc b/chromeos/ash/components/local_search_service/shared_structs.cc
index c1e516b..c34dc90 100644
--- a/chromeos/ash/components/local_search_service/shared_structs.cc
+++ b/chromeos/ash/components/local_search_service/shared_structs.cc
@@ -13,7 +13,8 @@
 #include "chromeos/components/string_matching/tokenized_string.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 local_search_service::Content::Content(const std::string& id,
                                        const std::u16string& content,
@@ -62,4 +63,5 @@
     : content(token.content), positions(token.positions) {}
 Token::~Token() = default;
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/shared_structs.h b/chromeos/ash/components/local_search_service/shared_structs.h
index 66d3754f..bb1f4505 100644
--- a/chromeos/ash/components/local_search_service/shared_structs.h
+++ b/chromeos/ash/components/local_search_service/shared_structs.h
@@ -8,7 +8,8 @@
 #include <string>
 #include <vector>
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 // This should be kept in sync with
 // //tools/metrics/histograms/metadata/local/histograms.xml.
@@ -163,13 +164,19 @@
   std::vector<WeightedPosition> positions;
 };
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
-// TODO(https://crbug.com/1164001): remove after the migration is finished.
-namespace chromeos::local_search_service {
-using ::ash::local_search_service::Data;
-using ::ash::local_search_service::ResponseStatus;
-using ::ash::local_search_service::Result;
-}  // namespace chromeos::local_search_service
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace local_search_service {
+using ::chromeos::local_search_service::Backend;
+using ::chromeos::local_search_service::Content;
+using ::chromeos::local_search_service::Data;
+using ::chromeos::local_search_service::IndexId;
+using ::chromeos::local_search_service::ResponseStatus;
+using ::chromeos::local_search_service::Result;
+}  // namespace local_search_service
+}  // namespace ash
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_SHARED_STRUCTS_H_
diff --git a/chromeos/ash/components/local_search_service/test_utils.cc b/chromeos/ash/components/local_search_service/test_utils.cc
index 95fa74b1..7896910 100644
--- a/chromeos/ash/components/local_search_service/test_utils.cc
+++ b/chromeos/ash/components/local_search_service/test_utils.cc
@@ -10,7 +10,8 @@
 #include <utility>
 #include <vector>
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 namespace {
 
@@ -89,4 +90,5 @@
   return tf * idf;
 }
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/ash/components/local_search_service/test_utils.h b/chromeos/ash/components/local_search_service/test_utils.h
index 3f74bd0..f29a39c 100644
--- a/chromeos/ash/components/local_search_service/test_utils.h
+++ b/chromeos/ash/components/local_search_service/test_utils.h
@@ -14,7 +14,8 @@
 #include "chromeos/ash/components/local_search_service/shared_structs.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace ash::local_search_service {
+namespace chromeos {
+namespace local_search_service {
 
 // Creates test data to be registered to the index. |input| is a map from
 // id to contents (id and content).
@@ -39,6 +40,7 @@
                  float weighted_num_term_occurrence_in_doc,
                  size_t doc_length);
 
-}  // namespace ash::local_search_service
+}  // namespace local_search_service
+}  // namespace chromeos
 
 #endif  // CHROMEOS_ASH_COMPONENTS_LOCAL_SEARCH_SERVICE_TEST_UTILS_H_
diff --git a/chromeos/ash/services/assistant/platform/audio_devices.cc b/chromeos/ash/services/assistant/platform/audio_devices.cc
index 086ab85..c512919 100644
--- a/chromeos/ash/services/assistant/platform/audio_devices.cc
+++ b/chromeos/ash/services/assistant/platform/audio_devices.cc
@@ -104,10 +104,13 @@
       case chromeos::AudioDeviceType::kHeadphone:
       case chromeos::AudioDeviceType::kInternalMic:
       case chromeos::AudioDeviceType::kFrontMic:
+      case chromeos::AudioDeviceType::kRearMic:
+      case chromeos::AudioDeviceType::kKeyboardMic:
         result = GetHighestPriorityDevice(result, &device);
         break;
       default:
-        // ignore other devices
+        // Ignore other devices. Note that we ignore bluetooth devices due to
+        // battery consumption concerns.
         break;
     }
   }
diff --git a/chromeos/ash/services/assistant/platform/audio_devices_unittest.cc b/chromeos/ash/services/assistant/platform/audio_devices_unittest.cc
index 6c207c6..26e4333a 100644
--- a/chromeos/ash/services/assistant/platform/audio_devices_unittest.cc
+++ b/chromeos/ash/services/assistant/platform/audio_devices_unittest.cc
@@ -208,14 +208,26 @@
   EXPECT_EQ("555", observer.preferred_device_id());
 }
 
-TEST_F(AssistantAudioDevicesTest, ShouldNotSendHdmiDeviceToObserver) {
+TEST_F(AssistantAudioDevicesTest, ShouldSendRearMicDeviceToObserver) {
   FakeAudioDevicesObserver observer;
   audio_devices().AddAndFireObserver(&observer);
 
-  UpdateDeviceList({DeviceBuilder(AudioDeviceType::kHdmi).WithId(999).Build()});
+  UpdateDeviceList(
+      {DeviceBuilder(AudioDeviceType::kRearMic).WithId(666).Build()});
 
   EXPECT_EQ("<none>", observer.hotword_device_id());
-  EXPECT_EQ("<none>", observer.preferred_device_id());
+  EXPECT_EQ("666", observer.preferred_device_id());
+}
+
+TEST_F(AssistantAudioDevicesTest, ShouldSendKeyboardMicDeviceToObserver) {
+  FakeAudioDevicesObserver observer;
+  audio_devices().AddAndFireObserver(&observer);
+
+  UpdateDeviceList(
+      {DeviceBuilder(AudioDeviceType::kKeyboardMic).WithId(777).Build()});
+
+  EXPECT_EQ("<none>", observer.hotword_device_id());
+  EXPECT_EQ("777", observer.preferred_device_id());
 }
 
 TEST_F(AssistantAudioDevicesTest, ShouldUseHighestPriorityHotwordDevice) {
@@ -310,8 +322,6 @@
       DeviceBuilder(AudioDeviceType::kBluetoothNbMic).WithId(3).Build(),
       DeviceBuilder(AudioDeviceType::kHdmi).WithId(4).Build(),
       DeviceBuilder(AudioDeviceType::kInternalSpeaker).WithId(5).Build(),
-      DeviceBuilder(AudioDeviceType::kRearMic).WithId(6).Build(),
-      DeviceBuilder(AudioDeviceType::kKeyboardMic).WithId(7).Build(),
       DeviceBuilder(AudioDeviceType::kLineout).WithId(8).Build(),
       DeviceBuilder(AudioDeviceType::kPostMixLoopback).WithId(9).Build(),
       DeviceBuilder(AudioDeviceType::kPostDspLoopback).WithId(10).Build(),
diff --git a/chromeos/components/string_matching/README.md b/chromeos/components/string_matching/README.md
new file mode 100644
index 0000000..7bf4474
--- /dev/null
+++ b/chromeos/components/string_matching/README.md
@@ -0,0 +1,36 @@
+## About
+
+This Chrome OS string matching library provides functionality to compute the
+similarity scores between two given strings.
+
+This library's main use is within the launcher backend ranking system
+(`chrome/browser/ui/app_list/search/`).
+
+The entry points to this library are via either:
+
+1. `FuzzyTokenizedStringMatch`
+    * For fuzzy matching.
+1. `TokenizedStringMatch`
+    * For non-fuzzy matching.
+
+## Testing
+
+The `FuzzyTokenizedStringMatch` class is complex and evolving. As such, we do
+not currently enforce many specific and strict scoring requirements for sample
+query-text pairs. However, there are tests which optionally log detailed
+scoring output for manual inspection.
+
+If making changes to fuzzy string matching functionality, please inspect the
+benchmarking unit tests with verbose logging enabled. Steps:
+
+Add to gn args:
+
+```
+use_runtime_vlog = true
+```
+
+Build and run tests:
+
+```sh
+autoninja -C out/Default chromeos_components_unittests && out/Default/chromeos_components_unittests --gtest_filter=*FuzzyTokenizedStringMatchTest.Benchmark* --v=1
+```
diff --git a/chromeos/components/string_matching/fuzzy_tokenized_string_match_unittest.cc b/chromeos/components/string_matching/fuzzy_tokenized_string_match_unittest.cc
index f6db468..d173c947 100644
--- a/chromeos/components/string_matching/fuzzy_tokenized_string_match_unittest.cc
+++ b/chromeos/components/string_matching/fuzzy_tokenized_string_match_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chromeos/components/string_matching/fuzzy_tokenized_string_match.h"
 
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chromeos/components/string_matching/sequence_matcher.h"
 #include "chromeos/components/string_matching/tokenized_string.h"
@@ -13,13 +15,61 @@
 namespace string_matching {
 
 namespace {
+
+// Default parameters.
+constexpr bool kUseWeightedRatio = false;
+constexpr bool kUseEditDistance = false;
 constexpr double kPartialMatchPenaltyRate = 0.9;
 
+double CalculateRelevance(std::u16string query, std::u16string text) {
+  FuzzyTokenizedStringMatch match;
+  return match.Relevance(TokenizedString(query), TokenizedString(text),
+                         kUseWeightedRatio, kUseEditDistance,
+                         kPartialMatchPenaltyRate);
+}
+
+std::string FormatRelevanceResult(std::u16string text,
+                                  std::u16string query,
+                                  double relevance) {
+  // Display text before query. Series of tests will tend to use the same
+  // text repeatedly while varying the query, so displaying the text first is
+  // more visually useful.
+  return base::StringPrintf("text: %s, query: %s, relevance: %f",
+                            base::UTF16ToUTF8(text).data(),
+                            base::UTF16ToUTF8(query).data(), relevance);
+}
+
 }  // namespace
 
 class FuzzyTokenizedStringMatchTest : public testing::Test {};
 
-// TODO(crbug.com/1018613): update the tests once params are consolidated.
+/**********************************************************************
+ * Benchmarking tests                                                 *
+ **********************************************************************/
+// The tests in this section perform benchmarking on the quality of
+// relevance scores. See the README for details.
+// TODO(crbug.com/1336160): Expand benchmarking tests.
+
+TEST_F(FuzzyTokenizedStringMatchTest, Benchmark_Chrome) {
+  std::vector<std::u16string> texts = {u"Chrome", u"Google Chrome"};
+  std::vector<std::u16string> queries = {u"c",    u"ch",    u"chr",
+                                         u"chro", u"chrom", u"chrome"};
+
+  for (auto text : texts) {
+    for (auto query : queries) {
+      double relevance = CalculateRelevance(query, text);
+      VLOG(1) << FormatRelevanceResult(text, query, relevance);
+    }
+  }
+}
+
+/**********************************************************************
+ * Per-method tests                                                   *
+ **********************************************************************/
+// The tests in this section check the functionality of individual class
+// methods (as opposed to the score benchmarking performed above).
+
+// TODO(crbug.com/1336160): update the tests once params are consolidated.
 TEST_F(FuzzyTokenizedStringMatchTest, PartialRatioTest) {
   FuzzyTokenizedStringMatch match;
   EXPECT_NEAR(match.PartialRatio(u"abcde", u"ababcXXXbcdeY",
diff --git a/chromeos/crosapi/mojom/BUILD.gn b/chromeos/crosapi/mojom/BUILD.gn
index f6b4e83..889bf4d 100644
--- a/chromeos/crosapi/mojom/BUILD.gn
+++ b/chromeos/crosapi/mojom/BUILD.gn
@@ -169,7 +169,7 @@
         },
         {
           mojom = "crosapi.mojom.LaunchSource"
-          cpp = "::apps::mojom::LaunchSource"
+          cpp = "::apps::LaunchSource"
         },
         {
           mojom = "crosapi.mojom.SharesheetLaunchSource"
@@ -228,6 +228,7 @@
         "//chromeos/crosapi/mojom/policy_domain_mojom_traits.h",
         "//chromeos/crosapi/mojom/web_app_types_mojom_traits.h",
         "//chromeos/crosapi/mojom/browser_app_instance_registry_mojom_traits.h",
+        "//components/services/app_service/public/cpp/app_launch_util.h",
         "//components/services/app_service/public/cpp/app_types.h",
         "//components/services/app_service/public/cpp/preferred_app.h",
         "//chromeos/crosapi/mojom/sharesheet_mojom_traits.h",
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
index c46fada..d44480b 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
@@ -834,170 +834,170 @@
 }
 
 crosapi::mojom::LaunchSource
-EnumTraits<crosapi::mojom::LaunchSource, apps::mojom::LaunchSource>::ToMojom(
-    apps::mojom::LaunchSource input) {
+EnumTraits<crosapi::mojom::LaunchSource, apps::LaunchSource>::ToMojom(
+    apps::LaunchSource input) {
   switch (input) {
-    case apps::mojom::LaunchSource::kUnknown:
+    case apps::LaunchSource::kUnknown:
       return crosapi::mojom::LaunchSource::kUnknown;
-    case apps::mojom::LaunchSource::kFromAppListGrid:
+    case apps::LaunchSource::kFromAppListGrid:
       return crosapi::mojom::LaunchSource::kFromAppListGrid;
-    case apps::mojom::LaunchSource::kFromAppListGridContextMenu:
+    case apps::LaunchSource::kFromAppListGridContextMenu:
       return crosapi::mojom::LaunchSource::kFromAppListGridContextMenu;
-    case apps::mojom::LaunchSource::kFromAppListQuery:
+    case apps::LaunchSource::kFromAppListQuery:
       return crosapi::mojom::LaunchSource::kFromAppListQuery;
-    case apps::mojom::LaunchSource::kFromAppListQueryContextMenu:
+    case apps::LaunchSource::kFromAppListQueryContextMenu:
       return crosapi::mojom::LaunchSource::kFromAppListQueryContextMenu;
-    case apps::mojom::LaunchSource::kFromAppListRecommendation:
+    case apps::LaunchSource::kFromAppListRecommendation:
       return crosapi::mojom::LaunchSource::kFromAppListRecommendation;
-    case apps::mojom::LaunchSource::kFromParentalControls:
+    case apps::LaunchSource::kFromParentalControls:
       return crosapi::mojom::LaunchSource::kFromParentalControls;
-    case apps::mojom::LaunchSource::kFromShelf:
+    case apps::LaunchSource::kFromShelf:
       return crosapi::mojom::LaunchSource::kFromShelf;
-    case apps::mojom::LaunchSource::kFromFileManager:
+    case apps::LaunchSource::kFromFileManager:
       return crosapi::mojom::LaunchSource::kFromFileManager;
-    case apps::mojom::LaunchSource::kFromLink:
+    case apps::LaunchSource::kFromLink:
       return crosapi::mojom::LaunchSource::kFromLink;
-    case apps::mojom::LaunchSource::kFromOmnibox:
+    case apps::LaunchSource::kFromOmnibox:
       return crosapi::mojom::LaunchSource::kFromOmnibox;
-    case apps::mojom::LaunchSource::kFromChromeInternal:
+    case apps::LaunchSource::kFromChromeInternal:
       return crosapi::mojom::LaunchSource::kFromChromeInternal;
-    case apps::mojom::LaunchSource::kFromKeyboard:
+    case apps::LaunchSource::kFromKeyboard:
       return crosapi::mojom::LaunchSource::kFromKeyboard;
-    case apps::mojom::LaunchSource::kFromOtherApp:
+    case apps::LaunchSource::kFromOtherApp:
       return crosapi::mojom::LaunchSource::kFromOtherApp;
-    case apps::mojom::LaunchSource::kFromMenu:
+    case apps::LaunchSource::kFromMenu:
       return crosapi::mojom::LaunchSource::kFromMenu;
-    case apps::mojom::LaunchSource::kFromInstalledNotification:
+    case apps::LaunchSource::kFromInstalledNotification:
       return crosapi::mojom::LaunchSource::kFromInstalledNotification;
-    case apps::mojom::LaunchSource::kFromTest:
+    case apps::LaunchSource::kFromTest:
       return crosapi::mojom::LaunchSource::kFromTest;
-    case apps::mojom::LaunchSource::kFromArc:
+    case apps::LaunchSource::kFromArc:
       return crosapi::mojom::LaunchSource::kFromArc;
-    case apps::mojom::LaunchSource::kFromSharesheet:
+    case apps::LaunchSource::kFromSharesheet:
       return crosapi::mojom::LaunchSource::kFromSharesheet;
-    case apps::mojom::LaunchSource::kFromReleaseNotesNotification:
+    case apps::LaunchSource::kFromReleaseNotesNotification:
       return crosapi::mojom::LaunchSource::kFromReleaseNotesNotification;
-    case apps::mojom::LaunchSource::kFromFullRestore:
+    case apps::LaunchSource::kFromFullRestore:
       return crosapi::mojom::LaunchSource::kFromFullRestore;
-    case apps::mojom::LaunchSource::kFromSmartTextContextMenu:
+    case apps::LaunchSource::kFromSmartTextContextMenu:
       return crosapi::mojom::LaunchSource::kFromSmartTextContextMenu;
-    case apps::mojom::LaunchSource::kFromDiscoverTabNotification:
+    case apps::LaunchSource::kFromDiscoverTabNotification:
       return crosapi::mojom::LaunchSource::kFromDiscoverTabNotification;
-    case apps::mojom::LaunchSource::kFromManagementApi:
+    case apps::LaunchSource::kFromManagementApi:
       return crosapi::mojom::LaunchSource::kFromManagementApi;
-    case apps::mojom::LaunchSource::kFromKiosk:
+    case apps::LaunchSource::kFromKiosk:
       return crosapi::mojom::LaunchSource::kFromKiosk;
-    case apps::mojom::LaunchSource::kFromNewTabPage:
+    case apps::LaunchSource::kFromNewTabPage:
       return crosapi::mojom::LaunchSource::kFromNewTabPage;
-    case apps::mojom::LaunchSource::kFromIntentUrl:
+    case apps::LaunchSource::kFromIntentUrl:
       return crosapi::mojom::LaunchSource::kFromIntentUrl;
-    case apps::mojom::LaunchSource::kFromOsLogin:
+    case apps::LaunchSource::kFromOsLogin:
       return crosapi::mojom::LaunchSource::kFromOsLogin;
-    case apps::mojom::LaunchSource::kFromProtocolHandler:
+    case apps::LaunchSource::kFromProtocolHandler:
       return crosapi::mojom::LaunchSource::kFromProtocolHandler;
-    case apps::mojom::LaunchSource::kFromUrlHandler:
+    case apps::LaunchSource::kFromUrlHandler:
       return crosapi::mojom::LaunchSource::kFromUrlHandler;
-    case apps::mojom::LaunchSource::kFromCommandLine:
-    case apps::mojom::LaunchSource::kFromBackgroundMode:
+    case apps::LaunchSource::kFromCommandLine:
+    case apps::LaunchSource::kFromBackgroundMode:
       NOTREACHED();
       return crosapi::mojom::LaunchSource::kUnknown;
   }
   NOTREACHED();
 }
 
-bool EnumTraits<crosapi::mojom::LaunchSource, apps::mojom::LaunchSource>::
-    FromMojom(crosapi::mojom::LaunchSource input,
-              apps::mojom::LaunchSource* output) {
+bool EnumTraits<crosapi::mojom::LaunchSource, apps::LaunchSource>::FromMojom(
+    crosapi::mojom::LaunchSource input,
+    apps::LaunchSource* output) {
   switch (input) {
     case crosapi::mojom::LaunchSource::kUnknown:
-      *output = apps::mojom::LaunchSource::kUnknown;
+      *output = apps::LaunchSource::kUnknown;
       return true;
     case crosapi::mojom::LaunchSource::kFromAppListGrid:
-      *output = apps::mojom::LaunchSource::kFromAppListGrid;
+      *output = apps::LaunchSource::kFromAppListGrid;
       return true;
     case crosapi::mojom::LaunchSource::kFromAppListGridContextMenu:
-      *output = apps::mojom::LaunchSource::kFromAppListGridContextMenu;
+      *output = apps::LaunchSource::kFromAppListGridContextMenu;
       return true;
     case crosapi::mojom::LaunchSource::kFromAppListQuery:
-      *output = apps::mojom::LaunchSource::kFromAppListQuery;
+      *output = apps::LaunchSource::kFromAppListQuery;
       return true;
     case crosapi::mojom::LaunchSource::kFromAppListQueryContextMenu:
-      *output = apps::mojom::LaunchSource::kFromAppListQueryContextMenu;
+      *output = apps::LaunchSource::kFromAppListQueryContextMenu;
       return true;
     case crosapi::mojom::LaunchSource::kFromAppListRecommendation:
-      *output = apps::mojom::LaunchSource::kFromAppListRecommendation;
+      *output = apps::LaunchSource::kFromAppListRecommendation;
       return true;
     case crosapi::mojom::LaunchSource::kFromParentalControls:
-      *output = apps::mojom::LaunchSource::kFromParentalControls;
+      *output = apps::LaunchSource::kFromParentalControls;
       return true;
     case crosapi::mojom::LaunchSource::kFromShelf:
-      *output = apps::mojom::LaunchSource::kFromShelf;
+      *output = apps::LaunchSource::kFromShelf;
       return true;
     case crosapi::mojom::LaunchSource::kFromFileManager:
-      *output = apps::mojom::LaunchSource::kFromFileManager;
+      *output = apps::LaunchSource::kFromFileManager;
       return true;
     case crosapi::mojom::LaunchSource::kFromLink:
-      *output = apps::mojom::LaunchSource::kFromLink;
+      *output = apps::LaunchSource::kFromLink;
       return true;
     case crosapi::mojom::LaunchSource::kFromOmnibox:
-      *output = apps::mojom::LaunchSource::kFromOmnibox;
+      *output = apps::LaunchSource::kFromOmnibox;
       return true;
     case crosapi::mojom::LaunchSource::kFromChromeInternal:
-      *output = apps::mojom::LaunchSource::kFromChromeInternal;
+      *output = apps::LaunchSource::kFromChromeInternal;
       return true;
     case crosapi::mojom::LaunchSource::kFromKeyboard:
-      *output = apps::mojom::LaunchSource::kFromKeyboard;
+      *output = apps::LaunchSource::kFromKeyboard;
       return true;
     case crosapi::mojom::LaunchSource::kFromOtherApp:
-      *output = apps::mojom::LaunchSource::kFromOtherApp;
+      *output = apps::LaunchSource::kFromOtherApp;
       return true;
     case crosapi::mojom::LaunchSource::kFromMenu:
-      *output = apps::mojom::LaunchSource::kFromMenu;
+      *output = apps::LaunchSource::kFromMenu;
       return true;
     case crosapi::mojom::LaunchSource::kFromInstalledNotification:
-      *output = apps::mojom::LaunchSource::kFromInstalledNotification;
+      *output = apps::LaunchSource::kFromInstalledNotification;
       return true;
     case crosapi::mojom::LaunchSource::kFromTest:
-      *output = apps::mojom::LaunchSource::kFromTest;
+      *output = apps::LaunchSource::kFromTest;
       return true;
     case crosapi::mojom::LaunchSource::kFromArc:
-      *output = apps::mojom::LaunchSource::kFromArc;
+      *output = apps::LaunchSource::kFromArc;
       return true;
     case crosapi::mojom::LaunchSource::kFromSharesheet:
-      *output = apps::mojom::LaunchSource::kFromSharesheet;
+      *output = apps::LaunchSource::kFromSharesheet;
       return true;
     case crosapi::mojom::LaunchSource::kFromReleaseNotesNotification:
-      *output = apps::mojom::LaunchSource::kFromReleaseNotesNotification;
+      *output = apps::LaunchSource::kFromReleaseNotesNotification;
       return true;
     case crosapi::mojom::LaunchSource::kFromFullRestore:
-      *output = apps::mojom::LaunchSource::kFromFullRestore;
+      *output = apps::LaunchSource::kFromFullRestore;
       return true;
     case crosapi::mojom::LaunchSource::kFromSmartTextContextMenu:
-      *output = apps::mojom::LaunchSource::kFromSmartTextContextMenu;
+      *output = apps::LaunchSource::kFromSmartTextContextMenu;
       return true;
     case crosapi::mojom::LaunchSource::kFromDiscoverTabNotification:
-      *output = apps::mojom::LaunchSource::kFromDiscoverTabNotification;
+      *output = apps::LaunchSource::kFromDiscoverTabNotification;
       return true;
     case crosapi::mojom::LaunchSource::kFromManagementApi:
-      *output = apps::mojom::LaunchSource::kFromManagementApi;
+      *output = apps::LaunchSource::kFromManagementApi;
       return true;
     case crosapi::mojom::LaunchSource::kFromKiosk:
-      *output = apps::mojom::LaunchSource::kFromKiosk;
+      *output = apps::LaunchSource::kFromKiosk;
       return true;
     case crosapi::mojom::LaunchSource::kFromNewTabPage:
-      *output = apps::mojom::LaunchSource::kFromNewTabPage;
+      *output = apps::LaunchSource::kFromNewTabPage;
       return true;
     case crosapi::mojom::LaunchSource::kFromIntentUrl:
-      *output = apps::mojom::LaunchSource::kFromIntentUrl;
+      *output = apps::LaunchSource::kFromIntentUrl;
       return true;
     case crosapi::mojom::LaunchSource::kFromOsLogin:
-      *output = apps::mojom::LaunchSource::kFromOsLogin;
+      *output = apps::LaunchSource::kFromOsLogin;
       return true;
     case crosapi::mojom::LaunchSource::kFromProtocolHandler:
-      *output = apps::mojom::LaunchSource::kFromProtocolHandler;
+      *output = apps::LaunchSource::kFromProtocolHandler;
       return true;
     case crosapi::mojom::LaunchSource::kFromUrlHandler:
-      *output = apps::mojom::LaunchSource::kFromUrlHandler;
+      *output = apps::LaunchSource::kFromUrlHandler;
       return true;
   }
 
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.h b/chromeos/crosapi/mojom/app_service_types_mojom_traits.h
index 41d9ad9..97434b8 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.h
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "chromeos/crosapi/mojom/app_service_types.mojom.h"
+#include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
@@ -288,10 +289,10 @@
 };
 
 template <>
-struct EnumTraits<crosapi::mojom::LaunchSource, apps::mojom::LaunchSource> {
-  static crosapi::mojom::LaunchSource ToMojom(apps::mojom::LaunchSource input);
+struct EnumTraits<crosapi::mojom::LaunchSource, apps::LaunchSource> {
+  static crosapi::mojom::LaunchSource ToMojom(apps::LaunchSource input);
   static bool FromMojom(crosapi::mojom::LaunchSource input,
-                        apps::mojom::LaunchSource* output);
+                        apps::LaunchSource* output);
 };
 
 template <>
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
index a7caea9..0ce8828 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/test/task_environment.h"
 #include "chromeos/crosapi/mojom/app_service_types.mojom.h"
 #include "chromeos/crosapi/mojom/app_service_types_mojom_traits.h"
+#include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
@@ -841,186 +842,186 @@
 
 // Test that serialization and deserialization works with launch source.
 TEST(AppServiceTypesMojomTraitsTest, RoundTripLaunchSource) {
-  apps::mojom::LaunchSource input;
+  apps::LaunchSource input;
   {
-    input = apps::mojom::LaunchSource::kUnknown;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kUnknown;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromAppListGrid;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromAppListGrid;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromAppListGridContextMenu;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromAppListGridContextMenu;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromAppListQuery;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromAppListQuery;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromAppListQueryContextMenu;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromAppListQueryContextMenu;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromAppListRecommendation;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromAppListRecommendation;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromParentalControls;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromParentalControls;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromShelf;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromShelf;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromFileManager;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromFileManager;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromLink;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromLink;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromOmnibox;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromOmnibox;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromChromeInternal;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromChromeInternal;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromKeyboard;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromKeyboard;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromOtherApp;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromOtherApp;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromMenu;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromMenu;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromInstalledNotification;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromInstalledNotification;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromTest;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromTest;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromArc;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromArc;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromSharesheet;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromSharesheet;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromReleaseNotesNotification;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromReleaseNotesNotification;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromFullRestore;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromFullRestore;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromSmartTextContextMenu;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromSmartTextContextMenu;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
     EXPECT_EQ(output, input);
   }
   {
-    input = apps::mojom::LaunchSource::kFromDiscoverTabNotification;
-    apps::mojom::LaunchSource output;
+    input = apps::LaunchSource::kFromDiscoverTabNotification;
+    apps::LaunchSource output;
     ASSERT_TRUE(
         mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
             input, output));
diff --git a/chromeos/dbus/attestation/BUILD.gn b/chromeos/dbus/attestation/BUILD.gn
deleted file mode 100644
index e8ff0d7..0000000
--- a/chromeos/dbus/attestation/BUILD.gn
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2020 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/protobuf/proto_library.gni")
-
-assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
-
-component("attestation") {
-  output_name = "chromeos_dbus_attestation"
-  defines = [ "IS_CHROMEOS_DBUS_ATTESTATION_IMPL" ]
-
-  deps = [
-    ":attestation_proto",
-    "//base",
-    "//chromeos/dbus/constants:constants",
-    "//dbus",
-  ]
-
-  sources = [
-    "attestation_client.cc",
-    "attestation_client.h",
-    "fake_attestation_client.cc",
-    "fake_attestation_client.h",
-  ]
-}
-
-proto_library("attestation_proto") {
-  sources = [
-    "//third_party/cros_system_api/dbus/attestation/attestation_ca.proto",
-    "//third_party/cros_system_api/dbus/attestation/interface.proto",
-    "//third_party/cros_system_api/dbus/attestation/keystore.proto",
-  ]
-
-  proto_out_dir = "chromeos/dbus/attestation"
-}
diff --git a/chromeos/dbus/attestation/attestation_client.cc b/chromeos/dbus/attestation/attestation_client.cc
deleted file mode 100644
index f2639c6..0000000
--- a/chromeos/dbus/attestation/attestation_client.cc
+++ /dev/null
@@ -1,350 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/dbus/attestation/attestation_client.h"
-
-#include <utility>
-
-#include <google/protobuf/message_lite.h>
-
-#include "base/bind.h"
-#include "base/check_op.h"
-#include "base/command_line.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
-#include "chromeos/dbus/constants/dbus_switches.h"
-#include "dbus/bus.h"
-#include "dbus/message.h"
-#include "dbus/object_path.h"
-#include "dbus/object_proxy.h"
-#include "third_party/cros_system_api/dbus/attestation/dbus-constants.h"
-
-namespace chromeos {
-namespace {
-
-// Values for the attestation server switch.
-const char kAttestationServerDefault[] = "default";
-const char kAttestationServerTest[] = "test";
-
-// An arbitrary timeout for getting a certificate.
-constexpr base::TimeDelta kGetCertificateTimeout = base::Seconds(80);
-
-AttestationClient* g_instance = nullptr;
-
-// Tries to parse a proto message from |response| into |proto|.
-// Returns false if |response| is nullptr or the message cannot be parsed.
-bool ParseProto(dbus::Response* response,
-                google::protobuf::MessageLite* proto) {
-  if (!response) {
-    LOG(ERROR) << "Failed to call attestationd";
-    return false;
-  }
-
-  dbus::MessageReader reader(response);
-  if (!reader.PopArrayOfBytesAsProto(proto)) {
-    LOG(ERROR) << "Failed to parse response message from attestationd";
-    return false;
-  }
-
-  return true;
-}
-
-// "Real" implementation of AttestationClient talking to the Attestation daemon
-// on the Chrome OS side.
-class AttestationClientImpl : public AttestationClient {
- public:
-  AttestationClientImpl() = default;
-  ~AttestationClientImpl() override = default;
-
-  // Not copyable or movable.
-  AttestationClientImpl(const AttestationClientImpl&) = delete;
-  AttestationClientImpl& operator=(const AttestationClientImpl&) = delete;
-  AttestationClientImpl(AttestationClientImpl&&) = delete;
-  AttestationClientImpl& operator=(AttestationClientImpl&&) = delete;
-
-  // AttestationClient overrides:
-  void GetKeyInfo(const ::attestation::GetKeyInfoRequest& request,
-                  GetKeyInfoCallback callback) override {
-    CallProtoMethod(attestation::kGetKeyInfo, request, std::move(callback));
-  }
-
-  void GetEndorsementInfo(
-      const ::attestation::GetEndorsementInfoRequest& request,
-      GetEndorsementInfoCallback callback) override {
-    CallProtoMethod(attestation::kGetEndorsementInfo, request,
-                    std::move(callback));
-  }
-
-  void GetAttestationKeyInfo(
-      const ::attestation::GetAttestationKeyInfoRequest& request,
-      GetAttestationKeyInfoCallback callback) override {
-    CallProtoMethod(attestation::kGetAttestationKeyInfo, request,
-                    std::move(callback));
-  }
-
-  void ActivateAttestationKey(
-      const ::attestation::ActivateAttestationKeyRequest& request,
-      ActivateAttestationKeyCallback callback) override {
-    CallProtoMethod(attestation::kActivateAttestationKey, request,
-                    std::move(callback));
-  }
-
-  void CreateCertifiableKey(
-      const ::attestation::CreateCertifiableKeyRequest& request,
-      CreateCertifiableKeyCallback callback) override {
-    CallProtoMethod(attestation::kCreateCertifiableKey, request,
-                    std::move(callback));
-  }
-
-  void Decrypt(const ::attestation::DecryptRequest& request,
-               DecryptCallback callback) override {
-    CallProtoMethod(attestation::kDecrypt, request, std::move(callback));
-  }
-
-  void Sign(const ::attestation::SignRequest& request,
-            SignCallback callback) override {
-    CallProtoMethod(attestation::kSign, request, std::move(callback));
-  }
-
-  void RegisterKeyWithChapsToken(
-      const ::attestation::RegisterKeyWithChapsTokenRequest& request,
-      RegisterKeyWithChapsTokenCallback callback) override {
-    CallProtoMethod(attestation::kRegisterKeyWithChapsToken, request,
-                    std::move(callback));
-  }
-
-  void GetEnrollmentPreparations(
-      const ::attestation::GetEnrollmentPreparationsRequest& request,
-      GetEnrollmentPreparationsCallback callback) override {
-    CallProtoMethod(attestation::kGetEnrollmentPreparations, request,
-                    std::move(callback));
-  }
-
-  void GetStatus(const ::attestation::GetStatusRequest& request,
-                 GetStatusCallback callback) override {
-    CallProtoMethod(attestation::kGetStatus, request, std::move(callback));
-  }
-
-  void Verify(const ::attestation::VerifyRequest& request,
-              VerifyCallback callback) override {
-    CallProtoMethod(attestation::kVerify, request, std::move(callback));
-  }
-
-  void CreateEnrollRequest(
-      const ::attestation::CreateEnrollRequestRequest& request,
-      CreateEnrollRequestCallback callback) override {
-    CallProtoMethod(attestation::kCreateEnrollRequest, request,
-                    std::move(callback));
-  }
-
-  void FinishEnroll(const ::attestation::FinishEnrollRequest& request,
-                    FinishEnrollCallback callback) override {
-    CallProtoMethod(attestation::kFinishEnroll, request, std::move(callback));
-  }
-
-  void CreateCertificateRequest(
-      const ::attestation::CreateCertificateRequestRequest& request,
-      CreateCertificateRequestCallback callback) override {
-    CallProtoMethod(attestation::kCreateCertificateRequest, request,
-                    std::move(callback));
-  }
-
-  void FinishCertificateRequest(
-      const ::attestation::FinishCertificateRequestRequest& request,
-      FinishCertificateRequestCallback callback) override {
-    CallProtoMethod(attestation::kFinishCertificateRequest, request,
-                    std::move(callback));
-  }
-
-  void Enroll(const ::attestation::EnrollRequest& request,
-              EnrollCallback callback) override {
-    CallProtoMethod(attestation::kEnroll, request, std::move(callback));
-  }
-
-  void GetCertificate(const ::attestation::GetCertificateRequest& request,
-                      GetCertificateCallback callback) override {
-    CallProtoMethodWithTimeout(attestation::kGetCertificate,
-                               kGetCertificateTimeout.InMilliseconds(), request,
-                               std::move(callback));
-  }
-
-  void SignEnterpriseChallenge(
-      const ::attestation::SignEnterpriseChallengeRequest& request,
-      SignEnterpriseChallengeCallback callback) override {
-    CallProtoMethod(attestation::kSignEnterpriseChallenge, request,
-                    std::move(callback));
-  }
-
-  void SignSimpleChallenge(
-      const ::attestation::SignSimpleChallengeRequest& request,
-      SignSimpleChallengeCallback callback) override {
-    CallProtoMethod(attestation::kSignSimpleChallenge, request,
-                    std::move(callback));
-  }
-
-  void SetKeyPayload(const ::attestation::SetKeyPayloadRequest& request,
-                     SetKeyPayloadCallback callback) override {
-    CallProtoMethod(attestation::kSetKeyPayload, request, std::move(callback));
-  }
-
-  void DeleteKeys(const ::attestation::DeleteKeysRequest& request,
-                  DeleteKeysCallback callback) override {
-    CallProtoMethod(attestation::kDeleteKeys, request, std::move(callback));
-  }
-
-  void ResetIdentity(const ::attestation::ResetIdentityRequest& request,
-                     ResetIdentityCallback callback) override {
-    CallProtoMethod(attestation::kResetIdentity, request, std::move(callback));
-  }
-
-  void GetEnrollmentId(const ::attestation::GetEnrollmentIdRequest& request,
-                       GetEnrollmentIdCallback callback) override {
-    CallProtoMethod(attestation::kGetEnrollmentId, request,
-                    std::move(callback));
-  }
-
-  void GetCertifiedNvIndex(
-      const ::attestation::GetCertifiedNvIndexRequest& request,
-      GetCertifiedNvIndexCallback callback) override {
-    CallProtoMethod(attestation::kGetCertifiedNvIndex, request,
-                    std::move(callback));
-  }
-
-  void Init(dbus::Bus* bus) {
-    proxy_ = bus->GetObjectProxy(
-        ::attestation::kAttestationServiceName,
-        dbus::ObjectPath(attestation::kAttestationServicePath));
-  }
-
- private:
-  TestInterface* GetTestInterface() override { return nullptr; }
-
-  // Calls attestationd's |method_name| method, passing in |request| as input
-  // with |timeout_ms|. Once the (asynchronous) call finishes, |callback| is
-  // called with the response proto.
-  template <typename RequestType, typename ReplyType>
-  void CallProtoMethodWithTimeout(
-      const char* method_name,
-      int timeout_ms,
-      const RequestType& request,
-      base::OnceCallback<void(const ReplyType&)> callback) {
-    dbus::MethodCall method_call(attestation::kAttestationInterface,
-                                 method_name);
-    dbus::MessageWriter writer(&method_call);
-    if (!writer.AppendProtoAsArrayOfBytes(request)) {
-      ReplyType reply;
-      reply.set_status(attestation::STATUS_INVALID_PARAMETER);
-      base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(std::move(callback), reply));
-      return;
-    }
-    // Bind with the weak pointer of |this| so the response is not
-    // handled once |this| is already destroyed.
-    proxy_->CallMethod(
-        &method_call, timeout_ms,
-        base::BindOnce(&AttestationClientImpl::HandleResponse<ReplyType>,
-                       weak_factory_.GetWeakPtr(), std::move(callback)));
-  }
-
-  // Calls attestationd's |method_name| method, passing in |request| as input
-  // with the default timeout. Once the (asynchronous) call finishes, |callback|
-  // is called with the response proto.
-  template <typename RequestType, typename ReplyType>
-  void CallProtoMethod(const char* method_name,
-                       const RequestType& request,
-                       base::OnceCallback<void(const ReplyType&)> callback) {
-    CallProtoMethodWithTimeout(method_name,
-                               dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, request,
-                               std::move(callback));
-  }
-
-  // Parses the response proto message from |response| and calls |callback| with
-  // the decoded message. Calls |callback| with an |STATUS_DBUS_ERROR| message
-  // on error, including timeout.
-  template <typename ReplyType>
-  void HandleResponse(base::OnceCallback<void(const ReplyType&)> callback,
-                      dbus::Response* response) {
-    ReplyType reply_proto;
-    if (!ParseProto(response, &reply_proto))
-      reply_proto.set_status(attestation::STATUS_DBUS_ERROR);
-    std::move(callback).Run(reply_proto);
-  }
-
-  // D-Bus proxy for the Attestation daemon, not owned.
-  dbus::ObjectProxy* proxy_ = nullptr;
-
-  base::WeakPtrFactory<AttestationClientImpl> weak_factory_{this};
-};
-
-}  // namespace
-
-AttestationClient::AttestationClient() {
-  CHECK(!g_instance);
-  g_instance = this;
-}
-
-AttestationClient::~AttestationClient() {
-  CHECK_EQ(this, g_instance);
-  g_instance = nullptr;
-}
-
-// static
-void AttestationClient::Initialize(dbus::Bus* bus) {
-  CHECK(bus);
-  (new AttestationClientImpl())->Init(bus);
-}
-
-// static
-void AttestationClient::InitializeFake() {
-  new FakeAttestationClient();
-}
-
-// static
-void AttestationClient::Shutdown() {
-  CHECK(g_instance);
-  delete g_instance;
-  // The destructor resets |g_instance|.
-  DCHECK(!g_instance);
-}
-
-// static
-AttestationClient* AttestationClient::Get() {
-  return g_instance;
-}
-
-// static
-bool AttestationClient::IsAttestationPrepared(
-    const ::attestation::GetEnrollmentPreparationsReply& reply) {
-  if (reply.status() != ::attestation::STATUS_SUCCESS) {
-    return false;
-  }
-  for (const auto& preparation : reply.enrollment_preparations()) {
-    if (preparation.second) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// static
-::attestation::VAType AttestationClient::GetVerifiedAccessServerType() {
-  std::string value =
-      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          switches::kAttestationServer);
-  if (value.empty() || value == kAttestationServerDefault) {
-    return ::attestation::DEFAULT_VA;
-  }
-  if (value == kAttestationServerTest) {
-    return ::attestation::TEST_VA;
-  }
-  LOG(WARNING) << "Invalid Verified Access server value: " << value
-               << ". Using default.";
-  return attestation::DEFAULT_VA;
-}
-
-}  // namespace chromeos
diff --git a/chromeos/dbus/attestation/attestation_client.h b/chromeos/dbus/attestation/attestation_client.h
deleted file mode 100644
index 212e6596..0000000
--- a/chromeos/dbus/attestation/attestation_client.h
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
-#define CHROMEOS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
-
-#include <deque>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/component_export.h"
-#include "base/time/time.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
-
-namespace dbus {
-class Bus;
-}
-
-namespace chromeos {
-
-// AttestationClient is used to communicate with the org.chromium.Attestation
-// service. All method should be called from the origin thread (UI thread) which
-// initializes the DBusThreadManager instance.
-class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) AttestationClient {
- public:
-  using GetKeyInfoCallback =
-      base::OnceCallback<void(const ::attestation::GetKeyInfoReply&)>;
-  using GetEndorsementInfoCallback =
-      base::OnceCallback<void(const ::attestation::GetEndorsementInfoReply&)>;
-  using GetAttestationKeyInfoCallback = base::OnceCallback<void(
-      const ::attestation::GetAttestationKeyInfoReply&)>;
-  using ActivateAttestationKeyCallback = base::OnceCallback<void(
-      const ::attestation::ActivateAttestationKeyReply&)>;
-  using CreateCertifiableKeyCallback =
-      base::OnceCallback<void(const ::attestation::CreateCertifiableKeyReply&)>;
-  using DecryptCallback =
-      base::OnceCallback<void(const ::attestation::DecryptReply&)>;
-  using SignCallback =
-      base::OnceCallback<void(const ::attestation::SignReply&)>;
-  using RegisterKeyWithChapsTokenCallback = base::OnceCallback<void(
-      const ::attestation::RegisterKeyWithChapsTokenReply&)>;
-  using GetEnrollmentPreparationsCallback = base::OnceCallback<void(
-      const ::attestation::GetEnrollmentPreparationsReply&)>;
-  using GetStatusCallback =
-      base::OnceCallback<void(const ::attestation::GetStatusReply&)>;
-  using VerifyCallback =
-      base::OnceCallback<void(const ::attestation::VerifyReply&)>;
-  using CreateEnrollRequestCallback =
-      base::OnceCallback<void(const ::attestation::CreateEnrollRequestReply&)>;
-  using FinishEnrollCallback =
-      base::OnceCallback<void(const ::attestation::FinishEnrollReply&)>;
-  using CreateCertificateRequestCallback = base::OnceCallback<void(
-      const ::attestation::CreateCertificateRequestReply&)>;
-  using FinishCertificateRequestCallback = base::OnceCallback<void(
-      const ::attestation::FinishCertificateRequestReply&)>;
-  using EnrollCallback =
-      base::OnceCallback<void(const ::attestation::EnrollReply&)>;
-  using GetCertificateCallback =
-      base::OnceCallback<void(const ::attestation::GetCertificateReply&)>;
-  using SignEnterpriseChallengeCallback = base::OnceCallback<void(
-      const ::attestation::SignEnterpriseChallengeReply&)>;
-  using SignSimpleChallengeCallback =
-      base::OnceCallback<void(const ::attestation::SignSimpleChallengeReply&)>;
-  using SetKeyPayloadCallback =
-      base::OnceCallback<void(const ::attestation::SetKeyPayloadReply&)>;
-  using DeleteKeysCallback =
-      base::OnceCallback<void(const ::attestation::DeleteKeysReply&)>;
-  using ResetIdentityCallback =
-      base::OnceCallback<void(const ::attestation::ResetIdentityReply&)>;
-  using GetEnrollmentIdCallback =
-      base::OnceCallback<void(const ::attestation::GetEnrollmentIdReply&)>;
-  using GetCertifiedNvIndexCallback =
-      base::OnceCallback<void(const ::attestation::GetCertifiedNvIndexReply&)>;
-
-  // Interface with testing functionality. Accessed through GetTestInterface(),
-  // only implemented in the fake implementation.
-  class TestInterface {
-   public:
-    // Sets the preparation status to |is_prepared|. If no injected sequence by
-    // |ConfigureEnrollmentPreparationsSequence| the enrollment preparations
-    // always returns |is_prepared|.
-    virtual void ConfigureEnrollmentPreparations(bool is_prepared) = 0;
-    // Injects |sequence| of enrollment preparations. Once injected, the
-    // returned enrollment preparations status will be the element popped from
-    // the |sequence| one-by-one until all the elements are consumed.
-    virtual void ConfigureEnrollmentPreparationsSequence(
-        std::deque<bool> sequence) = 0;
-    // Injects a bad status to `GetEnrollmentPreparations()` calls. By design,
-    // this only accepts bad status so |STATUS_SUCCESS| is seen as an illegal
-    // input and abort the program. To recover the fake behavior to successful
-    // calls, call ConfigureEnrollmentPreparations(Sequence)?.
-    virtual void ConfigureEnrollmentPreparationsStatus(
-        ::attestation::AttestationStatus status) = 0;
-
-    // Gets the mutable |GetStatusReply| that is returned when queried.
-    virtual ::attestation::GetStatusReply* mutable_status_reply() = 0;
-
-    // Allowlists |request| so the certificate requests that comes in afterwards
-    // will get a fake certificate. If any alias of |request| has been
-    // allowlisted this functions performs no-ops.
-    virtual void AllowlistCertificateRequest(
-        const ::attestation::GetCertificateRequest& request) = 0;
-
-    // Gets the history of `DeleteKeys()` requests.
-    virtual const std::vector<::attestation::DeleteKeysRequest>&
-    delete_keys_history() const = 0;
-
-    // Clears the request history of `DeleteKeys()`.
-    virtual void ClearDeleteKeysHistory() = 0;
-
-    // Sets returned enrollment ids, when ignoring/not ignoring cache,
-    // respectively.
-    virtual void set_enrollment_id_ignore_cache(const std::string& id) = 0;
-    virtual void set_cached_enrollment_id(const std::string& id) = 0;
-    // Sets the returned status of `GetEnrollmentId()` to be D-Bus error for
-    // `count` times to emulate D-Bus late availability.
-    virtual void set_enrollment_id_dbus_error_count(int count) = 0;
-
-    // Gets the reply to the key info query as a fake database.
-    virtual ::attestation::GetKeyInfoReply* GetMutableKeyInfoReply(
-        const std::string& username,
-        const std::string& label) = 0;
-    // Sets the returned status of `GetKeyInfo()` to be D-Bus error for
-    // `count` times to emulate D-Bus late availability.
-    virtual void set_key_info_dbus_error_count(int count) = 0;
-    // Gets the remaining count of `GetKeyInfo()` replying D-Bus error.
-    virtual int key_info_dbus_error_count() const = 0;
-
-    // Verifies if `signed_data` is signed against `challenge`.
-    virtual bool VerifySimpleChallengeResponse(
-        const std::string& challenge,
-        const ::attestation::SignedData& signed_data) = 0;
-
-    // Sets the status code returned by `SignSimpleChallenge()`.
-    virtual void set_sign_simple_challenge_status(
-        ::attestation::AttestationStatus status) = 0;
-    // Allowlists the key used to sign simple challenge.
-    virtual void AllowlistSignSimpleChallengeKey(const std::string& username,
-                                                 const std::string& label) = 0;
-
-    // Sets the status code returned by `Sign()`.
-    virtual void set_sign_status(::attestation::AttestationStatus status) = 0;
-
-    // Sets the status code returned by `RegisterKeyWithChapsToken()`.
-    virtual void set_register_key_status(
-        ::attestation::AttestationStatus status) = 0;
-    // Allowlists the key allowed to be registered to the key store.
-    virtual void AllowlistRegisterKey(const std::string& username,
-                                      const std::string& label) = 0;
-
-    // Sets the status code returned by `SignEnterpriseChallenge()`.
-    virtual void set_sign_enterprise_challenge_status(
-        ::attestation::AttestationStatus status) = 0;
-    // Allowlists the key used to sign enterprise challenge. Note that
-    // `include_signed_public_key` and `challenge` are ignored for key
-    // comparison because they are are part of the key but the inputs for
-    // signature generation.
-    virtual void AllowlistSignEnterpriseChallengeKey(
-        const ::attestation::SignEnterpriseChallengeRequest& request) = 0;
-    // Signs the enterprise `challenge` with this class the same way the
-    // enterprise challenge is signed.
-    virtual std::string GetEnterpriseChallengeFakeSignature(
-        const std::string& challenge,
-        bool include_spkac) const = 0;
-    // Sets the delay to the time we reply to `SignEnterpriseChallenge()`.
-    virtual void set_sign_enterprise_challenge_delay(
-        const base::TimeDelta& delay) = 0;
-
-    // Sets the allowed ACA type for the legacy attestation flow. The enroll
-    // request can be created/finished only if the ACA type matches the set ACA
-    // type. By default, it is default ACA.
-    virtual void set_aca_type_for_legacy_flow(
-        ::attestation::ACAType aca_type) = 0;
-
-    // Sets the status code returned by `CreateEnrollRequestRequest()`.
-    virtual void set_enroll_request_status(
-        ::attestation::AttestationStatus status) = 0;
-    // Gets the fake enroll request when the status is configured to be good.
-    virtual std::string GetFakePcaEnrollRequest() const = 0;
-    // Gets the fake enroll response that is accepted by `FinishEnroll()`.
-    virtual std::string GetFakePcaEnrollResponse() const = 0;
-
-    // Allowlists the request that has `username`, `request_origin`, `profile`,
-    // and `key_type`, so the certificate requests that comes in afterwards will
-    // be successfully created.
-    virtual void AllowlistLegacyCreateCertificateRequest(
-        const std::string& username,
-        const std::string& request_origin,
-        ::attestation::CertificateProfile profile,
-        ::attestation::KeyType key_type) = 0;
-    // Sets the status code returned by `CreateCertificateRequest()`.
-    virtual void set_cert_request_status(
-        ::attestation::AttestationStatus status) = 0;
-    // Gets the fake certificate request when the status is configured to be
-    // good.
-    virtual std::string GetFakePcaCertRequest() const = 0;
-    // Gets the fake enroll response that is accepted by
-    // `FinishCertificateRequest()`.
-    virtual std::string GetFakePcaCertResponse() const = 0;
-    // Gets the fake certificate that is returned by
-    // successful `FinishCertificateRequest()`.
-    virtual std::string GetFakeCertificate() const = 0;
-  };
-
-  // Not copyable or movable.
-  AttestationClient(const AttestationClient&) = delete;
-  AttestationClient& operator=(const AttestationClient&) = delete;
-  AttestationClient(AttestationClient&&) = delete;
-  AttestationClient& operator=(AttestationClient&&) = delete;
-
-  // Creates and initializes the global instance. |bus| must not be null.
-  static void Initialize(dbus::Bus* bus);
-
-  // Creates and initializes a fake global instance if not already created.
-  static void InitializeFake();
-
-  // Destroys the global instance.
-  static void Shutdown();
-
-  // Returns the global instance which may be null if not initialized.
-  static AttestationClient* Get();
-
-  // Checks if |reply| indicates the attestation service is prepared with any
-  // ACA.
-  static bool IsAttestationPrepared(
-      const ::attestation::GetEnrollmentPreparationsReply& reply);
-
-  // Gets the verified access server type from command-line arguments.
-  static ::attestation::VAType GetVerifiedAccessServerType();
-
-  // Attestation daemon D-Bus method calls. See org.chromium.Attestation.xml and
-  // the corresponding protobuf definitions in Chromium OS code for the
-  // documentation of the methods and request/ messages.
-
-  virtual void GetKeyInfo(const ::attestation::GetKeyInfoRequest& request,
-                          GetKeyInfoCallback callback) = 0;
-
-  virtual void GetEndorsementInfo(
-      const ::attestation::GetEndorsementInfoRequest& request,
-      GetEndorsementInfoCallback callback) = 0;
-
-  virtual void GetAttestationKeyInfo(
-      const ::attestation::GetAttestationKeyInfoRequest& request,
-      GetAttestationKeyInfoCallback callback) = 0;
-
-  virtual void ActivateAttestationKey(
-      const ::attestation::ActivateAttestationKeyRequest& request,
-      ActivateAttestationKeyCallback callback) = 0;
-
-  virtual void CreateCertifiableKey(
-      const ::attestation::CreateCertifiableKeyRequest& request,
-      CreateCertifiableKeyCallback callback) = 0;
-
-  virtual void Decrypt(const ::attestation::DecryptRequest& request,
-                       DecryptCallback callback) = 0;
-
-  virtual void Sign(const ::attestation::SignRequest& request,
-                    SignCallback callback) = 0;
-
-  virtual void RegisterKeyWithChapsToken(
-      const ::attestation::RegisterKeyWithChapsTokenRequest& request,
-      RegisterKeyWithChapsTokenCallback callback) = 0;
-
-  virtual void GetEnrollmentPreparations(
-      const ::attestation::GetEnrollmentPreparationsRequest& request,
-      GetEnrollmentPreparationsCallback callback) = 0;
-
-  virtual void GetStatus(const ::attestation::GetStatusRequest& request,
-                         GetStatusCallback callback) = 0;
-
-  virtual void Verify(const ::attestation::VerifyRequest& request,
-                      VerifyCallback callback) = 0;
-
-  virtual void CreateEnrollRequest(
-      const ::attestation::CreateEnrollRequestRequest& request,
-      CreateEnrollRequestCallback callback) = 0;
-
-  virtual void FinishEnroll(const ::attestation::FinishEnrollRequest& request,
-                            FinishEnrollCallback callback) = 0;
-
-  virtual void CreateCertificateRequest(
-      const ::attestation::CreateCertificateRequestRequest& request,
-      CreateCertificateRequestCallback callback) = 0;
-
-  virtual void FinishCertificateRequest(
-      const ::attestation::FinishCertificateRequestRequest& request,
-      FinishCertificateRequestCallback callback) = 0;
-
-  virtual void Enroll(const ::attestation::EnrollRequest& request,
-                      EnrollCallback callback) = 0;
-
-  virtual void GetCertificate(
-      const ::attestation::GetCertificateRequest& request,
-      GetCertificateCallback callback) = 0;
-
-  virtual void SignEnterpriseChallenge(
-      const ::attestation::SignEnterpriseChallengeRequest& request,
-      SignEnterpriseChallengeCallback callback) = 0;
-
-  virtual void SignSimpleChallenge(
-      const ::attestation::SignSimpleChallengeRequest& request,
-      SignSimpleChallengeCallback callback) = 0;
-
-  virtual void SetKeyPayload(const ::attestation::SetKeyPayloadRequest& request,
-                             SetKeyPayloadCallback callback) = 0;
-
-  virtual void DeleteKeys(const ::attestation::DeleteKeysRequest& request,
-                          DeleteKeysCallback callback) = 0;
-
-  virtual void ResetIdentity(const ::attestation::ResetIdentityRequest& request,
-                             ResetIdentityCallback callback) = 0;
-
-  virtual void GetEnrollmentId(
-      const ::attestation::GetEnrollmentIdRequest& request,
-      GetEnrollmentIdCallback callback) = 0;
-
-  virtual void GetCertifiedNvIndex(
-      const ::attestation::GetCertifiedNvIndexRequest& request,
-      GetCertifiedNvIndexCallback callback) = 0;
-
-  // Returns an interface for testing (fake only), or returns nullptr.
-  virtual TestInterface* GetTestInterface() = 0;
-
- protected:
-  // Initialize/Shutdown should be used instead.
-  AttestationClient();
-  virtual ~AttestationClient();
-};
-
-}  // namespace chromeos
-
-// TODO(https://crbug.com/1164001): remove before finalizing ChromeOS
-// source migration.
-namespace ash {
-using ::chromeos::AttestationClient;
-}  // namespace ash
-
-#endif  // CHROMEOS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
diff --git a/chromeos/dbus/attestation/fake_attestation_client.cc b/chromeos/dbus/attestation/fake_attestation_client.cc
deleted file mode 100644
index 03578aa..0000000
--- a/chromeos/dbus/attestation/fake_attestation_client.cc
+++ /dev/null
@@ -1,566 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/dbus/attestation/fake_attestation_client.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "third_party/cros_system_api/dbus/attestation/dbus-constants.h"
-
-namespace chromeos {
-namespace {
-
-constexpr int kCertificateNotAssigned = 0;
-constexpr char kFakeCertPrefix[] = "fake cert";
-constexpr char kResponseSuffix[] = "_response";
-constexpr char kSignatureSuffix[] = "_signature";
-constexpr char kEnterpriseChallengeResponseSuffix[] = "enterprise_challenge";
-constexpr char kIncludeSpkacSuffix[] = "_with_spkac";
-constexpr char kFakePcaEnrollRequest[] = "fake enroll request";
-constexpr char kFakePcaEnrollResponse[] = "fake enroll response";
-constexpr char kFakePcaCertRequest[] = "fake cert request";
-constexpr char kFakePcaCertResponse[] = "fake cert response";
-constexpr char kFakeCertificate[] = "fake certificate";
-
-// Posts `callback` on the current thread's task runner, passing it the
-// `reply` message.
-template <class ReplyType>
-void PostProtoResponse(base::OnceCallback<void(const ReplyType&)> callback,
-                       const ReplyType& reply) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(std::move(callback), reply));
-}
-
-// Posts `callback` on the current thread's task runner, passing it the
-// `reply` message with `delay`.
-template <class ReplyType>
-void PostProtoResponseWithDelay(
-    base::OnceCallback<void(const ReplyType&)> callback,
-    const ReplyType& reply,
-    const base::TimeDelta& delay) {
-  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::BindOnce(std::move(callback), reply), delay);
-}
-
-bool GetCertificateRequestEqual(::attestation::GetCertificateRequest r1,
-                                ::attestation::GetCertificateRequest r2) {
-  // To prevent regression from future expansion to |GetCertificateRequest|, we
-  // compare their serialized results so the difference doesn't get away from
-  // this function. We can't really make use of
-  // |google::protobuf::util::MessageDifferencer|, which doesn't apply to
-  // |MessageLite|.
-
-  // |shall_trigger_enrollment| and |forced| shouldn't affect the whilelisting.
-  r1.clear_forced();
-  r2.clear_forced();
-  r1.clear_shall_trigger_enrollment();
-  r2.clear_shall_trigger_enrollment();
-  return r1.SerializeAsString() == r2.SerializeAsString();
-}
-
-}  // namespace
-
-FakeAttestationClient::FakeAttestationClient() {
-  status_reply_.set_enrolled(true);
-}
-
-FakeAttestationClient::~FakeAttestationClient() = default;
-
-void FakeAttestationClient::GetKeyInfo(
-    const ::attestation::GetKeyInfoRequest& request,
-    GetKeyInfoCallback callback) {
-  ::attestation::GetKeyInfoReply reply;
-  if (key_info_dbus_error_count_ > 0) {
-    reply.set_status(::attestation::STATUS_DBUS_ERROR);
-    key_info_dbus_error_count_--;
-  } else {
-    auto iter = key_info_database_.find(request);
-    if (iter != key_info_database_.end()) {
-      reply = iter->second;
-    } else {
-      reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
-    }
-  }
-
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::GetEndorsementInfo(
-    const ::attestation::GetEndorsementInfoRequest& request,
-    GetEndorsementInfoCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::GetAttestationKeyInfo(
-    const ::attestation::GetAttestationKeyInfoRequest& request,
-    GetAttestationKeyInfoCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::ActivateAttestationKey(
-    const ::attestation::ActivateAttestationKeyRequest& request,
-    ActivateAttestationKeyCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::CreateCertifiableKey(
-    const ::attestation::CreateCertifiableKeyRequest& request,
-    CreateCertifiableKeyCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::Decrypt(
-    const ::attestation::DecryptRequest& request,
-    DecryptCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::Sign(const ::attestation::SignRequest& request,
-                                 SignCallback callback) {
-  ::attestation::SignReply reply;
-  reply.set_status(sign_status_);
-  if (reply.status() == ::attestation::STATUS_SUCCESS) {
-    reply.set_signature(kSignatureSuffix);
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::RegisterKeyWithChapsToken(
-    const ::attestation::RegisterKeyWithChapsTokenRequest& request,
-    RegisterKeyWithChapsTokenCallback callback) {
-  ::attestation::RegisterKeyWithChapsTokenReply reply;
-  if (allowlisted_register_keys_.count(
-          {request.username(), request.key_label()}) == 0) {
-    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
-  } else {
-    reply.set_status(register_key_status_);
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::GetEnrollmentPreparations(
-    const ::attestation::GetEnrollmentPreparationsRequest& request,
-    GetEnrollmentPreparationsCallback callback) {
-  ::attestation::GetEnrollmentPreparationsReply reply;
-  reply.set_status(preparations_status_);
-
-  if (reply.status() == ::attestation::STATUS_SUCCESS) {
-    bool is_prepared = is_prepared_;
-    // Override the state if there is a customized sequence.
-    if (!preparation_sequences_.empty()) {
-      is_prepared = preparation_sequences_.front();
-      preparation_sequences_.pop_front();
-    }
-    if (is_prepared) {
-      std::vector<::attestation::ACAType> prepared_types;
-      // As we do in the attestation service, if the ACA type is not specified,
-      // returns the statuses with all the possible ACA types.
-      if (request.has_aca_type()) {
-        prepared_types = {request.aca_type()};
-      } else {
-        prepared_types = {::attestation::DEFAULT_ACA, ::attestation::TEST_ACA};
-      }
-      for (const auto& type : prepared_types) {
-        (*reply.mutable_enrollment_preparations())[type] = true;
-      }
-    }
-  }
-
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::GetStatus(
-    const ::attestation::GetStatusRequest& request,
-    GetStatusCallback callback) {
-  PostProtoResponse(std::move(callback), status_reply_);
-}
-
-void FakeAttestationClient::Verify(const ::attestation::VerifyRequest& request,
-                                   VerifyCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::CreateEnrollRequest(
-    const ::attestation::CreateEnrollRequestRequest& request,
-    CreateEnrollRequestCallback callback) {
-  ::attestation::CreateEnrollRequestReply reply;
-  reply.set_status(enroll_request_status_);
-  if (aca_type_for_legacy_mode_ != request.aca_type()) {
-    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
-  }
-  if (reply.status() == ::attestation::STATUS_SUCCESS) {
-    reply.set_pca_request(GetFakePcaEnrollRequest());
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::FinishEnroll(
-    const ::attestation::FinishEnrollRequest& request,
-    FinishEnrollCallback callback) {
-  ::attestation::FinishEnrollReply reply;
-  reply.set_status(request.pca_response() == GetFakePcaEnrollResponse()
-                       ? ::attestation::STATUS_SUCCESS
-                       : ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
-  if (aca_type_for_legacy_mode_ != request.aca_type()) {
-    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::CreateCertificateRequest(
-    const ::attestation::CreateCertificateRequestRequest& request,
-    CreateCertificateRequestCallback callback) {
-  ::attestation::CreateCertificateRequestReply reply;
-  reply.set_status(cert_request_status_);
-  if (aca_type_for_legacy_mode_ != request.aca_type()) {
-    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
-  }
-  if (reply.status() != ::attestation::STATUS_SUCCESS) {
-    PostProtoResponse(std::move(callback), reply);
-    return;
-  }
-  for (const auto& req : allowlisted_create_requests_) {
-    if (req.username() == request.username() &&
-        req.request_origin() == request.request_origin() &&
-        req.certificate_profile() == request.certificate_profile() &&
-        req.key_type() == request.key_type()) {
-      reply.set_pca_request(GetFakePcaCertRequest());
-      PostProtoResponse(std::move(callback), reply);
-      return;
-    }
-  }
-  reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::FinishCertificateRequest(
-    const ::attestation::FinishCertificateRequestRequest& request,
-    FinishCertificateRequestCallback callback) {
-  ::attestation::FinishCertificateRequestReply reply;
-  if (request.pca_response() != GetFakePcaCertResponse()) {
-    reply.set_status(::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
-  }
-  if (reply.status() == ::attestation::STATUS_SUCCESS) {
-    reply.set_certificate(GetFakeCertificate());
-    // Also, insert the certificate into the fake database.
-    GetMutableKeyInfoReply(request.username(), request.key_label())
-        ->set_certificate(GetFakeCertificate());
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::Enroll(const ::attestation::EnrollRequest& request,
-                                   EnrollCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::GetCertificate(
-    const ::attestation::GetCertificateRequest& request,
-    GetCertificateCallback callback) {
-  ::attestation::GetCertificateReply reply;
-  reply.set_status(
-      ::attestation::AttestationStatus::STATUS_UNEXPECTED_DEVICE_ERROR);
-
-  if (request.shall_trigger_enrollment()) {
-    status_reply_.set_enrolled(true);
-  }
-  if (!status_reply_.enrolled()) {
-    PostProtoResponse(std::move(callback), reply);
-    return;
-  }
-
-  for (size_t i = 0; i < allowlisted_requests_.size(); ++i) {
-    if (GetCertificateRequestEqual(allowlisted_requests_[i], request)) {
-      if (request.forced() ||
-          certificate_indices_[i] == kCertificateNotAssigned) {
-        ++certificate_count_;
-        certificate_indices_[i] = certificate_count_;
-      }
-      reply.set_status(::attestation::AttestationStatus::STATUS_SUCCESS);
-      reply.set_certificate(kFakeCertPrefix +
-                            base::NumberToString(certificate_indices_[i]));
-      break;
-    }
-  }
-
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::SignEnterpriseChallenge(
-    const ::attestation::SignEnterpriseChallengeRequest& request,
-    SignEnterpriseChallengeCallback callback) {
-  ::attestation::SignEnterpriseChallengeReply reply;
-  if (allowlisted_sign_enterprise_challenge_keys_.count(request) == 0) {
-    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
-  } else {
-    reply.set_status(sign_enterprise_challenge_status_);
-  }
-  if (reply.status() == ::attestation::STATUS_SUCCESS) {
-    reply.set_challenge_response(GetEnterpriseChallengeFakeSignature(
-        request.challenge(), request.include_signed_public_key()));
-  }
-  PostProtoResponseWithDelay(std::move(callback), reply,
-                             sign_enterprise_challenge_delay_);
-}
-
-void FakeAttestationClient::SignSimpleChallenge(
-    const ::attestation::SignSimpleChallengeRequest& request,
-    SignSimpleChallengeCallback callback) {
-  ::attestation::SignSimpleChallengeReply reply;
-  if (allowlisted_sign_simple_challenge_keys_.count(
-          {request.username(), request.key_label()}) == 0) {
-    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
-  } else {
-    reply.set_status(sign_simple_challenge_status_);
-  }
-  if (reply.status() == ::attestation::STATUS_SUCCESS) {
-    ::attestation::SignedData signed_data;
-    signed_data.set_data(request.challenge() + kResponseSuffix);
-    signed_data.set_signature(request.challenge() + kSignatureSuffix);
-    reply.set_challenge_response(signed_data.SerializeAsString());
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::SetKeyPayload(
-    const ::attestation::SetKeyPayloadRequest& request,
-    SetKeyPayloadCallback callback) {
-  ::attestation::GetKeyInfoRequest get_key_info_request;
-  get_key_info_request.set_username(request.username());
-  get_key_info_request.set_key_label(request.key_label());
-  auto iter = key_info_database_.find(get_key_info_request);
-  ::attestation::SetKeyPayloadReply reply;
-  if (iter == key_info_database_.end()) {
-    reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
-  } else {
-    iter->second.set_payload(request.payload());
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::DeleteKeys(
-    const ::attestation::DeleteKeysRequest& request,
-    DeleteKeysCallback callback) {
-  delete_keys_history_.push_back(request);
-  ::attestation::DeleteKeysReply reply;
-  reply.set_status(::attestation::STATUS_SUCCESS);
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::ResetIdentity(
-    const ::attestation::ResetIdentityRequest& request,
-    ResetIdentityCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::GetEnrollmentId(
-    const ::attestation::GetEnrollmentIdRequest& request,
-    GetEnrollmentIdCallback callback) {
-  ::attestation::GetEnrollmentIdReply reply;
-  if (enrollment_id_dbus_error_count_ != 0) {
-    reply.set_status(::attestation::STATUS_DBUS_ERROR);
-    enrollment_id_dbus_error_count_--;
-  } else {
-    reply.set_status(::attestation::STATUS_SUCCESS);
-    reply.set_enrollment_id(request.ignore_cache() ? enrollment_id_ignore_cache_
-                                                   : enrollment_id_);
-  }
-  PostProtoResponse(std::move(callback), reply);
-}
-
-void FakeAttestationClient::GetCertifiedNvIndex(
-    const ::attestation::GetCertifiedNvIndexRequest& request,
-    GetCertifiedNvIndexCallback callback) {
-  NOTIMPLEMENTED();
-}
-
-void FakeAttestationClient::ConfigureEnrollmentPreparations(bool is_prepared) {
-  preparations_status_ = ::attestation::STATUS_SUCCESS;
-  is_prepared_ = is_prepared;
-}
-
-void FakeAttestationClient::ConfigureEnrollmentPreparationsSequence(
-    std::deque<bool> sequence) {
-  preparations_status_ = ::attestation::STATUS_SUCCESS;
-  preparation_sequences_ = std::move(sequence);
-}
-
-void FakeAttestationClient::ConfigureEnrollmentPreparationsStatus(
-    ::attestation::AttestationStatus status) {
-  CHECK_NE(status, ::attestation::STATUS_SUCCESS);
-  preparations_status_ = status;
-}
-
-::attestation::GetStatusReply* FakeAttestationClient::mutable_status_reply() {
-  return &status_reply_;
-}
-
-void FakeAttestationClient::AllowlistCertificateRequest(
-    const ::attestation::GetCertificateRequest& request) {
-  for (const auto& req : allowlisted_requests_) {
-    if (GetCertificateRequestEqual(req, request)) {
-      return;
-    }
-  }
-  allowlisted_requests_.push_back(request);
-  certificate_indices_.push_back(kCertificateNotAssigned);
-}
-
-const std::vector<::attestation::DeleteKeysRequest>&
-FakeAttestationClient::delete_keys_history() const {
-  return delete_keys_history_;
-}
-
-void FakeAttestationClient::ClearDeleteKeysHistory() {
-  delete_keys_history_.clear();
-}
-
-void FakeAttestationClient::set_enrollment_id_ignore_cache(
-    const std::string& id) {
-  enrollment_id_ignore_cache_ = id;
-}
-
-void FakeAttestationClient::set_cached_enrollment_id(const std::string& id) {
-  enrollment_id_ = id;
-}
-
-void FakeAttestationClient::set_enrollment_id_dbus_error_count(int count) {
-  enrollment_id_dbus_error_count_ = count;
-}
-
-::attestation::GetKeyInfoReply* FakeAttestationClient::GetMutableKeyInfoReply(
-    const std::string& username,
-    const std::string& label) {
-  ::attestation::GetKeyInfoRequest request;
-  request.set_username(username);
-  request.set_key_label(label);
-  // If there doesn't exist the entry yet, just create a new one.
-  return &(key_info_database_[request]);
-}
-
-void FakeAttestationClient::set_key_info_dbus_error_count(int count) {
-  key_info_dbus_error_count_ = count;
-}
-
-int FakeAttestationClient::key_info_dbus_error_count() const {
-  return key_info_dbus_error_count_;
-}
-
-bool FakeAttestationClient::VerifySimpleChallengeResponse(
-    const std::string& challenge,
-    const ::attestation::SignedData& signed_data) {
-  return signed_data.data() == challenge + kResponseSuffix &&
-         signed_data.signature() == challenge + kSignatureSuffix;
-}
-
-void FakeAttestationClient::set_sign_simple_challenge_status(
-    ::attestation::AttestationStatus status) {
-  sign_simple_challenge_status_ = status;
-}
-
-void FakeAttestationClient::set_sign_status(
-    ::attestation::AttestationStatus status) {
-  sign_status_ = status;
-}
-
-void FakeAttestationClient::AllowlistSignSimpleChallengeKey(
-    const std::string& username,
-    const std::string& label) {
-  allowlisted_sign_simple_challenge_keys_.insert({username, label});
-}
-
-void FakeAttestationClient::set_register_key_status(
-    ::attestation::AttestationStatus status) {
-  register_key_status_ = status;
-}
-
-void FakeAttestationClient::AllowlistRegisterKey(const std::string& username,
-                                                 const std::string& label) {
-  allowlisted_register_keys_.insert({username, label});
-}
-
-void FakeAttestationClient::set_sign_enterprise_challenge_status(
-    ::attestation::AttestationStatus status) {
-  sign_enterprise_challenge_status_ = status;
-}
-
-void FakeAttestationClient::AllowlistSignEnterpriseChallengeKey(
-    const ::attestation::SignEnterpriseChallengeRequest& request) {
-  allowlisted_sign_enterprise_challenge_keys_.insert(request);
-}
-
-std::string FakeAttestationClient::GetEnterpriseChallengeFakeSignature(
-    const std::string& challenge,
-    bool include_spkac) const {
-  std::string challenge_response =
-      challenge + kEnterpriseChallengeResponseSuffix;
-  if (include_spkac) {
-    challenge_response += kIncludeSpkacSuffix;
-  }
-  return challenge_response;
-}
-
-void FakeAttestationClient::set_sign_enterprise_challenge_delay(
-    const base::TimeDelta& delay) {
-  sign_enterprise_challenge_delay_ = delay;
-}
-
-void FakeAttestationClient::set_aca_type_for_legacy_flow(
-    ::attestation::ACAType aca_type) {
-  aca_type_for_legacy_mode_ = aca_type;
-}
-
-void FakeAttestationClient::set_enroll_request_status(
-    ::attestation::AttestationStatus status) {
-  enroll_request_status_ = status;
-}
-
-std::string FakeAttestationClient::GetFakePcaEnrollRequest() const {
-  return kFakePcaEnrollRequest;
-}
-
-std::string FakeAttestationClient::GetFakePcaEnrollResponse() const {
-  return kFakePcaEnrollResponse;
-}
-
-void FakeAttestationClient::AllowlistLegacyCreateCertificateRequest(
-    const std::string& username,
-    const std::string& request_origin,
-    ::attestation::CertificateProfile profile,
-    ::attestation::KeyType key_type) {
-  ::attestation::CreateCertificateRequestRequest request;
-  request.set_username(username);
-  request.set_request_origin(request_origin);
-  request.set_certificate_profile(profile);
-  request.set_key_type(key_type);
-  allowlisted_create_requests_.push_back(request);
-}
-
-void FakeAttestationClient::set_cert_request_status(
-    ::attestation::AttestationStatus status) {
-  cert_request_status_ = status;
-}
-
-std::string FakeAttestationClient::GetFakePcaCertRequest() const {
-  return kFakePcaCertRequest;
-}
-
-std::string FakeAttestationClient::GetFakePcaCertResponse() const {
-  return kFakePcaCertResponse;
-}
-
-std::string FakeAttestationClient::GetFakeCertificate() const {
-  return kFakeCertificate;
-}
-
-AttestationClient::TestInterface* FakeAttestationClient::GetTestInterface() {
-  return this;
-}
-
-}  // namespace chromeos
diff --git a/chromeos/dbus/attestation/fake_attestation_client.h b/chromeos/dbus/attestation/fake_attestation_client.h
deleted file mode 100644
index 12846070..0000000
--- a/chromeos/dbus/attestation/fake_attestation_client.h
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_DBUS_ATTESTATION_FAKE_ATTESTATION_CLIENT_H_
-#define CHROMEOS_DBUS_ATTESTATION_FAKE_ATTESTATION_CLIENT_H_
-
-#include "chromeos/dbus/attestation/attestation_client.h"
-
-#include <deque>
-#include <map>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/component_export.h"
-#include "base/time/time.h"
-#include "chromeos/dbus/attestation/interface.pb.h"
-#include "dbus/object_proxy.h"
-
-namespace chromeos {
-
-class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) FakeAttestationClient
-    : public AttestationClient,
-      public AttestationClient::TestInterface {
- public:
-  FakeAttestationClient();
-  ~FakeAttestationClient() override;
-
-  // Not copyable or movable.
-  FakeAttestationClient(const FakeAttestationClient&) = delete;
-  FakeAttestationClient& operator=(const FakeAttestationClient&) = delete;
-  FakeAttestationClient(FakeAttestationClient&&) = delete;
-  FakeAttestationClient& operator=(FakeAttestationClient&&) = delete;
-
-  // AttestationClient:
-  void GetKeyInfo(const ::attestation::GetKeyInfoRequest& request,
-                  GetKeyInfoCallback callback) override;
-  void GetEndorsementInfo(
-      const ::attestation::GetEndorsementInfoRequest& request,
-      GetEndorsementInfoCallback callback) override;
-  void GetAttestationKeyInfo(
-      const ::attestation::GetAttestationKeyInfoRequest& request,
-      GetAttestationKeyInfoCallback callback) override;
-  void ActivateAttestationKey(
-      const ::attestation::ActivateAttestationKeyRequest& request,
-      ActivateAttestationKeyCallback callback) override;
-  void CreateCertifiableKey(
-      const ::attestation::CreateCertifiableKeyRequest& request,
-      CreateCertifiableKeyCallback callback) override;
-  void Decrypt(const ::attestation::DecryptRequest& request,
-               DecryptCallback callback) override;
-  void Sign(const ::attestation::SignRequest& request,
-            SignCallback callback) override;
-  void RegisterKeyWithChapsToken(
-      const ::attestation::RegisterKeyWithChapsTokenRequest& request,
-      RegisterKeyWithChapsTokenCallback callback) override;
-  void GetEnrollmentPreparations(
-      const ::attestation::GetEnrollmentPreparationsRequest& request,
-      GetEnrollmentPreparationsCallback callback) override;
-  void GetStatus(const ::attestation::GetStatusRequest& request,
-                 GetStatusCallback callback) override;
-  void Verify(const ::attestation::VerifyRequest& request,
-              VerifyCallback callback) override;
-  void CreateEnrollRequest(
-      const ::attestation::CreateEnrollRequestRequest& request,
-      CreateEnrollRequestCallback callback) override;
-  void FinishEnroll(const ::attestation::FinishEnrollRequest& request,
-                    FinishEnrollCallback callback) override;
-  void CreateCertificateRequest(
-      const ::attestation::CreateCertificateRequestRequest& request,
-      CreateCertificateRequestCallback callback) override;
-  void FinishCertificateRequest(
-      const ::attestation::FinishCertificateRequestRequest& request,
-      FinishCertificateRequestCallback callback) override;
-  void Enroll(const ::attestation::EnrollRequest& request,
-              EnrollCallback callback) override;
-  void GetCertificate(const ::attestation::GetCertificateRequest& request,
-                      GetCertificateCallback callback) override;
-  void SignEnterpriseChallenge(
-      const ::attestation::SignEnterpriseChallengeRequest& request,
-      SignEnterpriseChallengeCallback callback) override;
-  void SignSimpleChallenge(
-      const ::attestation::SignSimpleChallengeRequest& request,
-      SignSimpleChallengeCallback callback) override;
-  void SetKeyPayload(const ::attestation::SetKeyPayloadRequest& request,
-                     SetKeyPayloadCallback callback) override;
-  void DeleteKeys(const ::attestation::DeleteKeysRequest& request,
-                  DeleteKeysCallback callback) override;
-  void ResetIdentity(const ::attestation::ResetIdentityRequest& request,
-                     ResetIdentityCallback callback) override;
-  void GetEnrollmentId(const ::attestation::GetEnrollmentIdRequest& request,
-                       GetEnrollmentIdCallback callback) override;
-  void GetCertifiedNvIndex(
-      const ::attestation::GetCertifiedNvIndexRequest& request,
-      GetCertifiedNvIndexCallback callback) override;
-
-  // AttestationClient::TestInterface:
-  void ConfigureEnrollmentPreparations(bool is_prepared) override;
-  void ConfigureEnrollmentPreparationsSequence(
-      std::deque<bool> sequence) override;
-  void ConfigureEnrollmentPreparationsStatus(
-      ::attestation::AttestationStatus status) override;
-  ::attestation::GetStatusReply* mutable_status_reply() override;
-  void AllowlistCertificateRequest(
-      const ::attestation::GetCertificateRequest& request) override;
-  const std::vector<::attestation::DeleteKeysRequest>& delete_keys_history()
-      const override;
-  void ClearDeleteKeysHistory() override;
-  void set_enrollment_id_ignore_cache(const std::string& id) override;
-  void set_cached_enrollment_id(const std::string& id) override;
-  void set_enrollment_id_dbus_error_count(int count) override;
-  ::attestation::GetKeyInfoReply* GetMutableKeyInfoReply(
-      const std::string& username,
-      const std::string& label) override;
-  void set_key_info_dbus_error_count(int count) override;
-  int key_info_dbus_error_count() const override;
-  bool VerifySimpleChallengeResponse(
-      const std::string& challenge,
-      const ::attestation::SignedData& signed_data) override;
-  void set_sign_simple_challenge_status(
-      ::attestation::AttestationStatus status) override;
-  void AllowlistSignSimpleChallengeKey(const std::string& username,
-                                       const std::string& label) override;
-  void set_sign_status(::attestation::AttestationStatus status) override;
-  void set_register_key_status(
-      ::attestation::AttestationStatus status) override;
-  void AllowlistRegisterKey(const std::string& username,
-                            const std::string& label) override;
-  void set_sign_enterprise_challenge_status(
-      ::attestation::AttestationStatus status) override;
-  void AllowlistSignEnterpriseChallengeKey(
-      const ::attestation::SignEnterpriseChallengeRequest& request) override;
-  std::string GetEnterpriseChallengeFakeSignature(
-      const std::string& challenge,
-      bool include_spkac) const override;
-  void set_sign_enterprise_challenge_delay(
-      const base::TimeDelta& delay) override;
-  void set_aca_type_for_legacy_flow(::attestation::ACAType aca_type) override;
-  void set_enroll_request_status(
-      ::attestation::AttestationStatus status) override;
-  std::string GetFakePcaEnrollRequest() const override;
-  std::string GetFakePcaEnrollResponse() const override;
-  void AllowlistLegacyCreateCertificateRequest(
-      const std::string& username,
-      const std::string& request_origin,
-      ::attestation::CertificateProfile profile,
-      ::attestation::KeyType key_type) override;
-  void set_cert_request_status(
-      ::attestation::AttestationStatus status) override;
-  std::string GetFakePcaCertRequest() const override;
-  std::string GetFakePcaCertResponse() const override;
-  std::string GetFakeCertificate() const override;
-
-  AttestationClient::TestInterface* GetTestInterface() override;
-
- private:
-  ::attestation::AttestationStatus preparations_status_ =
-      ::attestation::STATUS_SUCCESS;
-  bool is_prepared_ = true;
-  std::deque<bool> preparation_sequences_;
-
-  ::attestation::GetStatusReply status_reply_;
-
-  // Maintains the allowlisted certificate requests.
-  std::vector<::attestation::GetCertificateRequest> allowlisted_requests_;
-
-  // Maintains the allowlisted legacy create-certificate requests.
-  std::vector<::attestation::CreateCertificateRequestRequest>
-      allowlisted_create_requests_;
-
-  // Maintains the numbers assigned to the allowlisted requests.
-  std::vector<int> certificate_indices_;
-  // The count of certificates that has been issued.
-  int certificate_count_ = 0;
-
-  // Maintains the input request history of `DeleteKeys()`.
-  std::vector<::attestation::DeleteKeysRequest> delete_keys_history_;
-
-  // Maintains building components reply to `GetEnrollmentId()`.
-  std::string enrollment_id_;
-  std::string enrollment_id_ignore_cache_;
-  int enrollment_id_dbus_error_count_ = 0;
-
-  class GetKeyInfoRequestComparator {
-   public:
-    bool operator()(const ::attestation::GetKeyInfoRequest& r1,
-                    const ::attestation::GetKeyInfoRequest& r2) const {
-      return r1.username() == r2.username() ? r1.key_label() < r2.key_label()
-                                            : r1.username() < r2.username();
-    }
-  };
-  // The fake key info database. std::map is chosen because we don't have to
-  // implement the hash function for the `GetKeyInfoRequest`, which could be
-  // expensive and contributes unreasonable overhead at smaller scale, anyway.
-  std::map<::attestation::GetKeyInfoRequest,
-           ::attestation::GetKeyInfoReply,
-           GetKeyInfoRequestComparator>
-      key_info_database_;
-  int key_info_dbus_error_count_ = 0;
-
-  // The status returned by `SignSimpleChallenge()`.
-  ::attestation::AttestationStatus sign_simple_challenge_status_ =
-      ::attestation::STATUS_SUCCESS;
-  // The status returned by `Sign()`.
-  ::attestation::AttestationStatus sign_status_ = ::attestation::STATUS_SUCCESS;
-  // The table of username-label pairs of which keys can perform simple sign
-  // challenge.
-  std::set<std::pair<std::string, std::string>>
-      allowlisted_sign_simple_challenge_keys_;
-
-  // The status returned by `RegisterKeyWithChapsToken()`.
-  ::attestation::AttestationStatus register_key_status_ =
-      ::attestation::STATUS_SUCCESS;
-  // The table of username-label pairs of which keys can be registered to the
-  // key store.
-  std::set<std::pair<std::string, std::string>> allowlisted_register_keys_;
-
-  // The status returned by `SignEnterpriseChallenge()`.
-  ::attestation::AttestationStatus sign_enterprise_challenge_status_ =
-      ::attestation::STATUS_SUCCESS;
-
-  class SignEnterpriseChallengeRequestComparator {
-   public:
-    bool operator()(
-        const ::attestation::SignEnterpriseChallengeRequest& r1,
-        const ::attestation::SignEnterpriseChallengeRequest& r2) const {
-      // The inputs for signature generation `challenge()` and
-      // `include_signed_public_key()` are ignored.
-      return std::forward_as_tuple(r1.username(), r1.key_label(),
-                                   r1.key_name_for_spkac(), r1.domain(),
-                                   r1.device_id(), r1.va_type()) <
-             std::forward_as_tuple(r2.username(), r2.key_label(),
-                                   r2.key_name_for_spkac(), r2.domain(),
-                                   r2.device_id(), r2.va_type());
-    }
-  };
-  // The table of `SignEnterpriseChallenge` which can sign enterprise
-  // challenge.
-  std::set<::attestation::SignEnterpriseChallengeRequest,
-           SignEnterpriseChallengeRequestComparator>
-      allowlisted_sign_enterprise_challenge_keys_;
-  // The delay the reply of `SignEnterpriseChallenge()` is posted with.
-  base::TimeDelta sign_enterprise_challenge_delay_;
-
-  // The allowed ACA type for legacy attestation flow.
-  ::attestation::ACAType aca_type_for_legacy_mode_ = ::attestation::DEFAULT_ACA;
-
-  // The status returned by `CreateEnrollRequest()`.
-  ::attestation::AttestationStatus enroll_request_status_ =
-      ::attestation::STATUS_SUCCESS;
-  // The status returned by `CreateCertificateRequest()`.
-  ::attestation::AttestationStatus cert_request_status_ =
-      ::attestation::STATUS_SUCCESS;
-};
-
-}  // namespace chromeos
-
-#endif  // CHROMEOS_DBUS_ATTESTATION_FAKE_ATTESTATION_CLIENT_H_
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 93c91ab..4481868 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-105-5140.0-1656929358-benchmark-105.0.5171.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-105-5140.0-1657535009-benchmark-105.0.5173.0-r2-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index 5039955..79d6616 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-105-5112.23-1656928499-benchmark-105.0.5171.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-105-5140.0-1657533171-benchmark-105.0.5173.0-r2-redacted.afdo.xz
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index f0a63d7..fa96c115 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -268,6 +268,9 @@
   "crostini.RestartApp.stable",
   "crostini.RestartApp.clamshell_stable",
 
+  # http://b/238600197
+  "crostini.FilesAppWatch.buster_stable",
+
   # http://crbug.com/1335213
   "arc.WindowState.clamshell",
 
@@ -285,6 +288,9 @@
 
   # https://crbug.com/1341076
   "launcher.BubbleLaunchApp.disable_launcher_app_sort",
+
+  # http://b/238600125
+  "arc.TextToSpeech",
 ]
 
 # To create filters to be used on specific builders add them like this:
diff --git a/components/autofill_assistant/browser/public/BUILD.gn b/components/autofill_assistant/browser/public/BUILD.gn
index f74103e..db0fe4c 100644
--- a/components/autofill_assistant/browser/public/BUILD.gn
+++ b/components/autofill_assistant/browser/public/BUILD.gn
@@ -15,6 +15,7 @@
     "autofill_assistant_factory.h",
     "external_action_delegate.h",
     "headless_script_controller.h",
+    "public_script_parameters.h",
     "rectf.cc",
     "rectf.h",
     "runtime_manager.cc",
diff --git a/components/autofill_assistant/browser/public/public_script_parameters.h b/components/autofill_assistant/browser/public/public_script_parameters.h
new file mode 100644
index 0000000..42b7ec5
--- /dev/null
+++ b/components/autofill_assistant/browser/public/public_script_parameters.h
@@ -0,0 +1,47 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PUBLIC_PUBLIC_SCRIPT_PARAMETERS_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PUBLIC_PUBLIC_SCRIPT_PARAMETERS_H_
+
+namespace autofill_assistant::public_script_parameters {
+
+// Parameter that contains the current session username. Should be synced with
+// |SESSION_USERNAME_PARAMETER| from
+// .../password_manager/PasswordChangeLauncher.java
+// TODO(b/151401974): Eliminate duplicate parameter definitions.
+const char kPasswordChangeUsernameParameterName[] = "PASSWORD_CHANGE_USERNAME";
+
+// Whether the script should perform a login before changing the password.
+constexpr char kPasswordChangeSkipLoginParameterName[] =
+    "PASSWORD_CHANGE_SKIP_LOGIN";
+
+// Special bool parameter that MUST be present in all intents. It allows the
+// caller to either request immediate start of autofill assistant (if set to
+// true), or a delayed start using trigger scripts (if set to false). If this is
+// set to false, REQUEST_TRIGGER_SCRIPT or TRIGGER_SCRIPTS_BASE_64 must be set.
+const char kStartImmediatelyParameterName[] = "START_IMMEDIATELY";
+
+// Mandatory parameter that MUST be present and set to true in all intents.
+const char kEnabledParameterName[] = "ENABLED";
+
+// The original deeplink as indicated by the caller. Use this parameter instead
+// of the initial URL when available to avoid issues where the initial URL
+// points to a redirect rather than the actual deeplink.
+const char kOriginalDeeplinkParameterName[] = "ORIGINAL_DEEPLINK";
+
+// The intent parameter.
+const char kIntentParamenterName[] = "INTENT";
+
+// Parameter name of the CALLER script parameter. Note that the corresponding
+// values are integers, corresponding to the caller proto in the backend.
+const char kCallerParameterName[] = "CALLER";
+
+// Parameter name of the SOURCE script parameter. Note that the corresponding
+// values are integers, corresponding to the source proto in the backend.
+const char kSourceParameterName[] = "SOURCE";
+
+}  // namespace autofill_assistant::public_script_parameters
+
+#endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PUBLIC_PUBLIC_SCRIPT_PARAMETERS_H_
diff --git a/components/autofill_assistant/browser/script_parameters.cc b/components/autofill_assistant/browser/script_parameters.cc
index 4f883c43d..5d64699 100644
--- a/components/autofill_assistant/browser/script_parameters.cc
+++ b/components/autofill_assistant/browser/script_parameters.cc
@@ -12,6 +12,7 @@
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
+#include "components/autofill_assistant/browser/public/public_script_parameters.h"
 #include "components/autofill_assistant/browser/user_data.h"
 #include "components/autofill_assistant/browser/value_util.h"
 
@@ -48,55 +49,23 @@
 // Parameter that allows setting the color of the overlay.
 const char kOverlayColorParameterName[] = "OVERLAY_COLORS";
 
-// Parameter that contains the current session username. Should be synced with
-// |SESSION_USERNAME_PARAMETER| from
-// .../password_manager/PasswordChangeLauncher.java
-// TODO(b/151401974): Eliminate duplicate parameter definitions.
-const char kPasswordChangeUsernameParameterName[] = "PASSWORD_CHANGE_USERNAME";
-
 // Special parameter for instructing the client to request and run a trigger
 // script from a remote RPC prior to starting the regular flow.
 const char kRequestTriggerScriptParameterName[] = "REQUEST_TRIGGER_SCRIPT";
 
-// Special bool parameter that MUST be present in all intents. It allows the
-// caller to either request immediate start of autofill assistant (if set to
-// true), or a delayed start using trigger scripts (if set to false). If this is
-// set to false, REQUEST_TRIGGER_SCRIPT or TRIGGER_SCRIPTS_BASE_64 must be set.
-const char kStartImmediatelyParameterName[] = "START_IMMEDIATELY";
-
-// Mandatory parameter that MUST be present and set to true in all intents.
-// Note: this parameter is automatically removed from |ToProto|.
-const char kEnabledParameterName[] = "ENABLED";
-
 // The parameter key for the user's email, as indicated by the caller.
 const char kCallerEmailParameterName[] = "USER_EMAIL";
 
-// The original deeplink as indicated by the caller. Use this parameter instead
-// of the initial URL when available to avoid issues where the initial URL
-// points to a redirect rather than the actual deeplink.
-const char kOriginalDeeplinkParameterName[] = "ORIGINAL_DEEPLINK";
-
 // Special parameter for declaring a user to be in a trigger script experiment.
 const char kTriggerScriptExperimentParameterName[] =
     "TRIGGER_SCRIPT_EXPERIMENT";
 
-// The intent parameter.
-const char kIntent[] = "INTENT";
-
 // Parameter that allows enabling Text-to-Speech functionality.
 const char kEnableTtsParameterName[] = "ENABLE_TTS";
 
 // Allows enabling observer-based WaitForDOM.
 const char kEnableObserversParameter[] = "ENABLE_OBSERVER_WAIT_FOR_DOM";
 
-// Parameter name of the CALLER script parameter. Note that the corresponding
-// values are integers, corresponding to the caller proto in the backend.
-const char kCallerParameterName[] = "CALLER";
-
-// Parameter name of the SOURCE script parameter. Note that the corresponding
-// values are integers, corresponding to the source proto in the backend.
-const char kSourceParameterName[] = "SOURCE";
-
 // Parameter to specify experiments.
 const char kExperimentsParameterName[] = "EXPERIMENT_IDS";
 
@@ -112,8 +81,9 @@
 // autofill-assistant onboarding. Even so, please always reach out to Chrome
 // privacy when you plan to make use of this list, and/or adjust it.
 constexpr std::array<const char*, 6> kNonSensitiveScriptParameters = {
-    "DEBUG_BUNDLE_ID",    "DEBUG_BUNDLE_VERSION",    "DEBUG_SOCKET_ID",
-    "FALLBACK_BUNDLE_ID", "FALLBACK_BUNDLE_VERSION", kIntent};
+    "DEBUG_BUNDLE_ID",         "DEBUG_BUNDLE_VERSION",
+    "DEBUG_SOCKET_ID",         "FALLBACK_BUNDLE_ID",
+    "FALLBACK_BUNDLE_VERSION", public_script_parameters::kIntentParamenterName};
 
 // Parameters to specify details before the first backend roundtrip.
 const char kDetailsShowInitialParameterName[] = "DETAILS_SHOW_INITIAL";
@@ -180,7 +150,7 @@
 
   // TODO(arbesser): Send properly typed parameters to backend.
   for (const auto& parameter : parameters_) {
-    if (parameter.first == kEnabledParameterName) {
+    if (parameter.first == public_script_parameters::kEnabledParameterName) {
       continue;
     }
     if (parameter.second.is_client_side_only()) {
@@ -212,7 +182,8 @@
 
 absl::optional<std::string> ScriptParameters::GetPasswordChangeUsername()
     const {
-  return GetParameter(kPasswordChangeUsernameParameterName);
+  return GetParameter(
+      public_script_parameters::kPasswordChangeUsernameParameterName);
 }
 
 absl::optional<bool> ScriptParameters::GetRequestsTriggerScript() const {
@@ -221,15 +192,17 @@
 }
 
 absl::optional<bool> ScriptParameters::GetStartImmediately() const {
-  return GetTypedParameter<bool>(parameters_, kStartImmediatelyParameterName);
+  return GetTypedParameter<bool>(
+      parameters_, public_script_parameters::kStartImmediatelyParameterName);
 }
 
 absl::optional<bool> ScriptParameters::GetEnabled() const {
-  return GetTypedParameter<bool>(parameters_, kEnabledParameterName);
+  return GetTypedParameter<bool>(
+      parameters_, public_script_parameters::kEnabledParameterName);
 }
 
 absl::optional<std::string> ScriptParameters::GetOriginalDeeplink() const {
-  return GetParameter(kOriginalDeeplinkParameterName);
+  return GetParameter(public_script_parameters::kOriginalDeeplinkParameterName);
 }
 
 absl::optional<bool> ScriptParameters::GetTriggerScriptExperiment() const {
@@ -238,7 +211,7 @@
 }
 
 absl::optional<std::string> ScriptParameters::GetIntent() const {
-  return GetParameter(kIntent);
+  return GetParameter(public_script_parameters::kIntentParamenterName);
 }
 
 absl::optional<std::string> ScriptParameters::GetCallerEmail() const {
@@ -254,11 +227,13 @@
 }
 
 absl::optional<int> ScriptParameters::GetCaller() const {
-  return GetTypedParameter<int>(parameters_, kCallerParameterName);
+  return GetTypedParameter<int>(parameters_,
+                                public_script_parameters::kCallerParameterName);
 }
 
 absl::optional<int> ScriptParameters::GetSource() const {
-  return GetTypedParameter<int>(parameters_, kSourceParameterName);
+  return GetTypedParameter<int>(parameters_,
+                                public_script_parameters::kSourceParameterName);
 }
 
 std::vector<std::string> ScriptParameters::GetExperiments() const {
diff --git a/components/discardable_memory/service/discardable_shared_memory_manager.cc b/components/discardable_memory/service/discardable_shared_memory_manager.cc
index 61c8a45a..ad058b8 100644
--- a/components/discardable_memory/service/discardable_shared_memory_manager.cc
+++ b/components/discardable_memory/service/discardable_shared_memory_manager.cc
@@ -158,20 +158,20 @@
 // Returns the default memory limit to use for discardable memory, taking
 // the amount physical memory available and other platform specific constraints
 // into account.
-uint64_t GetDefaultMemoryLimit() {
-  const uint64_t kMegabyte = 1024ull * 1024;
+int64_t GetDefaultMemoryLimit() {
+  const int kMegabyte = 1024 * 1024;
 
 #if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
   // Bypass IsLowEndDevice() check and fix max_default_memory_limit to 64MB on
   // Chromecast devices. Set value here as IsLowEndDevice() is used on some, but
   // not all Chromecast devices.
-  uint64_t max_default_memory_limit = 64 * kMegabyte;
+  int64_t max_default_memory_limit = 64 * kMegabyte;
 #else
 #if BUILDFLAG(IS_ANDROID)
   // Limits the number of FDs used to 32, assuming a 4MB allocation size.
-  uint64_t max_default_memory_limit = 128 * kMegabyte;
+  int64_t max_default_memory_limit = 128 * kMegabyte;
 #else
-  uint64_t max_default_memory_limit = 512 * kMegabyte;
+  int64_t max_default_memory_limit = 512 * kMegabyte;
 #endif
 
   // Use 1/8th of discardable memory on low-end devices.
@@ -201,8 +201,7 @@
 
     // Allow 1/2 of available shmem dir space to be used for discardable memory.
     max_default_memory_limit =
-        std::min(max_default_memory_limit,
-                 static_cast<uint64_t>(shmem_dir_amount_of_free_space / 2));
+        std::min(max_default_memory_limit, shmem_dir_amount_of_free_space / 2);
   }
 #endif
 
diff --git a/components/exo/wayland/zaura_shell.cc b/components/exo/wayland/zaura_shell.cc
index 1bbfa83c..d6ccd97 100644
--- a/components/exo/wayland/zaura_shell.cc
+++ b/components/exo/wayland/zaura_shell.cc
@@ -768,6 +768,11 @@
   if (activated)
     AddState(&states, XDG_TOPLEVEL_STATE_ACTIVATED);
 
+  if (state_type == chromeos::WindowStateType::kPrimarySnapped)
+    AddState(&states, XDG_TOPLEVEL_STATE_TILED_LEFT);
+  if (state_type == chromeos::WindowStateType::kSecondarySnapped)
+    AddState(&states, XDG_TOPLEVEL_STATE_TILED_RIGHT);
+
   zaura_toplevel_send_configure(aura_toplevel_resource_, bounds.x(), bounds.y(),
                                 bounds.width(), bounds.height(), &states);
   wl_array_release(&states);
diff --git a/components/exo/wayland/zcr_keyboard_configuration.cc b/components/exo/wayland/zcr_keyboard_configuration.cc
index bdb76d6..3da62572 100644
--- a/components/exo/wayland/zcr_keyboard_configuration.cc
+++ b/components/exo/wayland/zcr_keyboard_configuration.cc
@@ -74,6 +74,7 @@
         is_physical
             ? ZCR_KEYBOARD_DEVICE_CONFIGURATION_V1_KEYBOARD_TYPE_PHYSICAL
             : ZCR_KEYBOARD_DEVICE_CONFIGURATION_V1_KEYBOARD_TYPE_VIRTUAL);
+    wl_client_flush(client());
   }
 
   // Overridden from ImeControllerImpl::Observer:
@@ -82,6 +83,7 @@
   void OnKeyboardLayoutNameChanged(const std::string& layout_name) override {
     zcr_keyboard_device_configuration_v1_send_layout_change(
         resource_, layout_name.c_str());
+    wl_client_flush(client());
   }
 
   // Overridden from ui::InputDeviceEventObserver:
@@ -127,8 +129,11 @@
     zcr_keyboard_device_configuration_v1_send_supported_key_bits(resource_,
                                                                  &wl_key_bits);
     wl_array_release(&wl_key_bits);
+    wl_client_flush(client());
   }
 
+  wl_client* client() const { return wl_resource_get_client(resource_); }
+
   wl_resource* resource_;
   Keyboard* keyboard_;
 };
diff --git a/components/messages/android/BUILD.gn b/components/messages/android/BUILD.gn
index 8a34a8d..fccd31a 100644
--- a/components/messages/android/BUILD.gn
+++ b/components/messages/android/BUILD.gn
@@ -59,6 +59,8 @@
     "message_enums.h",
     "message_wrapper.cc",
     "message_wrapper.h",
+    "throttler/domain_session_throttler.cc",
+    "throttler/domain_session_throttler.h",
   ]
   deps = [
     ":jni_headers",
diff --git a/components/messages/android/throttler/domain_session_throttler.cc b/components/messages/android/throttler/domain_session_throttler.cc
new file mode 100644
index 0000000..031af58f
--- /dev/null
+++ b/components/messages/android/throttler/domain_session_throttler.cc
@@ -0,0 +1,28 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/messages/android/throttler/domain_session_throttler.h"
+
+namespace messages {
+
+DomainSessionThrottler::DomainSessionThrottler(int capacity)
+    : cache_(base::LRUCacheSet<url::Origin>(capacity)) {}
+
+DomainSessionThrottler::~DomainSessionThrottler() {
+  cache_.Clear();
+}
+
+bool DomainSessionThrottler::ShouldShow(url::Origin url) {
+  if (cache_.max_size() == 0)
+    return true;
+  return cache_.Get(url) == cache_.end();
+}
+
+void DomainSessionThrottler::AddStrike(url::Origin url) {
+  if (cache_.max_size() == 0)
+    return;
+  cache_.Put(url::Origin(url));
+}
+
+}  // namespace messages
diff --git a/components/messages/android/throttler/domain_session_throttler.h b/components/messages/android/throttler/domain_session_throttler.h
new file mode 100644
index 0000000..f14aece
--- /dev/null
+++ b/components/messages/android/throttler/domain_session_throttler.h
@@ -0,0 +1,28 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MESSAGES_ANDROID_THROTTLER_DOMAIN_SESSION_THROTTLER_H_
+#define COMPONENTS_MESSAGES_ANDROID_THROTTLER_DOMAIN_SESSION_THROTTLER_H_
+
+#include "base/containers/lru_cache.h"
+#include "url/origin.h"
+
+namespace messages {
+// A simple wrapper of LRUCache to store domains on which
+// the messages should not be displayed.
+// Session means the throttler is valid during the lifecycle of
+// app and is reset every time app is destroyed.
+class DomainSessionThrottler {
+ public:
+  explicit DomainSessionThrottler(int capacity);
+  ~DomainSessionThrottler();
+  bool ShouldShow(url::Origin url);
+  void AddStrike(url::Origin url);
+
+ private:
+  base::LRUCacheSet<url::Origin> cache_;
+};
+}  // namespace messages
+
+#endif  // COMPONENTS_MESSAGES_ANDROID_THROTTLER_DOMAIN_SESSION_THROTTLER_H_
diff --git a/components/omnibox/browser/keyword_provider.cc b/components/omnibox/browser/keyword_provider.cc
index 50d676be..a18d590 100644
--- a/components/omnibox/browser/keyword_provider.cc
+++ b/components/omnibox/browser/keyword_provider.cc
@@ -232,8 +232,7 @@
   // Don't provide a keyword for inactive search engines (if the active search
   // engine flag is enabled). Prepopulated engines and extensions controlled
   // engines should always work regardless of is_active.
-  if (OmniboxFieldTrial::IsActiveSearchEnginesEnabled() &&
-      template_url->type() != TemplateURL::OMNIBOX_API_EXTENSION &&
+  if (template_url->type() != TemplateURL::OMNIBOX_API_EXTENSION &&
       template_url->prepopulate_id() == 0 &&
       template_url->is_active() != TemplateURLData::ActiveStatus::kTrue) {
     return std::u16string();
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 93a07d0..19dde84a 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -636,10 +636,6 @@
   return base::FeatureList::IsEnabled(omnibox::kDisableCGIParamMatching);
 }
 
-bool OmniboxFieldTrial::IsActiveSearchEnginesEnabled() {
-  return base::FeatureList::IsEnabled(omnibox::kActiveSearchEngines);
-}
-
 bool OmniboxFieldTrial::IsSiteSearchStarterPackEnabled() {
   return base::FeatureList::IsEnabled(omnibox::kSiteSearchStarterPack);
 }
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index 2980249c..0b1776e0 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -371,10 +371,6 @@
 // suggestions.
 bool ShouldDisableCGIParamMatching();
 
-// If true, enables a third category on the manage search engines page for
-// active search engines.
-bool IsActiveSearchEnginesEnabled();
-
 // If true, enables a "starter pack" of @history, @bookmarks, and @settings
 // scopes for Site Search.
 bool IsSiteSearchStarterPackEnabled();
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index f30f5f2..035b092 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -274,12 +274,6 @@
 const base::Feature kBlurWithEscape{"OmniboxBlurWithEscape",
                                     base::FEATURE_DISABLED_BY_DEFAULT};
 
-// When enabled, add an Active Search Engines category to
-// chrome://settings/searchEngines. This section contains any search engines
-// that have been used or manually added/modified by the user.
-const base::Feature kActiveSearchEngines{"OmniboxActiveSearchEngines",
-                                         base::FEATURE_ENABLED_BY_DEFAULT};
-
 // When enabled, adds a "starter pack" of @history, @bookmarks, and @settings
 // scopes to Site Search/Keyword Mode.
 const base::Feature kSiteSearchStarterPack{"OmniboxSiteSearchStarterPack",
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h
index e56c08d..31124a0 100644
--- a/components/omnibox/common/omnibox_features.h
+++ b/components/omnibox/common/omnibox_features.h
@@ -89,7 +89,6 @@
 
 // Settings Page - these affect the appearance of the Search Engines settings
 // page
-extern const base::Feature kActiveSearchEngines;
 extern const base::Feature kSiteSearchStarterPack;
 
 // Experiment to introduce new security indicators for HTTPS.
diff --git a/components/printing/common/cloud_print_cdd_conversion.cc b/components/printing/common/cloud_print_cdd_conversion.cc
index 6a41e88..342442b 100644
--- a/components/printing/common/cloud_print_cdd_conversion.cc
+++ b/components/printing/common/cloud_print_cdd_conversion.cc
@@ -27,6 +27,11 @@
 
 namespace {
 
+#if BUILDFLAG(IS_WIN)
+constexpr char kIdPageOutputQuality[] = "page_output_quality";
+constexpr char kDisplayNamePageOutputQuality[] = "Page output quality";
+#endif  // BUILDFLAG(IS_WIN)
+
 printer::DuplexType ToCloudDuplexType(printing::mojom::DuplexMode mode) {
   switch (mode) {
     case printing::mojom::DuplexMode::kSimplex:
@@ -167,6 +172,22 @@
 }
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
+#if BUILDFLAG(IS_WIN)
+printer::SelectVendorCapability GetPageOutputQualityCapabilities(
+    const printing::PrinterSemanticCapsAndDefaults& semantic_info) {
+  printer::SelectVendorCapability page_output_quality_capabilities;
+  const absl::optional<printing::PageOutputQuality>& page_output_quality =
+      semantic_info.page_output_quality;
+  for (const auto& attribute : page_output_quality->qualities) {
+    page_output_quality_capabilities.AddDefaultOption(
+        printer::SelectVendorCapabilityOption(attribute.name,
+                                              attribute.display_name),
+        attribute.name == page_output_quality->default_quality);
+  }
+  return page_output_quality_capabilities;
+}
+#endif  // BUILDFLAG(IS_WIN)
+
 }  // namespace
 
 base::Value PrinterSemanticCapsAndDefaultsToCdd(
@@ -244,6 +265,16 @@
   }
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
+#if BUILDFLAG(IS_WIN)
+  if (semantic_info.page_output_quality) {
+    printer::VendorCapabilities vendor_capabilities;
+    vendor_capabilities.AddOption(printer::VendorCapability(
+        kIdPageOutputQuality, kDisplayNamePageOutputQuality,
+        GetPageOutputQualityCapabilities(semantic_info)));
+    vendor_capabilities.SaveTo(&description);
+  }
+#endif  // BUILDFLAG(IS_WIN)
+
   return std::move(description).ToValue();
 }
 
diff --git a/components/printing/common/cloud_print_cdd_conversion_unittest.cc b/components/printing/common/cloud_print_cdd_conversion_unittest.cc
index 6d8f35a4..137580b 100644
--- a/components/printing/common/cloud_print_cdd_conversion_unittest.cc
+++ b/components/printing/common/cloud_print_cdd_conversion_unittest.cc
@@ -149,6 +149,49 @@
 ])json";
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
+#if BUILDFLAG(IS_WIN)
+constexpr char kExpectedPageOutputQuality[] = R"json([
+  {
+    "display_name": "Page output quality",
+    "id": "page_output_quality",
+    "select_cap": {
+      "option": [ {
+        "display_name": "Normal",
+        "value": "ns0000:Normal"
+      }, {
+        "display_name": "Draft",
+        "value": "ns0000:Draft",
+        "is_default": true
+      }, {
+        "display_name": "Custom Settings",
+        "value": "ns0000:AdvancedSetting"
+      } ]
+    },
+    "type": "SELECT"
+  }
+])json";
+
+constexpr char kExpectedPageOutputQualityNullDefault[] = R"json([
+  {
+    "display_name": "Page output quality",
+    "id": "page_output_quality",
+    "select_cap": {
+      "option": [ {
+        "display_name": "Normal",
+        "value": "ns0000:Normal"
+      }, {
+        "display_name": "Draft",
+        "value": "ns0000:Draft"
+      }, {
+        "display_name": "Custom Settings",
+        "value": "ns0000:AdvancedSetting"
+      } ]
+    },
+    "type": "SELECT"
+  }
+])json";
+#endif  // BUILDFLAG(IS_WIN)
+
 const printing::PrinterSemanticCapsAndDefaults::Paper kPaperA3{
     /*display_name=*/"A3", /*vendor_id=*/"67",
     /*size_um=*/gfx::Size(7016, 9921)};
@@ -190,6 +233,23 @@
     kAdvancedCapability1, kAdvancedCapability2};
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
+#if BUILDFLAG(IS_WIN)
+const printing::PageOutputQuality
+    kPageOutputQuality(/*qualities=*/
+                       {
+                           printing::PageOutputQualityAttribute(
+                               /*display_name=*/"Normal",
+                               /*name=*/"ns0000:Normal"),
+                           printing::PageOutputQualityAttribute(
+                               /*display_name=*/"Draft",
+                               /*name=*/"ns0000:Draft"),
+                           printing::PageOutputQualityAttribute(
+                               /*display_name=*/"Custom Settings",
+                               /*name=*/"ns0000:AdvancedSetting"),
+                       },
+                       /*default_quality=*/"ns0000:Draft");
+#endif  // BUILDFLAG(IS_WIN)
+
 constexpr bool kCollateCapable = true;
 constexpr bool kCollateDefault = true;
 
@@ -342,4 +402,34 @@
 }
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
+#if BUILDFLAG(IS_WIN)
+TEST(CloudPrintCddConversionTest, PageOutputQualityWithDefaultQuality) {
+  printing::PrinterSemanticCapsAndDefaults input =
+      GenerateSamplePrinterSemanticCapsAndDefaults();
+  input.page_output_quality = kPageOutputQuality;
+  const base::Value output = PrinterSemanticCapsAndDefaultsToCdd(input);
+  const base::Value::Dict* printer_dict = GetPrinterDict(output);
+
+  ASSERT_TRUE(printer_dict);
+  ASSERT_EQ(9u, printer_dict->size());
+  base::ExpectDictValue(base::test::ParseJson(kExpectedPageOutputQuality),
+                        *printer_dict, "vendor_capability");
+}
+
+TEST(CloudPrintCddConversionTest, PageOutputQualityNullDefaultQuality) {
+  printing::PrinterSemanticCapsAndDefaults input =
+      GenerateSamplePrinterSemanticCapsAndDefaults();
+  input.page_output_quality = kPageOutputQuality;
+  input.page_output_quality->default_quality = absl::nullopt;
+  const base::Value output = PrinterSemanticCapsAndDefaultsToCdd(input);
+  const base::Value::Dict* printer_dict = GetPrinterDict(output);
+
+  ASSERT_TRUE(printer_dict);
+  ASSERT_EQ(9u, printer_dict->size());
+  base::ExpectDictValue(
+      base::test::ParseJson(kExpectedPageOutputQualityNullDefault),
+      *printer_dict, "vendor_capability");
+}
+#endif  // BUILDFLAG(IS_WIN)
+
 }  // namespace cloud_print
\ No newline at end of file
diff --git a/components/segmentation_platform/internal/selection/segment_selector_impl.cc b/components/segmentation_platform/internal/selection/segment_selector_impl.cc
index dcfc51fb..b301173 100644
--- a/components/segmentation_platform/internal/selection/segment_selector_impl.cc
+++ b/components/segmentation_platform/internal/selection/segment_selector_impl.cc
@@ -27,6 +27,7 @@
 #include "components/segmentation_platform/public/config.h"
 #include "components/segmentation_platform/public/field_trial_register.h"
 #include "components/segmentation_platform/public/model_provider.h"
+#include "components/segmentation_platform/public/segment_selection_result.h"
 
 namespace segmentation_platform {
 namespace {
@@ -268,6 +269,11 @@
   if (!result->rank) {
     stats::RecordSegmentSelectionFailure(config_->segmentation_key,
                                          GetFailureReason(result->state));
+    if (config_->on_demand_execution && !callback.is_null()) {
+      base::ThreadTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE,
+          base::BindOnce(std::move(callback), SegmentSelectionResult()));
+    }
     return;
   }
   ranks->insert(std::make_pair(current_segment_id, *result->rank));
diff --git a/components/signin/internal/identity_manager/account_tracker_service_unittest.cc b/components/signin/internal/identity_manager/account_tracker_service_unittest.cc
index 4a4226c5..9f5e14a 100644
--- a/components/signin/internal/identity_manager/account_tracker_service_unittest.cc
+++ b/components/signin/internal/identity_manager/account_tracker_service_unittest.cc
@@ -249,9 +249,6 @@
 
   // Helpers to fake access token and user info fetching
   CoreAccountId AccountKeyToAccountId(AccountKey account_key) {
-    if (force_account_id_to_email_for_legacy_tests_)
-      return CoreAccountId(AccountKeyToEmail(account_key));
-
     return CoreAccountId::FromGaiaId(AccountKeyToGaiaId(account_key));
   }
 
@@ -357,10 +354,6 @@
     return signin_client_.GetTestURLLoaderFactory();
   }
 
-  bool* force_account_id_to_email_for_legacy_tests_pointer() {
-    return &force_account_id_to_email_for_legacy_tests_;
-  }
-
  protected:
   void ReturnFetchResults(const GURL& url,
                           net::HttpStatusCode response_code,
@@ -418,7 +411,6 @@
   raw_ptr<FakeAccountCapabilitiesFetcherFactory>
       fake_account_capabilities_fetcher_factory_ = nullptr;
   std::vector<TrackingEvent> account_tracker_events_;
-  bool force_account_id_to_email_for_legacy_tests_ = false;
 };
 
 void AccountTrackerServiceTest::ReturnFetchResults(
@@ -1204,41 +1196,6 @@
 }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-TEST_F(AccountTrackerServiceTest, LegacyDottedAccountIds) {
-  // Force legacy of non-normalized email as account_id.
-  base::AutoReset<bool> force_account_id_to_email_for_legacy_test(
-      force_account_id_to_email_for_legacy_tests_pointer(), true);
-
-  // Start by creating a tracker and adding an account with a dotted account
-  // id because of an old bug in token service.  The token service would also
-  // add a correct non-dotted account id for the same account.
-  ResetAccountTracker();
-
-  SimulateTokenAvailable(kAccountKeyFooDotBar);
-  SimulateTokenAvailable(kAccountKeyFooBar);
-  ReturnAccountInfoFetchSuccess(kAccountKeyFooDotBar);
-  ReturnAccountInfoFetchSuccess(kAccountKeyFooBar);
-
-  EXPECT_TRUE(account_fetcher()->IsAllUserInfoFetched());
-  std::vector<AccountInfo> infos = account_tracker()->GetAccounts();
-  ASSERT_EQ(2u, infos.size());
-  EXPECT_EQ(AccountKeyToEmail(kAccountKeyFooDotBar), infos[0].email);
-  EXPECT_EQ(AccountKeyToEmail(kAccountKeyFooBar), infos[1].email);
-
-  // Remove the bad account now from the token service to simulate that it
-  // has been "fixed".
-  SimulateTokenRevoked(kAccountKeyFooDotBar);
-
-  // Instantiate a new tracker and validate that it has only one account, and
-  // it is the correct non dotted one.
-  ResetAccountTrackerNetworkDisabled();
-
-  EXPECT_TRUE(account_fetcher()->IsAllUserInfoFetched());
-  infos = account_tracker()->GetAccounts();
-  ASSERT_EQ(1u, infos.size());
-  EXPECT_EQ(AccountKeyToEmail(kAccountKeyFooBar), infos[0].email);
-}
-
 TEST_F(AccountTrackerServiceTest, MigrateAccountIdToGaiaId) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(switches::kAccountIdMigration);
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc
index c54f007b..54756a6 100644
--- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc
+++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc
@@ -13,34 +13,11 @@
 #include "google_apis/gaia/gaia_access_token_fetcher.h"
 #include "google_apis/gaia/gaia_constants.h"
 
-namespace {
-// Values used from |MutableProfileOAuth2TokenServiceDelegate|.
-const net::BackoffEntry::Policy kBackoffPolicy = {
-    0 /* int num_errors_to_ignore */,
-
-    1000 /* int initial_delay_ms */,
-
-    2.0 /* double multiply_factor */,
-
-    0.2 /* double jitter_factor */,
-
-    15 * 60 * 1000 /* int64_t maximum_backoff_ms */,
-
-    -1 /* int64_t entry_lifetime_ms */,
-
-    false /* bool always_use_initial_delay */,
-};
-}  // namespace
-
-FakeProfileOAuth2TokenServiceDelegate::AccountInfo::AccountInfo(
-    const std::string& refresh_token)
-    : refresh_token(refresh_token), error(GoogleServiceAuthError::NONE) {}
-
 FakeProfileOAuth2TokenServiceDelegate::FakeProfileOAuth2TokenServiceDelegate()
-    : shared_factory_(
+    : ProfileOAuth2TokenServiceDelegate(/*use_backoff=*/true),
+      shared_factory_(
           base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-              &test_url_loader_factory_)),
-      backoff_entry_(&kBackoffPolicy) {}
+              &test_url_loader_factory_)) {}
 
 FakeProfileOAuth2TokenServiceDelegate::
     ~FakeProfileOAuth2TokenServiceDelegate() = default;
@@ -54,7 +31,7 @@
   DCHECK(it != refresh_tokens_.end());
   return GaiaAccessTokenFetcher::
       CreateExchangeRefreshTokenForAccessTokenInstance(
-          consumer, url_loader_factory, it->second->refresh_token);
+          consumer, url_loader_factory, it->second);
 }
 
 bool FakeProfileOAuth2TokenServiceDelegate::RefreshTokenIsAvailable(
@@ -62,26 +39,14 @@
   return !GetRefreshToken(account_id).empty();
 }
 
-GoogleServiceAuthError FakeProfileOAuth2TokenServiceDelegate::GetAuthError(
-    const CoreAccountId& account_id) const {
-  auto it = refresh_tokens_.find(account_id);
-  return (it == refresh_tokens_.end()) ? GoogleServiceAuthError::AuthErrorNone()
-                                       : it->second->error;
-}
-
 std::string FakeProfileOAuth2TokenServiceDelegate::GetRefreshToken(
     const CoreAccountId& account_id) const {
   auto it = refresh_tokens_.find(account_id);
   if (it != refresh_tokens_.end())
-    return it->second->refresh_token;
+    return it->second;
   return std::string();
 }
 
-const net::BackoffEntry* FakeProfileOAuth2TokenServiceDelegate::BackoffEntry()
-    const {
-  return &backoff_entry_;
-}
-
 std::vector<CoreAccountId> FakeProfileOAuth2TokenServiceDelegate::GetAccounts()
     const {
   std::vector<CoreAccountId> account_ids;
@@ -123,23 +88,27 @@
   if (token.empty()) {
     base::Erase(account_ids_, account_id);
     refresh_tokens_.erase(account_id);
+    ClearAuthError(account_id);
     FireRefreshTokenRevoked(account_id);
   } else {
     // Look for the account ID in the list, and if it is not present append it.
     if (base::ranges::find(account_ids_, account_id) == account_ids_.end()) {
       account_ids_.push_back(account_id);
     }
-    refresh_tokens_[account_id] = std::make_unique<AccountInfo>(token);
+    refresh_tokens_[account_id] = token;
     // If the token is a special "invalid" value, then that means the token was
     // rejected by the client and is thus not valid. So set the appropriate
     // error in that case. This logic is essentially duplicated from
     // MutableProfileOAuth2TokenServiceDelegate.
-    if (token == GaiaConstants::kInvalidRefreshToken) {
-      refresh_tokens_[account_id]->error =
-          GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
-              GoogleServiceAuthError::InvalidGaiaCredentialsReason::
-                  CREDENTIALS_REJECTED_BY_CLIENT);
-    }
+    GoogleServiceAuthError error =
+        token == GaiaConstants::kInvalidRefreshToken
+            ? GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+                  GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+                      CREDENTIALS_REJECTED_BY_CLIENT)
+            : GoogleServiceAuthError(GoogleServiceAuthError::NONE);
+    UpdateAuthError(account_id, error,
+                    /*fire_auth_error_changed=*/false);
+
     FireRefreshTokenAvailable(account_id);
   }
 }
@@ -154,8 +123,7 @@
     const CoreAccountId& account_id) {
   auto it = refresh_tokens_.find(account_id);
   DCHECK(it != refresh_tokens_.end());
-  to_service->GetDelegate()->UpdateCredentials(account_id,
-                                               it->second->refresh_token);
+  to_service->GetDelegate()->UpdateCredentials(account_id, it->second);
   RevokeCredentials(account_id);
 }
 
@@ -168,25 +136,6 @@
   return fix_request_if_possible_;
 }
 
-void FakeProfileOAuth2TokenServiceDelegate::UpdateAuthError(
-    const CoreAccountId& account_id,
-    const GoogleServiceAuthError& error) {
-  backoff_entry_.InformOfRequest(!error.IsTransientError());
-  // Drop transient errors to match ProfileOAuth2TokenService's stated contract
-  // for GetAuthError() and to allow clients to test proper behavior in the case
-  // of transient errors.
-  if (error.IsTransientError())
-    return;
-
-  if (GetAuthError(account_id) == error)
-    return;
-
-  auto it = refresh_tokens_.find(account_id);
-  DCHECK(it != refresh_tokens_.end());
-  it->second->error = error;
-  FireAuthErrorChanged(account_id, error);
-}
-
 #if BUILDFLAG(IS_ANDROID)
 base::android::ScopedJavaLocalRef<jobject>
 FakeProfileOAuth2TokenServiceDelegate::GetJavaObject() {
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h
index 8aa89396..8bf8cc9 100644
--- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h
+++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h
@@ -39,10 +39,6 @@
   // Overriden to make sure it works on Android.
   bool RefreshTokenIsAvailable(const CoreAccountId& account_id) const override;
 
-  GoogleServiceAuthError GetAuthError(
-      const CoreAccountId& account_id) const override;
-  void UpdateAuthError(const CoreAccountId& account_id,
-                       const GoogleServiceAuthError& error) override;
   std::vector<CoreAccountId> GetAccounts() const override;
   void RevokeAllCredentials() override;
   void LoadCredentials(const CoreAccountId& primary_account_id,
@@ -68,16 +64,7 @@
     fix_request_if_possible_ = value;
   }
 
-  const net::BackoffEntry* BackoffEntry() const override;
-
  private:
-  struct AccountInfo {
-    AccountInfo(const std::string& refresh_token);
-
-    const std::string refresh_token;
-    GoogleServiceAuthError error;
-  };
-
   void IssueRefreshTokenForUser(const CoreAccountId& account_id,
                                 const std::string& token);
 
@@ -89,13 +76,11 @@
   // A given account ID appears at most once in this list.
   std::list<CoreAccountId> account_ids_;
 
-  // Maps account ids to info.
-  std::map<CoreAccountId, std::unique_ptr<AccountInfo>> refresh_tokens_;
+  // Maps account ids to tokens.
+  std::map<CoreAccountId, std::string> refresh_tokens_;
 
   network::TestURLLoaderFactory test_url_loader_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> shared_factory_;
   bool fix_request_if_possible_ = false;
-
-  net::BackoffEntry backoff_entry_;
 };
 #endif  // COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_DELEGATE_H_
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
index 0e2e638..60d7e01 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -197,9 +197,8 @@
         signin::AccountConsistencyMethod account_consistency,
         bool revoke_all_tokens_on_load,
         FixRequestErrorCallback fix_request_error_callback)
-    : web_data_service_request_(0),
-      backoff_entry_(&backoff_policy_),
-      backoff_error_(GoogleServiceAuthError::NONE),
+    : ProfileOAuth2TokenServiceDelegate(/*use_backoff=*/true),
+      web_data_service_request_(0),
       client_(client),
       account_tracker_service_(account_tracker_service),
       network_connection_tracker_(network_connection_tracker),
@@ -212,14 +211,6 @@
   DCHECK(account_tracker_service_);
   DCHECK(network_connection_tracker_);
   DCHECK_NE(signin::AccountConsistencyMethod::kMirror, account_consistency_);
-  // It's okay to fill the backoff policy after being used in construction.
-  backoff_policy_.num_errors_to_ignore = 0;
-  backoff_policy_.initial_delay_ms = 1000;
-  backoff_policy_.multiply_factor = 2.0;
-  backoff_policy_.jitter_factor = 0.2;
-  backoff_policy_.maximum_backoff_ms = 15 * 60 * 1000;
-  backoff_policy_.entry_lifetime_ms = -1;
-  backoff_policy_.always_use_initial_delay = false;
   network_connection_tracker_->AddNetworkConnectionObserver(this);
 }
 
@@ -237,17 +228,18 @@
     OAuth2AccessTokenConsumer* consumer) {
   ValidateAccountId(account_id);
   // check whether the account has persistent error.
-  if (refresh_tokens_[account_id].last_auth_error.IsPersistentError()) {
+  GoogleServiceAuthError auth_error = GetAuthError(account_id);
+  if (auth_error.IsPersistentError()) {
     VLOG(1) << "Request for token has been rejected due to persistent error #"
-            << refresh_tokens_[account_id].last_auth_error.state();
-    return std::make_unique<OAuth2AccessTokenFetcherImmediateError>(
-        consumer, refresh_tokens_[account_id].last_auth_error);
+            << auth_error.state();
+    return std::make_unique<OAuth2AccessTokenFetcherImmediateError>(consumer,
+                                                                    auth_error);
   }
-  if (backoff_entry_.ShouldRejectRequest()) {
+  if (BackoffEntry()->ShouldRejectRequest()) {
     VLOG(1) << "Request for token has been rejected due to backoff rules from"
-            << " previous error #" << backoff_error_.state();
+            << " previous error #" << BackOffError().state();
     return std::make_unique<OAuth2AccessTokenFetcherImmediateError>(
-        consumer, backoff_error_);
+        consumer, BackOffError());
   }
   std::string refresh_token = GetRefreshToken(account_id);
   DCHECK(!refresh_token.empty());
@@ -256,53 +248,14 @@
           consumer, url_loader_factory, refresh_token);
 }
 
-GoogleServiceAuthError MutableProfileOAuth2TokenServiceDelegate::GetAuthError(
-    const CoreAccountId& account_id) const {
-  auto it = refresh_tokens_.find(account_id);
-  return (it == refresh_tokens_.end()) ? GoogleServiceAuthError::AuthErrorNone()
-                                       : it->second.last_auth_error;
-}
-
-void MutableProfileOAuth2TokenServiceDelegate::UpdateAuthError(
-    const CoreAccountId& account_id,
-    const GoogleServiceAuthError& error) {
-  VLOG(1) << "MutablePO2TS::UpdateAuthError. Error: " << error.state()
-          << " account_id=" << account_id;
-  backoff_entry_.InformOfRequest(!error.IsTransientError());
-  ValidateAccountId(account_id);
-
-  // Do not report connection errors as these are not actually auth errors.
-  // We also want to avoid masking a "real" auth error just because we
-  // subsequently get a transient network error.  We do keep it around though
-  // to report for future requests being denied for "backoff" reasons.
-  if (error.IsTransientError()) {
-    backoff_error_ = error;
-    return;
-  }
-
-  if (refresh_tokens_.count(account_id) == 0) {
-    // This could happen if the preferences have been corrupted (see
-    // http://crbug.com/321370). In a Debug build that would be a bug, but in a
-    // Release build we want to deal with it gracefully.
-    NOTREACHED();
-    return;
-  }
-
-  AccountStatus* status = &refresh_tokens_[account_id];
-  if (error != status->last_auth_error) {
-    status->last_auth_error = error;
-    FireAuthErrorChanged(account_id, error);
-  }
-}
-
 std::string MutableProfileOAuth2TokenServiceDelegate::GetTokenForMultilogin(
     const CoreAccountId& account_id) const {
   auto iter = refresh_tokens_.find(account_id);
   if (iter == refresh_tokens_.end() ||
-      iter->second.last_auth_error != GoogleServiceAuthError::AuthErrorNone()) {
+      GetAuthError(account_id) != GoogleServiceAuthError::AuthErrorNone()) {
     return std::string();
   }
-  const std::string& refresh_token = iter->second.refresh_token;
+  const std::string& refresh_token = iter->second;
   DCHECK(!refresh_token.empty());
   return refresh_token;
 }
@@ -317,7 +270,7 @@
     const CoreAccountId& account_id) const {
   auto iter = refresh_tokens_.find(account_id);
   if (iter != refresh_tokens_.end()) {
-    const std::string refresh_token = iter->second.refresh_token;
+    const std::string refresh_token = iter->second;
     DCHECK(!refresh_token.empty());
     return refresh_token;
   }
@@ -368,6 +321,7 @@
   DCHECK_EQ(0, web_data_service_request_);
 
   refresh_tokens_.clear();
+  ClearAuthError(absl::nullopt);
 
   if (!token_web_data_) {
     // This case only exists in unit tests that do not care about loading
@@ -531,7 +485,7 @@
   // If token present, and different from the new one, cancel its requests,
   // and clear the entries in cache related to that account.
   if (refresh_token_present) {
-    DCHECK_NE(refresh_token, refresh_tokens_[account_id].refresh_token);
+    DCHECK_NE(refresh_token, refresh_tokens_[account_id]);
     VLOG(1) << "MutablePO2TS::UpdateCredentials; Refresh Token was present. "
             << "account_id=" << account_id;
 
@@ -547,9 +501,9 @@
     // would also be invalidated server-side).
     // See http://crbug.com/865189 for more information about this regression.
     if (is_refresh_token_invalidated)
-      RevokeCredentialsOnServer(refresh_tokens_[account_id].refresh_token);
+      RevokeCredentialsOnServer(refresh_tokens_[account_id]);
 
-    refresh_tokens_[account_id].refresh_token = refresh_token;
+    refresh_tokens_[account_id] = refresh_token;
     UpdateAuthError(account_id, error);
   } else {
     VLOG(1) << "MutablePO2TS::UpdateCredentials; Refresh Token was absent. "
@@ -658,12 +612,7 @@
     network::mojom::ConnectionType type) {
   // If our network has changed, reset the backoff timer so that errors caused
   // by a previous lack of network connectivity don't prevent new requests.
-  backoff_entry_.Reset();
-}
-
-const net::BackoffEntry*
-MutableProfileOAuth2TokenServiceDelegate::BackoffEntry() const {
-  return &backoff_entry_;
+  ResetBackOffEntry();
 }
 
 bool MutableProfileOAuth2TokenServiceDelegate::FixRequestErrorIfPossible() {
@@ -677,7 +626,8 @@
     const std::string& refresh_token,
     const GoogleServiceAuthError& error) {
   DCHECK_EQ(0u, refresh_tokens_.count(account_id));
-  refresh_tokens_[account_id] = AccountStatus{refresh_token, error};
+  refresh_tokens_[account_id] = refresh_token;
+  UpdateAuthError(account_id, error, /*fire_auth_error_changed=*/false);
   FireAuthErrorChanged(account_id, error);
 }
 
@@ -694,10 +644,10 @@
   if (refresh_tokens_.count(account_id) > 0) {
     VLOG(1) << "MutablePO2TS::RevokeCredentials for account_id=" << account_id;
     ScopedBatchChange batch(this);
-    const std::string& token = refresh_tokens_[account_id].refresh_token;
     if (revoke_on_server)
-      RevokeCredentialsOnServer(token);
+      RevokeCredentialsOnServer(refresh_tokens_[account_id]);
     refresh_tokens_.erase(account_id);
+    ClearAuthError(account_id);
     ClearPersistedCredentials(account_id);
     FireRefreshTokenRevoked(account_id);
   }
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
index 82a113ef..4fa67d16 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
@@ -55,16 +55,9 @@
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
       OAuth2AccessTokenConsumer* consumer) override;
 
-  // Updates the internal cache of the result from the most-recently-completed
-  // auth request (used for reporting errors to the user).
-  void UpdateAuthError(const CoreAccountId& account_id,
-                       const GoogleServiceAuthError& error) override;
-
   std::string GetTokenForMultilogin(
       const CoreAccountId& account_id) const override;
   bool RefreshTokenIsAvailable(const CoreAccountId& account_id) const override;
-  GoogleServiceAuthError GetAuthError(
-      const CoreAccountId& account_id) const override;
   std::vector<CoreAccountId> GetAccounts() const override;
   scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory()
       const override;
@@ -81,9 +74,6 @@
   // Overridden from NetworkConnectionTracker::NetworkConnectionObserver.
   void OnConnectionChanged(network::mojom::ConnectionType type) override;
 
-  // Overridden from ProfileOAuth2TokenServiceDelegate.
-  const net::BackoffEntry* BackoffEntry() const override;
-
   bool FixRequestErrorIfPossible() override;
 
   // Returns the account's refresh token used for testing purposes.
@@ -94,11 +84,6 @@
 
   class RevokeServerRefreshToken;
 
-  struct AccountStatus {
-    std::string refresh_token;
-    GoogleServiceAuthError last_auth_error;
-  };
-
   FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
                            PersistenceDBUpgrade);
   FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
@@ -132,8 +117,6 @@
   FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
                            GetAccounts);
   FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
-                           RetryBackoff);
-  FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
                            CanonicalizeAccountId);
   FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
                            CanonAndNonCanonAccountId);
@@ -196,11 +179,8 @@
   void RevokeCredentialsImpl(const CoreAccountId& account_id,
                              bool revoke_on_server);
 
-  // Maps the |account_id| of accounts known to ProfileOAuth2TokenService
-  // to information about the account.
-  typedef std::map<CoreAccountId, AccountStatus> AccountStatusMap;
   // In memory refresh token store mapping account_id to refresh_token.
-  AccountStatusMap refresh_tokens_;
+  std::map<CoreAccountId, std::string> refresh_tokens_;
 
   // Handle to the request reading tokens from database.
   WebDataServiceBase::Handle web_data_service_request_;
@@ -215,11 +195,6 @@
   // this instance was created.
   THREAD_CHECKER(thread_checker_);
 
-  // Used to rate-limit network token requests so as to not overload the server.
-  net::BackoffEntry::Policy backoff_policy_;
-  net::BackoffEntry backoff_entry_;
-  GoogleServiceAuthError backoff_error_;
-
   raw_ptr<SigninClient> client_;
   raw_ptr<AccountTrackerService> account_tracker_service_;
   raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
index 97c523d..498242e 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -264,8 +264,7 @@
   EXPECT_TRUE(
       oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account_id));
   EXPECT_EQ(GaiaConstants::kInvalidRefreshToken,
-            oauth2_service_delegate_->refresh_tokens_[primary_account_id]
-                .refresh_token);
+            oauth2_service_delegate_->refresh_tokens_[primary_account_id]);
 }
 
 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
@@ -406,13 +405,13 @@
   // LoadCredentials() guarantees that the account given to it as argument
   // is in the refresh_token map.
   EXPECT_EQ(1U, oauth2_service_delegate_->refresh_tokens_.size());
-  EXPECT_EQ(
-      GaiaConstants::kInvalidRefreshToken,
-      oauth2_service_delegate_->refresh_tokens_[account_id].refresh_token);
+  EXPECT_EQ(GaiaConstants::kInvalidRefreshToken,
+            oauth2_service_delegate_->refresh_tokens_[account_id]);
   // Setup a DB with tokens that don't require upgrade and clear memory.
   oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
   oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
   oauth2_service_delegate_->refresh_tokens_.clear();
+  oauth2_service_delegate_->ClearAuthError(absl::nullopt);
   EXPECT_EQ(2, end_batch_changes_);
   EXPECT_EQ(2, auth_error_changed_count_);
   ResetObserverCounts();
@@ -477,6 +476,7 @@
   oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
   oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
   oauth2_service_delegate_->refresh_tokens_.clear();
+  oauth2_service_delegate_->ClearAuthError(absl::nullopt);
   EXPECT_EQ(2, end_batch_changes_);
   EXPECT_EQ(2, auth_error_changed_count_);
   ResetObserverCounts();
@@ -862,11 +862,11 @@
   EXPECT_EQ(0, access_token_success_count_);
   EXPECT_EQ(1, access_token_failure_count_);
   // Expect a positive backoff time.
-  EXPECT_GT(oauth2_service_delegate_->backoff_entry_.GetTimeUntilRelease(),
+  EXPECT_GT(oauth2_service_delegate_->BackoffEntry()->GetTimeUntilRelease(),
             base::TimeDelta());
 
   // Pretend that backoff has expired and try again.
-  oauth2_service_delegate_->backoff_entry_.SetCustomReleaseTime(
+  oauth2_service_delegate_->backoff_entry_->SetCustomReleaseTime(
       base::TimeTicks());
   std::unique_ptr<OAuth2AccessTokenFetcher> fetcher2 =
       oauth2_service_delegate_->CreateAccessTokenFetcher(
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.cc
index 925866b9..d0e1c9f 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.cc
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.cc
@@ -9,6 +9,26 @@
 #include "google_apis/gaia/oauth2_access_token_consumer.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
+namespace {
+
+const net::BackoffEntry::Policy kBackoffPolicy = {
+    0 /* int num_errors_to_ignore */,
+
+    1000 /* int initial_delay_ms */,
+
+    2.0 /* double multiply_factor */,
+
+    0.2 /* double jitter_factor */,
+
+    15 * 60 * 1000 /* int64_t maximum_backoff_ms (15 minutes) */,
+
+    -1 /* int64_t entry_lifetime_ms */,
+
+    false /* bool always_use_initial_delay */,
+};
+
+}  // namespace
+
 ProfileOAuth2TokenServiceDelegate::ScopedBatchChange::ScopedBatchChange(
     ProfileOAuth2TokenServiceDelegate* delegate)
     : delegate_(delegate) {
@@ -20,8 +40,12 @@
   delegate_->EndBatchChanges();
 }
 
-ProfileOAuth2TokenServiceDelegate::ProfileOAuth2TokenServiceDelegate()
-    : batch_change_depth_(0) {}
+ProfileOAuth2TokenServiceDelegate::ProfileOAuth2TokenServiceDelegate(
+    bool use_backoff)
+    : batch_change_depth_(0) {
+  if (use_backoff)
+    backoff_entry_ = std::make_unique<net::BackoffEntry>(&kBackoffPolicy);
+}
 
 ProfileOAuth2TokenServiceDelegate::~ProfileOAuth2TokenServiceDelegate() =
     default;
@@ -107,11 +131,6 @@
   return nullptr;
 }
 
-GoogleServiceAuthError ProfileOAuth2TokenServiceDelegate::GetAuthError(
-    const CoreAccountId& account_id) const {
-  return GoogleServiceAuthError::AuthErrorNone();
-}
-
 std::vector<CoreAccountId> ProfileOAuth2TokenServiceDelegate::GetAccounts()
     const {
   return std::vector<CoreAccountId>();
@@ -119,7 +138,7 @@
 
 const net::BackoffEntry* ProfileOAuth2TokenServiceDelegate::BackoffEntry()
     const {
-  return nullptr;
+  return backoff_entry_.get();
 }
 
 void ProfileOAuth2TokenServiceDelegate::LoadCredentials(
@@ -140,3 +159,78 @@
 bool ProfileOAuth2TokenServiceDelegate::FixRequestErrorIfPossible() {
   return false;
 }
+
+GoogleServiceAuthError ProfileOAuth2TokenServiceDelegate::GetAuthError(
+    const CoreAccountId& account_id) const {
+  auto it = errors_.find(account_id);
+  return (it == errors_.end()) ? GoogleServiceAuthError::AuthErrorNone()
+                               : it->second;
+}
+
+void ProfileOAuth2TokenServiceDelegate::UpdateAuthError(
+    const CoreAccountId& account_id,
+    const GoogleServiceAuthError& error,
+    bool fire_auth_error_changed) {
+  DVLOG(1) << "ProfileOAuth2TokenServiceDelegate::UpdateAuthError"
+           << " account=" << account_id << " error=" << error.ToString();
+
+  if (!RefreshTokenIsAvailable(account_id)) {
+    DLOG(ERROR) << "Update auth error failed because account="
+                << account_id.ToString() << "has no refresh token";
+    DCHECK_EQ(GetAuthError(account_id),
+              GoogleServiceAuthError::AuthErrorNone());
+    return;
+  }
+
+  if (backoff_entry_) {
+    backoff_entry_->InformOfRequest(!error.IsTransientError());
+    backoff_error_ = error;
+  }
+  ValidateAccountId(account_id);
+
+  // Do not report connection errors as these are not actually auth errors.
+  // We also want to avoid masking a "real" auth error just because we
+  // subsequently get a transient network error.  We do keep it around though
+  // to report for future requests being denied for "backoff" reasons.
+  if (error.IsTransientError())
+    return;
+
+  auto it = errors_.find(account_id);
+  if (error.state() == GoogleServiceAuthError::NONE) {
+    if (it == errors_.end())
+      return;
+    errors_.erase(it);
+  } else {
+    if (it != errors_.end() && it->second == error)
+      return;
+    errors_[account_id] = error;
+  }
+
+  if (fire_auth_error_changed)
+    FireAuthErrorChanged(account_id, error);
+}
+
+void ProfileOAuth2TokenServiceDelegate::ClearAuthError(
+    const absl::optional<CoreAccountId>& account_id) {
+  if (!account_id.has_value()) {
+    errors_.clear();
+    return;
+  }
+
+  auto it = errors_.find(account_id.value());
+  if (it != errors_.end())
+    errors_.erase(it);
+}
+
+GoogleServiceAuthError ProfileOAuth2TokenServiceDelegate::BackOffError() const {
+  return backoff_error_;
+}
+
+void ProfileOAuth2TokenServiceDelegate::ResetBackOffEntry() {
+  if (!backoff_entry_) {
+    NOTREACHED() << "Should be called only if `use_backoff` was true in the "
+                    "constructor.";
+    return;
+  }
+  backoff_entry_->Reset();
+}
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
index fb6cfe1..a71d331a 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
@@ -39,7 +39,7 @@
 // CreateAccessTokenFetcher properly.
 class ProfileOAuth2TokenServiceDelegate {
  public:
-  ProfileOAuth2TokenServiceDelegate();
+  explicit ProfileOAuth2TokenServiceDelegate(bool use_backoff);
 
   ProfileOAuth2TokenServiceDelegate(const ProfileOAuth2TokenServiceDelegate&) =
       delete;
@@ -61,10 +61,12 @@
   // returned by |GetAccounts|.
   virtual bool RefreshTokenIsAvailable(
       const CoreAccountId& account_id) const = 0;
+
   virtual GoogleServiceAuthError GetAuthError(
       const CoreAccountId& account_id) const;
   virtual void UpdateAuthError(const CoreAccountId& account_id,
-                               const GoogleServiceAuthError& error) {}
+                               const GoogleServiceAuthError& error,
+                               bool fire_auth_error_changed = true);
 
   // Returns a list of accounts for which a refresh token is maintained by
   // |this| instance, in the order the refresh tokens were added.
@@ -104,8 +106,8 @@
   void AddObserver(ProfileOAuth2TokenServiceObserver* observer);
   void RemoveObserver(ProfileOAuth2TokenServiceObserver* observer);
 
-  // Returns a pointer to its instance of net::BackoffEntry if it has one, or
-  // a nullptr otherwise.
+  // Returns a pointer to its instance of net::BackoffEntry if it has one
+  // (`use_backoff` was true in the constructor), or a nullptr otherwise.
   virtual const net::BackoffEntry* BackoffEntry() const;
 
   // -----------------------------------------------------------------------
@@ -161,6 +163,11 @@
     load_credentials_state_ = state;
   }
 
+  virtual void ClearAuthError(const absl::optional<CoreAccountId>& account_id);
+  virtual GoogleServiceAuthError BackOffError() const;
+  // Can be called only if `use_backoff` was true in the constructor.
+  virtual void ResetBackOffEntry();
+
   // Called by subclasses to notify observers.
   void FireEndBatchChanges();
   void FireRefreshTokenAvailable(const CoreAccountId& account_id);
@@ -186,6 +193,11 @@
   };
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
+                           RetryBackoff);
+  FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceDelegateChromeOSTest,
+                           BackOffIsTriggerredForTransientErrors);
+
   // List of observers to notify when refresh token availability changes.
   // Makes sure list is empty on destruction.
   base::ObserverList<ProfileOAuth2TokenServiceObserver, true>::Unchecked
@@ -200,6 +212,15 @@
 
   // The depth of batch changes.
   int batch_change_depth_;
+
+  // If the error is transient, back off is used on some platforms to rate-limit
+  // network token requests so as to not overload the server. |backoff_entry_|
+  // is initialized only if `use_backoff` was true in the constructor.
+  std::unique_ptr<net::BackoffEntry> backoff_entry_;
+  GoogleServiceAuthError backoff_error_;
+
+  // A map from account id to the last seen error for that account.
+  std::map<CoreAccountId, GoogleServiceAuthError> errors_;
 };
 
 #endif  // COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PROFILE_OAUTH2_TOKEN_SERVICE_DELEGATE_H_
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
index 010b083f..3f82668 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
@@ -149,7 +149,8 @@
 ProfileOAuth2TokenServiceDelegateAndroid::
     ProfileOAuth2TokenServiceDelegateAndroid(
         AccountTrackerService* account_tracker_service)
-    : account_tracker_service_(account_tracker_service),
+    : ProfileOAuth2TokenServiceDelegate(/*use_backoff=*/false),
+      account_tracker_service_(account_tracker_service),
       fire_refresh_token_loaded_(RT_LOAD_NOT_START) {
   DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::ctor";
   DCHECK(account_tracker_service_);
@@ -193,35 +194,6 @@
   return refresh_token_is_available == JNI_TRUE;
 }
 
-GoogleServiceAuthError ProfileOAuth2TokenServiceDelegateAndroid::GetAuthError(
-    const CoreAccountId& account_id) const {
-  auto it = errors_.find(account_id);
-  return (it == errors_.end()) ? GoogleServiceAuthError::AuthErrorNone()
-                               : it->second;
-}
-
-void ProfileOAuth2TokenServiceDelegateAndroid::UpdateAuthError(
-    const CoreAccountId& account_id,
-    const GoogleServiceAuthError& error) {
-  DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAuthError"
-           << " account=" << account_id << " error=" << error.ToString();
-
-  if (error.IsTransientError())
-    return;
-
-  auto it = errors_.find(account_id);
-  if (error.state() == GoogleServiceAuthError::NONE) {
-    if (it == errors_.end())
-      return;
-    errors_.erase(it);
-  } else {
-    if (it != errors_.end() && it->second == error)
-      return;
-    errors_[account_id] = error;
-  }
-  FireAuthErrorChanged(account_id, error);
-}
-
 std::vector<CoreAccountId>
 ProfileOAuth2TokenServiceDelegateAndroid::GetAccounts() const {
   return accounts_;
@@ -320,7 +292,7 @@
            << " prev_ids=" << prev_ids.size()
            << " curr_ids=" << curr_ids.size();
   // Clear any auth errors so that client can retry to get access tokens.
-  errors_.clear();
+  ClearAuthError(absl::nullopt);
 
   std::vector<CoreAccountId> refreshed_ids;
   std::vector<CoreAccountId> revoked_ids;
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
index e452292..7be0aafe 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
@@ -44,10 +44,7 @@
 
   // ProfileOAuth2TokenServiceDelegate overrides:
   bool RefreshTokenIsAvailable(const CoreAccountId& account_id) const override;
-  GoogleServiceAuthError GetAuthError(
-      const CoreAccountId& account_id) const override;
-  void UpdateAuthError(const CoreAccountId& account_id,
-                       const GoogleServiceAuthError& error) override;
+
   std::vector<CoreAccountId> GetAccounts() const override;
 
   // Overridden from ProfileOAuth2TokenService to complete signout of all
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc
index 9b5045e..b580aff 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc
@@ -23,23 +23,6 @@
 
 namespace {
 
-// Values used from |MutableProfileOAuth2TokenServiceDelegate|.
-const net::BackoffEntry::Policy kBackoffPolicy = {
-    0 /* int num_errors_to_ignore */,
-
-    1000 /* int initial_delay_ms */,
-
-    2.0 /* double multiply_factor */,
-
-    0.2 /* double jitter_factor */,
-
-    15 * 60 * 1000 /* int64_t maximum_backoff_ms */,
-
-    -1 /* int64_t entry_lifetime_ms */,
-
-    false /* bool always_use_initial_delay */,
-};
-
 // Maps crOS Account Manager |account_keys| to the account id representation
 // used by the OAuth token service chain. |account_keys| can safely contain Gaia
 // and non-Gaia accounts. Non-Gaia accounts will be filtered out.
@@ -147,12 +130,11 @@
         bool delete_signin_cookies_on_exit,
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
         bool is_regular_profile)
-    : signin_client_(signin_client),
+    : ProfileOAuth2TokenServiceDelegate(/*use_backoff=*/true),
+      signin_client_(signin_client),
       account_tracker_service_(account_tracker_service),
       network_connection_tracker_(network_connection_tracker),
       account_manager_facade_(account_manager_facade),
-      backoff_entry_(&kBackoffPolicy),
-      backoff_error_(GoogleServiceAuthError::NONE),
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
       delete_signin_cookies_on_exit_(delete_signin_cookies_on_exit),
 #endif
@@ -182,21 +164,21 @@
   // Check if we need to reject the request.
   // We will reject the request if we are facing a persistent error for this
   // account.
-  auto it = errors_.find(account_id);
-  if (it != errors_.end() && it->second.last_auth_error.IsPersistentError()) {
+  GoogleServiceAuthError error = GetAuthError(account_id);
+  if (error.IsPersistentError()) {
     VLOG(1) << "Request for token has been rejected due to persistent error #"
-            << it->second.last_auth_error.state();
+            << error.state();
     // |ProfileOAuth2TokenService| will manage the lifetime of this pointer.
-    return std::make_unique<OAuth2AccessTokenFetcherImmediateError>(
-        consumer, it->second.last_auth_error);
+    return std::make_unique<OAuth2AccessTokenFetcherImmediateError>(consumer,
+                                                                    error);
   }
   // Or when we need to backoff.
-  if (backoff_entry_.ShouldRejectRequest()) {
+  if (BackoffEntry()->ShouldRejectRequest()) {
     VLOG(1) << "Request for token has been rejected due to backoff rules from"
-            << " previous error #" << backoff_error_.state();
+            << " previous error #" << BackOffError().state();
     // |ProfileOAuth2TokenService| will manage the lifetime of this pointer.
     return std::make_unique<OAuth2AccessTokenFetcherImmediateError>(
-        consumer, backoff_error_);
+        consumer, BackOffError());
   }
 
   return account_manager_facade_->CreateAccessTokenFetcher(
@@ -224,56 +206,6 @@
                         account_id);
 }
 
-void ProfileOAuth2TokenServiceDelegateChromeOS::UpdateAuthError(
-    const CoreAccountId& account_id,
-    const GoogleServiceAuthError& error) {
-  UpdateAuthErrorInternal(account_id, error, /*fire_auth_error_changed=*/true);
-}
-
-void ProfileOAuth2TokenServiceDelegateChromeOS::UpdateAuthErrorInternal(
-    const CoreAccountId& account_id,
-    const GoogleServiceAuthError& error,
-    bool fire_auth_error_changed) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  backoff_entry_.InformOfRequest(!error.IsTransientError());
-  ValidateAccountId(account_id);
-  if (error.IsTransientError()) {
-    backoff_error_ = error;
-    return;
-  }
-
-  auto it = errors_.find(account_id);
-  if (it != errors_.end()) {
-    if (error == it->second.last_auth_error)
-      return;
-    // Update the existing error.
-    if (error.state() == GoogleServiceAuthError::NONE)
-      errors_.erase(it);
-    else
-      it->second.last_auth_error = error;
-    if (fire_auth_error_changed) {
-      FireAuthErrorChanged(account_id, error);
-    }
-  } else if (error.state() != GoogleServiceAuthError::NONE) {
-    // Add a new error.
-    errors_.emplace(account_id, AccountErrorStatus{error});
-    if (fire_auth_error_changed) {
-      FireAuthErrorChanged(account_id, error);
-    }
-  }
-}
-
-GoogleServiceAuthError ProfileOAuth2TokenServiceDelegateChromeOS::GetAuthError(
-    const CoreAccountId& account_id) const {
-  auto it = errors_.find(account_id);
-  if (it != errors_.end()) {
-    return it->second.last_auth_error;
-  }
-
-  return GoogleServiceAuthError::AuthErrorNone();
-}
-
 // Note: This method should use the same logic for filtering accounts as
 // |RefreshTokenIsAvailable|. See crbug.com/919793 for details. At the time of
 // writing, both |GetAccounts| and |RefreshTokenIsAvailable| use
@@ -458,8 +390,8 @@
 
   // Don't call |FireAuthErrorChanged|, since we call it at the end of this
   // function.
-  UpdateAuthErrorInternal(account_id, error,
-                          /*fire_auth_error_changed=*/false);
+  UpdateAuthError(account_id, error,
+                  /*fire_auth_error_changed=*/false);
 
   ScopedBatchChange batch(this);
   FireRefreshTokenAvailable(account_id);
@@ -524,8 +456,7 @@
           ->FindAccountInfoByGaiaId(account.key.id() /* gaia_id */)
           .account_id;
   DCHECK(!account_id.empty());
-  UpdateAuthErrorInternal(account_id, GoogleServiceAuthError::AuthErrorNone(),
-                          /*fire_auth_error_changed=*/false);
+  ClearAuthError(account_id);
 
   ScopedBatchChange batch(this);
 
@@ -560,14 +491,9 @@
 #endif
 }
 
-const net::BackoffEntry*
-ProfileOAuth2TokenServiceDelegateChromeOS::BackoffEntry() const {
-  return &backoff_entry_;
-}
-
 void ProfileOAuth2TokenServiceDelegateChromeOS::OnConnectionChanged(
     network::mojom::ConnectionType type) {
-  backoff_entry_.Reset();
+  ResetBackOffEntry();
 }
 
 }  // namespace signin
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.h b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.h
index 72f0213..9e30846 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.h
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.h
@@ -57,13 +57,6 @@
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
       OAuth2AccessTokenConsumer* consumer) override;
   bool RefreshTokenIsAvailable(const CoreAccountId& account_id) const override;
-  void UpdateAuthError(const CoreAccountId& account_id,
-                       const GoogleServiceAuthError& error) override;
-  void UpdateAuthErrorInternal(const CoreAccountId& account_id,
-                               const GoogleServiceAuthError& error,
-                               bool fire_auth_error_changed = true);
-  GoogleServiceAuthError GetAuthError(
-      const CoreAccountId& account_id) const override;
   std::vector<CoreAccountId> GetAccounts() const override;
   void LoadCredentials(const CoreAccountId& primary_account_id,
                        bool is_syncing) override;
@@ -73,7 +66,6 @@
       const override;
   void RevokeCredentials(const CoreAccountId& account_id) override;
   void RevokeAllCredentials() override;
-  const net::BackoffEntry* BackoffEntry() const override;
 
   // `account_manager::AccountManagerFacade::Observer` overrides.
   void OnAccountUpserted(const account_manager::Account& account) override;
@@ -83,17 +75,7 @@
   void OnConnectionChanged(network::mojom::ConnectionType type) override;
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceDelegateChromeOSTest,
-                           BackOffIsTriggerredForTransientErrors);
-  FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceDelegateChromeOSTest,
-                           BackOffIsResetOnNetworkChange);
-
-  // A utility class to keep track of |GoogleServiceAuthError|s for an account.
-  struct AccountErrorStatus {
-    // The last auth error seen.
-    GoogleServiceAuthError last_auth_error;
-  };
-
+  friend class TestProfileOAuth2TokenServiceDelegateChromeOS;
   // Callback handler for `account_manager::AccountManagerFacade::GetAccounts`.
   void OnGetAccounts(const std::vector<account_manager::Account>& accounts);
 
@@ -123,13 +105,6 @@
   // A cache of AccountKeys.
   std::set<account_manager::AccountKey> account_keys_;
 
-  // A map from account id to the last seen error for that account.
-  std::map<CoreAccountId, AccountErrorStatus> errors_;
-
-  // Used to rate-limit token fetch requests so as to not overload the server.
-  net::BackoffEntry backoff_entry_;
-  GoogleServiceAuthError backoff_error_;
-
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   const bool delete_signin_cookies_on_exit_;
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos_unittest.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos_unittest.cc
index 07e1e90..54da9c0 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos_unittest.cc
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos_unittest.cc
@@ -37,8 +37,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace signin {
-
 namespace {
 
 using ::account_manager::AccountManager;
@@ -244,14 +242,15 @@
       bool delete_signin_cookies_on_exit,
       bool is_syncing) {
     delegate_.reset();
-    delegate_ = std::make_unique<ProfileOAuth2TokenServiceDelegateChromeOS>(
-        client_.get(), &account_tracker_service_,
-        network::TestNetworkConnectionTracker::GetInstance(),
-        account_manager_facade_.get(),
+    delegate_ =
+        std::make_unique<signin::ProfileOAuth2TokenServiceDelegateChromeOS>(
+            client_.get(), &account_tracker_service_,
+            network::TestNetworkConnectionTracker::GetInstance(),
+            account_manager_facade_.get(),
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-        delete_signin_cookies_on_exit,
+            delete_signin_cookies_on_exit,
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-        /*is_regular_profile=*/true);
+            /*is_regular_profile=*/true);
 
     LoadCredentialsAndWaitForCompletion(
         /*primary_account_id=*/account_info_.account_id, is_syncing);
@@ -387,7 +386,7 @@
       account_manager_mojo_service_;
   std::unique_ptr<account_manager::AccountManagerFacade>
       account_manager_facade_;
-  std::unique_ptr<ProfileOAuth2TokenServiceDelegateChromeOS> delegate_;
+  std::unique_ptr<signin::ProfileOAuth2TokenServiceDelegateChromeOS> delegate_;
   AccountManager::DelayNetworkCallRunner immediate_callback_runner_ =
       base::BindRepeating(
           [](base::OnceClosure closure) -> void { std::move(closure).Run(); });
@@ -456,14 +455,15 @@
   // behaviour.
   AccountManager account_manager;
 
-  auto delegate = std::make_unique<ProfileOAuth2TokenServiceDelegateChromeOS>(
-      client_.get(), &account_tracker_service_,
-      network::TestNetworkConnectionTracker::GetInstance(),
-      account_manager_facade_.get(),
+  auto delegate =
+      std::make_unique<signin::ProfileOAuth2TokenServiceDelegateChromeOS>(
+          client_.get(), &account_tracker_service_,
+          network::TestNetworkConnectionTracker::GetInstance(),
+          account_manager_facade_.get(),
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-      /*delete_signin_cookies_on_exit=*/false,
+          /*delete_signin_cookies_on_exit=*/false,
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-      /*is_regular_profile=*/false);
+          /*is_regular_profile=*/false);
   TestOAuth2TokenServiceObserver observer(delegate.get());
 
   // Test that LoadCredentials works as expected.
@@ -471,14 +471,16 @@
   delegate->LoadCredentials(CoreAccountId() /* primary_account_id */,
                             /*is_syncing=*/false);
   EXPECT_TRUE(observer.refresh_tokens_loaded_);
-  EXPECT_EQ(LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
-            delegate->load_credentials_state());
+  EXPECT_EQ(
+      signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
+      delegate->load_credentials_state());
 }
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        RefreshTokenIsAvailableReturnsTrueForValidGaiaTokens) {
-  EXPECT_EQ(LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
-            delegate_->load_credentials_state());
+  EXPECT_EQ(
+      signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
+      delegate_->load_credentials_state());
 
   EXPECT_FALSE(delegate_->RefreshTokenIsAvailable(account_info_.account_id));
   EXPECT_FALSE(
@@ -493,8 +495,9 @@
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        RefreshTokenIsAvailableReturnsTrueForInvalidGaiaTokens) {
-  EXPECT_EQ(LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
-            delegate_->load_credentials_state());
+  EXPECT_EQ(
+      signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
+      delegate_->load_credentials_state());
 
   EXPECT_FALSE(delegate_->RefreshTokenIsAvailable(account_info_.account_id));
   EXPECT_FALSE(
@@ -510,6 +513,7 @@
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        ObserversAreNotifiedOnAuthErrorChange) {
+  UpsertAccountAndWaitForCompletion(gaia_account_key(), kUserEmail, kGaiaToken);
   TestOAuth2TokenServiceObserver observer(delegate_.get());
   auto error =
       GoogleServiceAuthError(GoogleServiceAuthError::State::SERVICE_ERROR);
@@ -522,18 +526,21 @@
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        ObserversAreNotNotifiedIfErrorDidntChange) {
+  UpsertAccountAndWaitForCompletion(gaia_account_key(), kUserEmail, kGaiaToken);
   TestOAuth2TokenServiceObserver observer(delegate_.get());
   auto error =
       GoogleServiceAuthError(GoogleServiceAuthError::State::SERVICE_ERROR);
 
   delegate_->UpdateAuthError(account_info_.account_id, error);
   EXPECT_EQ(1, observer.on_auth_error_changed_calls);
+  EXPECT_EQ(error, delegate_->GetAuthError(account_info_.account_id));
   delegate_->UpdateAuthError(account_info_.account_id, error);
   EXPECT_EQ(1, observer.on_auth_error_changed_calls);
 }
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        ObserversAreNotifiedIfErrorDidChange) {
+  UpsertAccountAndWaitForCompletion(gaia_account_key(), kUserEmail, kGaiaToken);
   TestOAuth2TokenServiceObserver observer(delegate_.get());
   delegate_->UpdateAuthError(
       account_info_.account_id,
@@ -582,6 +589,7 @@
                                     kGaiaToken);
   // Deliberately add an error.
   delegate_->UpdateAuthError(account_info_.account_id, error);
+  EXPECT_EQ(error, delegate_->GetAuthError(account_info_.account_id));
   RemoveAccountAndWaitForCompletion(gaia_account_key());
   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
             delegate_->GetAuthError(account_info_.account_id));
@@ -684,14 +692,15 @@
       CreateAccountManagerFacade(account_manager_mojo_service.get());
 
   // Register callbacks before AccountManager has been fully initialized.
-  auto delegate = std::make_unique<ProfileOAuth2TokenServiceDelegateChromeOS>(
-      client_.get(), &account_tracker_service_,
-      network::TestNetworkConnectionTracker::GetInstance(),
-      account_manager_facade.get(),
+  auto delegate =
+      std::make_unique<signin::ProfileOAuth2TokenServiceDelegateChromeOS>(
+          client_.get(), &account_tracker_service_,
+          network::TestNetworkConnectionTracker::GetInstance(),
+          account_manager_facade.get(),
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-      /*delete_signin_cookies_on_exit=*/false,
+          /*delete_signin_cookies_on_exit=*/false,
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS
-      /*is_regular_profile=*/true);
+          /*is_regular_profile=*/true);
   delegate->LoadCredentials(account1.account_id /* primary_account_id */,
                             /*is_syncing=*/false);
   TestOAuth2TokenServiceObserver observer(delegate.get());
@@ -750,8 +759,9 @@
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        RefreshTokenMustBeAvailableForAllAccountsReturnedByGetAccounts) {
-  EXPECT_EQ(LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
-            delegate_->load_credentials_state());
+  EXPECT_EQ(
+      signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
+      delegate_->load_credentials_state());
   EXPECT_TRUE(delegate_->GetAccounts().empty());
   const std::string kUserEmail2 = "random-email2@example.com";
   const std::string kUserEmail3 = "random-email3@example.com";
@@ -851,6 +861,7 @@
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        SigninErrorObserversAreNotifiedOnAuthErrorChange) {
+  UpsertAccountAndWaitForCompletion(gaia_account_key(), kUserEmail, kGaiaToken);
   auto error =
       GoogleServiceAuthError(GoogleServiceAuthError::State::SERVICE_ERROR);
 
@@ -861,6 +872,7 @@
 
 TEST_F(ProfileOAuth2TokenServiceDelegateChromeOSTest,
        TransientErrorsAreNotShown) {
+  UpsertAccountAndWaitForCompletion(gaia_account_key(), kUserEmail, kGaiaToken);
   auto transient_error = GoogleServiceAuthError(
       GoogleServiceAuthError::State::SERVICE_UNAVAILABLE);
   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
@@ -898,10 +910,11 @@
   EXPECT_EQ(0, access_token_consumer.num_access_token_fetch_success_);
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_failure_);
   // Expect a positive backoff time.
-  EXPECT_GT(delegate_->backoff_entry_.GetTimeUntilRelease(), base::TimeDelta());
+  EXPECT_GT(delegate_->BackoffEntry()->GetTimeUntilRelease(),
+            base::TimeDelta());
 
   // Pretend that backoff has expired and try again.
-  delegate_->backoff_entry_.SetCustomReleaseTime(base::TimeTicks());
+  delegate_->backoff_entry_->SetCustomReleaseTime(base::TimeTicks());
   fetcher = delegate_->CreateAccessTokenFetcher(
       account_info_.account_id, delegate_->GetURLLoaderFactory(),
       &access_token_consumer);
@@ -937,7 +950,8 @@
   EXPECT_EQ(0, access_token_consumer.num_access_token_fetch_success_);
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_failure_);
   // Expect a positive backoff time.
-  EXPECT_GT(delegate_->backoff_entry_.GetTimeUntilRelease(), base::TimeDelta());
+  EXPECT_GT(delegate_->BackoffEntry()->GetTimeUntilRelease(),
+            base::TimeDelta());
 
   // Notify of network change and ensure that request now runs.
   delegate_->OnConnectionChanged(
@@ -950,5 +964,3 @@
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_success_);
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_failure_);
 }
-
-}  // namespace signin
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h
index 1750fde..53ab5f2e 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h
@@ -41,10 +41,6 @@
   void Shutdown() override;
 
   bool RefreshTokenIsAvailable(const CoreAccountId& account_id) const override;
-  GoogleServiceAuthError GetAuthError(
-      const CoreAccountId& account_id) const override;
-  void UpdateAuthError(const CoreAccountId& account_id,
-                       const GoogleServiceAuthError& error) override;
 
   void LoadCredentials(const CoreAccountId& primary_account_id,
                        bool is_syncing) override;
@@ -76,21 +72,13 @@
  private:
   friend class ProfileOAuth2TokenServiceIOSDelegateTest;
 
-  struct AccountStatus {
-    GoogleServiceAuthError last_auth_error;
-  };
-
-  // Maps the |account_id| of accounts known to ProfileOAuth2TokenService
-  // to information about the account.
-  typedef std::map<CoreAccountId, AccountStatus> AccountStatusMap;
-
   // Reloads accounts from the provider. Fires |OnRefreshTokenAvailable| for
   // each new account. Fires |OnRefreshTokenRevoked| for each account that was
   // removed.
   void ReloadCredentials(const CoreAccountId& primary_account_id);
 
   // Info about the existing accounts.
-  AccountStatusMap accounts_;
+  std::set<CoreAccountId> accounts_;
 
   // Calls to this class are expected to be made from the browser UI thread.
   // The purpose of this checker is to detect access to
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
index 3b4d9bf..72b006a 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
@@ -160,7 +160,8 @@
     SigninClient* client,
     std::unique_ptr<DeviceAccountsProvider> provider,
     AccountTrackerService* account_tracker_service)
-    : client_(client),
+    : ProfileOAuth2TokenServiceDelegate(/*use_backoff=*/false),
+      client_(client),
       provider_(std::move(provider)),
       account_tracker_service_(account_tracker_service) {
   DCHECK(client_);
@@ -175,6 +176,7 @@
 void ProfileOAuth2TokenServiceIOSDelegate::Shutdown() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   accounts_.clear();
+  ClearAuthError(absl::nullopt);
 }
 
 void ProfileOAuth2TokenServiceIOSDelegate::LoadCredentials(
@@ -209,12 +211,11 @@
 
     // For whatever reason, we failed to load the device account for the primary
     // account. There must always be an account for the primary account
-    accounts_[primary_account_id].last_auth_error =
-        GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
-            GoogleServiceAuthError::InvalidGaiaCredentialsReason::
-                CREDENTIALS_MISSING);
-    FireAuthErrorChanged(primary_account_id,
-                         accounts_[primary_account_id].last_auth_error);
+    accounts_.insert(primary_account_id);
+    UpdateAuthError(primary_account_id,
+                    GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+                        GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+                            CREDENTIALS_MISSING));
     FireRefreshTokenAvailable(primary_account_id);
     set_load_credentials_state(
         signin::LoadCredentialsState::
@@ -287,9 +288,9 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   ScopedBatchChange batch(this);
-  AccountStatusMap toRemove = accounts_;
-  for (auto& accountStatus : toRemove)
-    RemoveAccount(accountStatus.first);
+  std::set<CoreAccountId> toRemove = accounts_;
+  for (auto& account_id : toRemove)
+    RemoveAccount(account_id);
 
   DCHECK_EQ(0u, accounts_.size());
 }
@@ -319,10 +320,7 @@
 std::vector<CoreAccountId> ProfileOAuth2TokenServiceIOSDelegate::GetAccounts()
     const {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  std::vector<CoreAccountId> account_ids;
-  for (const auto& account : accounts_)
-    account_ids.push_back(account.first);
-  return account_ids;
+  return std::vector<CoreAccountId>(accounts_.begin(), accounts_.end());
 }
 
 bool ProfileOAuth2TokenServiceIOSDelegate::RefreshTokenIsAvailable(
@@ -332,36 +330,6 @@
   return accounts_.count(account_id) > 0;
 }
 
-GoogleServiceAuthError ProfileOAuth2TokenServiceIOSDelegate::GetAuthError(
-    const CoreAccountId& account_id) const {
-  auto it = accounts_.find(account_id);
-  return (it == accounts_.end()) ? GoogleServiceAuthError::AuthErrorNone()
-                                 : it->second.last_auth_error;
-}
-
-void ProfileOAuth2TokenServiceIOSDelegate::UpdateAuthError(
-    const CoreAccountId& account_id,
-    const GoogleServiceAuthError& error) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  // Do not report connection errors as these are not actually auth errors.
-  // We also want to avoid masking a "real" auth error just because we
-  // subsequently get a transient network error.
-  if (error.IsTransientError())
-    return;
-
-  if (accounts_.count(account_id) == 0) {
-    // Nothing to update as the account has already been removed.
-    return;
-  }
-
-  AccountStatus* status = &accounts_[account_id];
-  if (error.state() != status->last_auth_error.state()) {
-    status->last_auth_error = error;
-    FireAuthErrorChanged(account_id, error);
-  }
-}
-
 // Clear the authentication error state and notify all observers that a new
 // refresh token is available so that they request new access tokens.
 void ProfileOAuth2TokenServiceIOSDelegate::AddOrUpdateAccount(
@@ -373,15 +341,16 @@
   DCHECK(!account_tracker_service_->GetAccountInfo(account_id).email.empty());
 
   bool account_present = accounts_.count(account_id) > 0;
-  if (account_present && accounts_[account_id].last_auth_error.state() ==
-                             GoogleServiceAuthError::NONE) {
+  if (account_present &&
+      GetAuthError(account_id) == GoogleServiceAuthError::AuthErrorNone()) {
     // No need to update the account if it is already a known account and if
     // there is no auth error.
     return;
   }
 
-  accounts_[account_id].last_auth_error =
-      GoogleServiceAuthError::AuthErrorNone();
+  accounts_.insert(account_id);
+  UpdateAuthError(account_id, GoogleServiceAuthError::AuthErrorNone(),
+                  /*fire_auth_error_changed=*/false);
   FireAuthErrorChanged(account_id, GoogleServiceAuthError::AuthErrorNone());
   FireRefreshTokenAvailable(account_id);
 }
@@ -393,6 +362,7 @@
 
   if (accounts_.count(account_id) > 0) {
     accounts_.erase(account_id);
+    ClearAuthError(account_id);
     FireRefreshTokenRevoked(account_id);
   }
 }
diff --git a/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.cc b/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.cc
index 2742c8f..41eb373 100644
--- a/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.cc
+++ b/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.cc
@@ -18,7 +18,8 @@
         SigninClient* client,
         AccountTrackerService* account_tracker_service,
         crosapi::AccountManagerMojoService* account_manager_mojo_service,
-        bool is_regular_profile) {
+        bool is_regular_profile)
+    : ProfileOAuth2TokenServiceDelegate(/*use_backoff=*/true) {
   if (!network::TestNetworkConnectionTracker::HasInstance()) {
     owned_tracker_ = network::TestNetworkConnectionTracker::CreateInstance();
   }
@@ -60,8 +61,9 @@
 
 void TestProfileOAuth2TokenServiceDelegateChromeOS::UpdateAuthError(
     const CoreAccountId& account_id,
-    const GoogleServiceAuthError& error) {
-  delegate_->UpdateAuthError(account_id, error);
+    const GoogleServiceAuthError& error,
+    bool fire_auth_error_changed) {
+  delegate_->UpdateAuthError(account_id, error, fire_auth_error_changed);
 }
 
 GoogleServiceAuthError
@@ -75,6 +77,20 @@
   return delegate_->GetAccounts();
 }
 
+void TestProfileOAuth2TokenServiceDelegateChromeOS::ClearAuthError(
+    const absl::optional<CoreAccountId>& account_id) {
+  delegate_->ClearAuthError(account_id);
+}
+
+GoogleServiceAuthError
+TestProfileOAuth2TokenServiceDelegateChromeOS::BackOffError() const {
+  return delegate_->BackOffError();
+}
+
+void TestProfileOAuth2TokenServiceDelegateChromeOS::ResetBackOffEntry() {
+  delegate_->ResetBackOffEntry();
+}
+
 void TestProfileOAuth2TokenServiceDelegateChromeOS::LoadCredentials(
     const CoreAccountId& primary_account_id,
     bool is_syncing) {
diff --git a/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.h b/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.h
index a37f65f6..34d0305d 100644
--- a/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.h
+++ b/components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.h
@@ -46,7 +46,8 @@
       OAuth2AccessTokenConsumer* consumer) override;
   bool RefreshTokenIsAvailable(const CoreAccountId& account_id) const override;
   void UpdateAuthError(const CoreAccountId& account_id,
-                       const GoogleServiceAuthError& error) override;
+                       const GoogleServiceAuthError& error,
+                       bool fire_auth_error_changed) override;
   GoogleServiceAuthError GetAuthError(
       const CoreAccountId& account_id) const override;
   std::vector<CoreAccountId> GetAccounts() const override;
@@ -59,6 +60,9 @@
   void RevokeCredentials(const CoreAccountId& account_id) override;
   void RevokeAllCredentials() override;
   const net::BackoffEntry* BackoffEntry() const override;
+  void ClearAuthError(const absl::optional<CoreAccountId>& account_id) override;
+  GoogleServiceAuthError BackOffError() const override;
+  void ResetBackOffEntry() override;
 
   // |ProfileOAuth2TokenServiceObserver| implementation.
   void OnRefreshTokenAvailable(const CoreAccountId& account_id) override;
diff --git a/components/update_client/protocol_serializer.cc b/components/update_client/protocol_serializer.cc
index 408e99b..16bd70b 100644
--- a/components/update_client/protocol_serializer.cc
+++ b/components/update_client/protocol_serializer.cc
@@ -37,7 +37,9 @@
 
 // Returns the amount of physical memory in GB, rounded to the nearest GB.
 int GetPhysicalMemoryGB() {
-  return base::ClampRound(base::SysInfo::AmountOfPhysicalMemoryMB() / 1024.0f);
+  const double kOneGB = 1024 * 1024 * 1024;
+  const int64_t phys_mem = base::SysInfo::AmountOfPhysicalMemory();
+  return static_cast<int>(std::floor(0.5 + phys_mem / kOneGB));
 }
 
 std::string GetOSVersion() {
diff --git a/components/web_package/web_bundle_parser.cc b/components/web_package/web_bundle_parser.cc
index 814b588..c18752e 100644
--- a/components/web_package/web_bundle_parser.cc
+++ b/components/web_package/web_bundle_parser.cc
@@ -167,12 +167,6 @@
   if (url.has_ref() || url.has_username() || url.has_password())
     return GURL();
 
-  // For now, we allow only http:, https: and uuid-in-package: URLs in Web
-  // Bundles.
-  // TODO(crbug.com/966753): Revisit this once
-  // https://github.com/WICG/webpackage/issues/468 is resolved.
-  if (!url.SchemeIsHTTPOrHTTPS() && !IsValidUuidInPackageURL(url))
-    return GURL();
   return url;
 }
 
diff --git a/components/web_package/web_bundle_parser_unittest.cc b/components/web_package/web_bundle_parser_unittest.cc
index 0e5d7f6..160ee283 100644
--- a/components/web_package/web_bundle_parser_unittest.cc
+++ b/components/web_package/web_bundle_parser_unittest.cc
@@ -313,14 +313,26 @@
   ExpectFormatError(ParseUnsignedBundle(&data_source));
 }
 
-TEST_F(WebBundleParserTest, RequestURLHasBadScheme) {
+// TODO(crbug.com/966753): Revisit this once
+// https://github.com/WICG/webpackage/issues/468 is resolved.
+TEST_F(WebBundleParserTest, RequestURLHasNonStandardScheme) {
   WebBundleBuilder builder;
-  builder.AddExchange("file:///tmp/foo",
+  builder.AddExchange("foo://bar",
                       {{":status", "200"}, {"content-type", "text/plain"}},
                       "payload");
   TestDataSource data_source(builder.CreateBundle());
 
-  ExpectFormatError(ParseUnsignedBundle(&data_source));
+  ASSERT_TRUE(ParseUnsignedBundle(&data_source).first);
+}
+
+TEST_F(WebBundleParserTest, RequestURLHasIsolatedAppScheme) {
+  WebBundleBuilder builder;
+  builder.AddExchange("isolated-app://foo",
+                      {{":status", "200"}, {"content-type", "text/plain"}},
+                      "payload");
+  TestDataSource data_source(builder.CreateBundle());
+
+  ASSERT_TRUE(ParseUnsignedBundle(&data_source).first);
 }
 
 TEST_F(WebBundleParserTest, RequestURLHasCredentials) {
@@ -359,17 +371,6 @@
   ASSERT_TRUE(location);
 }
 
-TEST_F(WebBundleParserTest, RequestURLIsInvalidUuidInPackage) {
-  const char uuid_in_package[] = "uuid-in-package:invalid";
-  WebBundleBuilder builder;
-  builder.AddExchange(uuid_in_package,
-                      {{":status", "200"}, {"content-type", "text/plain"}},
-                      "payload");
-  TestDataSource data_source(builder.CreateBundle());
-
-  ExpectFormatError(ParseUnsignedBundle(&data_source));
-}
-
 TEST_F(WebBundleParserTest, NoStatusInResponseHeaders) {
   WebBundleBuilder builder;
   builder.AddExchange("https://test.example.com/",
diff --git a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc
index 21e8751..de7c2e7 100644
--- a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc
+++ b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc
@@ -5,11 +5,16 @@
 #include "components/webapps/browser/android/installable/installable_ambient_badge_message_controller.h"
 
 #include "base/bind.h"
+#include "base/containers/lru_cache.h"
+#include "base/no_destructor.h"
 #include "components/messages/android/message_dispatcher_bridge.h"
+#include "components/messages/android/throttler/domain_session_throttler.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/url_formatter/elide_url.h"
 #include "components/webapps/browser/android/installable/installable_ambient_badge_client.h"
 #include "components/webapps/browser/android/webapps_icon_utils.h"
+#include "components/webapps/browser/features.h"
+#include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace webapps {
@@ -35,7 +40,12 @@
     const bool is_primary_icon_maskable,
     const GURL& start_url) {
   DCHECK(!message_);
+  if (!GetThrottler()->ShouldShow(
+          web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin())) {
+    return;
+  }
 
+  save_origin_ = web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
   message_ = std::make_unique<messages::MessageWrapper>(
       messages::MessageIdentifier::INSTALLABLE_AMBIENT_BADGE,
       base::BindOnce(
@@ -84,6 +94,17 @@
   if (dismiss_reason == messages::DismissReason::GESTURE) {
     client_->BadgeDismissed();
   }
+  if (dismiss_reason != messages::DismissReason::PRIMARY_ACTION) {
+    GetThrottler()->AddStrike(save_origin_);
+  }
+}
+
+// static
+messages::DomainSessionThrottler*
+InstallableAmbientBadgeMessageController::GetThrottler() {
+  static messages::DomainSessionThrottler instance(
+      features::kInstallableAmbientBadgeMessage_ThrottleDomainsCapacity.Get());
+  return &instance;
 }
 
 }  // namespace webapps
diff --git a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.h b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.h
index c4647dc..180ac9e9 100644
--- a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.h
+++ b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.h
@@ -11,8 +11,10 @@
 #include "base/memory/raw_ptr.h"
 #include "components/messages/android/message_enums.h"
 #include "components/messages/android/message_wrapper.h"
+#include "components/messages/android/throttler/domain_session_throttler.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "url/gurl.h"
+#include "url/origin.h"
 
 namespace content {
 class WebContents;
@@ -49,11 +51,14 @@
   void DismissMessage();
 
  private:
+  static messages::DomainSessionThrottler* GetThrottler();
+
   void HandleInstallButtonClicked();
   void HandleMessageDismissed(messages::DismissReason dismiss_reason);
 
   raw_ptr<InstallableAmbientBadgeClient> client_;
   std::unique_ptr<messages::MessageWrapper> message_;
+  url::Origin save_origin_;
 };
 
 }  // namespace webapps
diff --git a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller_unittest.cc b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller_unittest.cc
index 24cd89ff..086b6efa 100644
--- a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller_unittest.cc
+++ b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller_unittest.cc
@@ -38,6 +38,7 @@
 
   void EnqueueMessage();
   void EnqueueMessage(bool maskable);
+  void EnqueueMessageWithExpectNotCalled();
   void DismissMessage(bool expected);
 
   void TriggerActionClick();
@@ -98,6 +99,15 @@
                                      maskable, GURL("https://example.com/"));
 }
 
+void InstallableAmbientBadgeMessageControllerTest::
+    EnqueueMessageWithExpectNotCalled() {
+  EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage).Times(0);
+  test_icon.allocPixels(SkImageInfo::Make(100, 100, kRGBA_8888_SkColorType,
+                                          kUnpremul_SkAlphaType));
+  message_controller_.EnqueueMessage(web_contents(), kAppName, test_icon, false,
+                                     GURL("https://example.com/"));
+}
+
 void InstallableAmbientBadgeMessageControllerTest::DismissMessage(
     bool bridge_dismiss_call_expected) {
   if (bridge_dismiss_call_expected) {
@@ -183,4 +193,15 @@
   TriggerMessageDismissedWithGesture();
 }
 
+// Tests that when the user dismisses the message with a gesture, client's
+// BadgeDismissed method is called and the message is not enqueued
+// because of throttling.
+TEST_F(InstallableAmbientBadgeMessageControllerTest, Throttle) {
+  EnqueueMessage();
+  EXPECT_CALL(client_mock(), AddToHomescreenFromBadge).Times(0);
+  DismissMessage(true);
+  EnqueueMessageWithExpectNotCalled();
+  ASSERT_FALSE(message_controller()->IsMessageEnqueued());
+}
+
 }  // namespace webapps
diff --git a/components/webapps/browser/features.cc b/components/webapps/browser/features.cc
index fea6d53d..8014b879 100644
--- a/components/webapps/browser/features.cc
+++ b/components/webapps/browser/features.cc
@@ -21,6 +21,13 @@
 const base::Feature kInstallableAmbientBadgeMessage{
     "InstallableAmbientBadgeMessage", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// The capacity of cached domains which do not show message again if
+// users do not accept the message.
+extern const base::FeatureParam<int>
+    kInstallableAmbientBadgeMessage_ThrottleDomainsCapacity{
+        &kInstallableAmbientBadgeMessage,
+        "installable_ambient_badge_message_throttle_domains_capacity", 100};
+
 // Enables PWA Unique IDs for WebAPKs.
 const base::Feature kWebApkUniqueId{"WebApkUniqueId",
                                     base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/webapps/browser/features.h b/components/webapps/browser/features.h
index f16b413..5e9a8e0a 100644
--- a/components/webapps/browser/features.h
+++ b/components/webapps/browser/features.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_WEBAPPS_BROWSER_FEATURES_H_
 #define COMPONENTS_WEBAPPS_BROWSER_FEATURES_H_
 
+#include "base/metrics/field_trial_params.h"
 #include "build/build_config.h"
 
 namespace base {
@@ -18,6 +19,8 @@
 extern const base::Feature kAddToHomescreenMessaging;
 extern const base::Feature kInstallableAmbientBadgeInfoBar;
 extern const base::Feature kInstallableAmbientBadgeMessage;
+extern const base::FeatureParam<int>
+    kInstallableAmbientBadgeMessage_ThrottleDomainsCapacity;
 extern const base::Feature kWebApkUniqueId;
 #endif  // BUILDFLAG(IS_ANDROID)
 
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2Api.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2Api.java
index c540ee79..772d4d2 100644
--- a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2Api.java
+++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2Api.java
@@ -1040,11 +1040,6 @@
             }
             final int endPosition = addLengthToParcelPosition(header.second, parcel);
 
-            // The original version of this API returned only discoverable credentials, not usable
-            // for Secure Payment Confirmation. If the tags are missing, this is the default.
-            details.mIsDiscoverable = true;
-            details.mIsPayment = false;
-
             while (parcel.dataPosition() < endPosition) {
                 header = readHeader(parcel);
                 switch (header.first) {
@@ -1060,23 +1055,13 @@
                     case 4:
                         details.mCredentialId = parcel.createByteArray();
                         break;
-                    case 5:
-                        details.mIsDiscoverable = parcel.readInt() != 0;
-                        break;
-                    case 6:
-                        details.mIsPayment = parcel.readInt() != 0;
-                        break;
                     default:
                         // unknown tag. Skip over it.
                         parcel.setDataPosition(addLengthToParcelPosition(header.second, parcel));
                 }
             }
-            if (details.mCredentialId == null) {
-                throw new IllegalArgumentException();
-            }
-            if (details.mIsDiscoverable
-                    && (details.mUserName == null || details.mUserDisplayName == null
-                            || details.mUserId == null)) {
+            if (details.mUserName == null || details.mUserDisplayName == null
+                    || details.mUserId == null || details.mCredentialId == null) {
                 throw new IllegalArgumentException();
             }
             credentials.add(details);
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
index f633063c..ced62316 100644
--- a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
+++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
@@ -41,7 +41,6 @@
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -270,13 +269,7 @@
         if (mBrowserBridge == null) {
             mBrowserBridge = new WebAuthnBrowserBridge();
         }
-        List<WebAuthnCredentialDetails> discoverableCredentials = new ArrayList<>();
-        for (WebAuthnCredentialDetails credential : credentials) {
-            if (credential.mIsDiscoverable) {
-                discoverableCredentials.add(credential);
-            }
-        }
-        mBrowserBridge.onCredentialsDetailsListReceived(frameHost, discoverableCredentials,
+        mBrowserBridge.onCredentialsDetailsListReceived(frameHost, credentials,
                 (selectedCredentialId)
                         -> dispatchGetAssertionRequest(
                                 options, callerOriginString, clientDataHash, selectedCredentialId));
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnCredentialDetails.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnCredentialDetails.java
index 5e245d2..4850aa7 100644
--- a/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnCredentialDetails.java
+++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnCredentialDetails.java
@@ -29,15 +29,5 @@
      */
     public byte[] mCredentialId;
 
-    /**
-     * Whether the credential is discoverable.
-     */
-    public boolean mIsDiscoverable;
-
-    /**
-     * Whether the credential is enabled for Secure Payment Confirmation.
-     */
-    public boolean mIsPayment;
-
     public WebAuthnCredentialDetails() {}
 }
diff --git a/content/browser/accessibility/accessibility_action_browsertest.cc b/content/browser/accessibility/accessibility_action_browsertest.cc
index f621dbd..7b454fef8 100644
--- a/content/browser/accessibility/accessibility_action_browsertest.cc
+++ b/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/escape.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/test_timeouts.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "content/browser/accessibility/browser_accessibility.h"
@@ -21,6 +22,7 @@
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
 #include "net/base/data_url.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/accessibility/accessibility_switches.h"
@@ -924,6 +926,87 @@
                      "inner_doc.getElementById('2').focus();");
 }
 
+IN_PROC_BROWSER_TEST_F(AccessibilityActionBrowserTest,
+                       FocusLostOnDeletedNodeInInnerWebContents) {
+  EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
+
+  GURL url(
+      "data:text/html,"
+      "<button id='1'>1</button>"
+      "<iframe></iframe>");
+
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+  EnableAccessibilityForWebContents(shell()->web_contents());
+  // Make sure we have an initial accessibility tree before continuing the test
+  // setup, otherwise the wait for button 3 below seems to flake on linux.
+  WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(), "1");
+
+  RenderFrameHostImplWrapper child(ChildFrameAt(shell()->web_contents(), 0));
+  EXPECT_TRUE(child);
+
+  GURL inner_url(
+      "data:text/html,"
+      "<button id='2'>2</button>"
+      "<iframe id='iframe' srcdoc=\""
+      "<button id='3'>3</button>"
+      "\"></iframe>");
+  auto* inner_contents =
+      static_cast<WebContentsImpl*>(CreateAndAttachInnerContents(child.get()));
+  EnableAccessibilityForWebContents(inner_contents);
+
+  EXPECT_TRUE(NavigateToURL(inner_contents, inner_url));
+
+  RenderFrameHostImplWrapper inner_iframe(ChildFrameAt(inner_contents, 0));
+  EXPECT_TRUE(inner_iframe);
+
+  // We need to explicitly focus the inner web contents, it can't do so on its
+  // own.
+  inner_contents->FocusOwningWebContents(inner_iframe->GetRenderWidgetHost());
+
+  FrameFocusedObserver focus_observer(inner_iframe.get());
+  EXPECT_TRUE(ExecJs(inner_iframe.get(),
+                     "window.focus();"
+                     "document.getElementById('3').focus();"));
+  focus_observer.Wait();
+
+  // We now have an inner WebContents which has an iframe with a button, and
+  // that button has focus.
+  EXPECT_EQ(shell()->web_contents()->GetFocusedFrame(), inner_iframe.get());
+  // WaitForAccessibilityTreeToContainNodeWithName seems to flake when waiting
+  // for button 3, so we poll instead.
+  BrowserAccessibility* node_button_3 = FindNode(ax::mojom::Role::kButton, "3");
+  while (!node_button_3) {
+    base::RunLoop run_loop;
+    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+    run_loop.Run();
+
+    node_button_3 = FindNode(ax::mojom::Role::kButton, "3");
+  }
+  while (GetFocusedAccessibilityNodeInfo(shell()->web_contents()).id !=
+         node_button_3->GetId()) {
+    WaitForAccessibilityFocusChange();
+  }
+
+  // Now delete the iframe with the focused button.
+  EXPECT_TRUE(
+      ExecJs(inner_contents, "document.querySelector('iframe').remove();"));
+  EXPECT_TRUE(inner_iframe.WaitUntilRenderFrameDeleted());
+  ASSERT_FALSE(FindNode(ax::mojom::Role::kButton, "3"));
+
+  // No frame has focus now.
+  EXPECT_EQ(shell()->web_contents()->GetFocusedFrame(), nullptr);
+
+  // If nothing is focused, accessibility treats the top document as having
+  // focus.
+  auto root_document_id =
+      FindNode(ax::mojom::Role::kRootWebArea, "")->GetData().id;
+  while (GetFocusedAccessibilityNodeInfo(shell()->web_contents()).id !=
+         root_document_id) {
+    WaitForAccessibilityFocusChange();
+  }
+}
+
 // Action::kScrollToMakeVisible does not seem reliable on Android and we are
 // currently only using it for desktop screen readers.
 #if !BUILDFLAG(IS_ANDROID)
diff --git a/content/browser/devtools/protocol/emulation_handler.cc b/content/browser/devtools/protocol/emulation_handler.cc
index 8f2954e..c7d7f57 100644
--- a/content/browser/devtools/protocol/emulation_handler.cc
+++ b/content/browser/devtools/protocol/emulation_handler.cc
@@ -30,6 +30,9 @@
 
 namespace {
 
+constexpr char kCommandIsOnlyAvailableAtTopTarget[] =
+    "Command can only be executed on top-level targets";
+
 display::mojom::ScreenOrientation WebScreenOrientationTypeFromString(
     const std::string& type) {
   if (type == Emulation::ScreenOrientation::TypeEnum::PortraitPrimary)
@@ -177,6 +180,12 @@
 Response EmulationHandler::SetEmitTouchEventsForMouse(
     bool enabled,
     Maybe<std::string> configuration) {
+  if (!host_)
+    return Response::InternalError();
+
+  if (host_->GetParentOrOuterDocument())
+    return Response::ServerError(kCommandIsOnlyAvailableAtTopTarget);
+
   touch_emulation_enabled_ = enabled;
   touch_emulation_configuration_ = configuration.fromMaybe("");
   UpdateTouchEventEmulationState();
@@ -545,12 +554,10 @@
 }
 
 void EmulationHandler::UpdateTouchEventEmulationState() {
-  if (!host_)
-    return;
+  DCHECK(host_);
   // We only have a single TouchEmulator for all frames, so let the main frame's
   // EmulationHandler enable/disable it.
-  if (!host_->is_main_frame())
-    return;
+  DCHECK(!host_->GetParentOrOuterDocument());
 
   if (touch_emulation_enabled_) {
     if (auto* touch_emulator =
diff --git a/content/browser/net/network_service_memory_cache_browsertest.cc b/content/browser/net/network_service_memory_cache_browsertest.cc
new file mode 100644
index 0000000..554aaeb
--- /dev/null
+++ b/content/browser/net/network_service_memory_cache_browsertest.cc
@@ -0,0 +1,188 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "content/test/resource_load_observer.h"
+#include "net/base/features.h"
+#include "net/base/network_isolation_key.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/default_handlers.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "services/network/public/cpp/features.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+constexpr const char kTestPagePath[] = "/empty.html";
+constexpr const char kCrossOrignIsolatedPath[] = "/cross-origin-isolated.html";
+
+// Cacheable, no Access-Control-Allow-Origin / Cross-Origin-Resource-Policy.
+constexpr const char kCacheableIsolatedImagePath[] = "/cacheable-isolated.jpg";
+
+// Cacheable, Access-Control-Allow-Origin is "*".
+constexpr const char kCacheableImagePath[] = "/cacheable.svg";
+
+// Cache-Control is "no-store".
+constexpr const char kNoStoreImagePath[] = "/nostore.jpg";
+
+}  // namespace
+
+class NetworkServiceMemoryCacheBrowserTest : public ContentBrowserTest {
+ public:
+  NetworkServiceMemoryCacheBrowserTest() {
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/{network::features::kNetworkServiceMemoryCache,
+                              net::features::kSplitCacheByNetworkIsolationKey},
+        /*disabled_features=*/{});
+  }
+
+  void SetUpOnMainThread() override {
+    // Setup the server to allow serving separate sites.
+    host_resolver()->AddRule("*", "127.0.0.1");
+    ASSERT_TRUE(embedded_test_server()->Start());
+
+    // Setup a cross origin server.
+    cross_origin_server_.ServeFilesFromSourceDirectory(GetTestDataFilePath());
+    net::test_server::RegisterDefaultHandlers(&cross_origin_server_);
+    ASSERT_TRUE(cross_origin_server_.Start());
+  }
+
+  net::EmbeddedTestServer& cross_origin_server() {
+    return cross_origin_server_;
+  }
+
+  bool FetchResource(const GURL& url) {
+    ResourceLoadObserver observer(shell());
+    EvalJsResult result = EvalJs(shell(), JsReplace(R"(
+      fetch($1)
+        .then(_ => true)
+        .catch(_ => false);
+    )",
+                                                    url));
+    if (!result.ExtractBool())
+      return false;
+    observer.WaitForResourceCompletion(url);
+    return true;
+  }
+
+  bool LoadImageViaImgTag(const GURL& url) {
+    ResourceLoadObserver observer(shell());
+    EvalJsResult result = EvalJs(shell(), JsReplace(R"(
+      new Promise(resolve => {
+        const img = document.createElement("img");
+        img.src = $1;
+        img.onerror = () => resolve(false);
+        img.onload = () => resolve(true);
+        document.body.appendChild(img);
+      });
+    )",
+                                                    url));
+    if (!result.ExtractBool())
+      return false;
+    observer.WaitForResourceCompletion(url);
+    return true;
+  }
+
+  bool ResourceIsInMemoryCache(const GURL& resource_url) {
+    ResourceLoadObserver observer(shell());
+    if (!FetchResource(resource_url))
+      return false;
+    observer.WaitForResourceCompletion(resource_url);
+    return (*observer.GetResource(resource_url))
+        ->was_in_network_service_memory_cache;
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  net::EmbeddedTestServer cross_origin_server_;
+};
+
+IN_PROC_BROWSER_TEST_F(NetworkServiceMemoryCacheBrowserTest, Basic) {
+  const GURL resource_url =
+      embedded_test_server()->GetURL(kCacheableIsolatedImagePath);
+
+  // Fetch a cacheable resource to store it in the in-memory cache.
+  EXPECT_TRUE(
+      NavigateToURL(shell(), embedded_test_server()->GetURL(kTestPagePath)));
+  ASSERT_TRUE(FetchResource(resource_url));
+
+  ASSERT_TRUE(ResourceIsInMemoryCache(resource_url));
+}
+
+IN_PROC_BROWSER_TEST_F(NetworkServiceMemoryCacheBrowserTest, NoStore) {
+  const GURL resource_url = embedded_test_server()->GetURL(kNoStoreImagePath);
+
+  EXPECT_TRUE(
+      NavigateToURL(shell(), embedded_test_server()->GetURL(kTestPagePath)));
+  ASSERT_TRUE(FetchResource(resource_url));
+  ASSERT_FALSE(ResourceIsInMemoryCache(resource_url));
+}
+
+IN_PROC_BROWSER_TEST_F(NetworkServiceMemoryCacheBrowserTest, CorsBlocked) {
+  const GURL resource_url =
+      cross_origin_server().GetURL(kCacheableIsolatedImagePath);
+
+  // Navigate to a cross site and fetch a resource to store the response in the
+  // in-memory cache.
+  EXPECT_TRUE(
+      NavigateToURL(shell(), cross_origin_server().GetURL(kTestPagePath)));
+  ASSERT_TRUE(FetchResource(resource_url));
+  ASSERT_TRUE(ResourceIsInMemoryCache(resource_url));
+
+  // Navigate to a test page and try to fetch the cross origin resource. It
+  // should be blocked by CORS checks.
+  EXPECT_TRUE(
+      NavigateToURL(shell(), embedded_test_server()->GetURL(kTestPagePath)));
+  ASSERT_FALSE(FetchResource(resource_url));
+}
+
+IN_PROC_BROWSER_TEST_F(NetworkServiceMemoryCacheBrowserTest, CorpBlocked) {
+  const GURL resource_url =
+      cross_origin_server().GetURL(kCacheableIsolatedImagePath);
+
+  // Store a cross-site image in the in-memory cache. The response doesn't have
+  // Cross-Origin-Resource-Policy.
+  EXPECT_TRUE(
+      NavigateToURL(shell(), cross_origin_server().GetURL(kTestPagePath)));
+  ASSERT_TRUE(FetchResource(resource_url));
+  ASSERT_TRUE(ResourceIsInMemoryCache(resource_url));
+
+  // Try to load the image from a cross origin isolated page. It should be
+  // blocked by CORP checks.
+  EXPECT_TRUE(NavigateToURL(
+      shell(), embedded_test_server()->GetURL(kCrossOrignIsolatedPath)));
+  ASSERT_FALSE(LoadImageViaImgTag(resource_url));
+}
+
+IN_PROC_BROWSER_TEST_F(NetworkServiceMemoryCacheBrowserTest, SplitCache) {
+  const GURL test_page1 =
+      embedded_test_server()->GetURL("a.test", kTestPagePath);
+  const GURL test_page2 = cross_origin_server().GetURL("b.test", kTestPagePath);
+  const GURL resource_url =
+      embedded_test_server()->GetURL("x.test", kCacheableImagePath);
+
+  // Fetch an image on a site. Cached response will be available for the same
+  // site.
+  EXPECT_TRUE(NavigateToURL(shell(), test_page1));
+  ASSERT_TRUE(FetchResource(resource_url));
+  ASSERT_TRUE(ResourceIsInMemoryCache(resource_url));
+
+  // Navigate to a different site and fetch the same image. There should be no
+  // cached response yet.
+  EXPECT_TRUE(NavigateToURL(shell(), test_page2));
+  ASSERT_FALSE(ResourceIsInMemoryCache(resource_url));
+}
+
+}  // namespace content
diff --git a/content/browser/renderer_host/pending_beacon_host.cc b/content/browser/renderer_host/pending_beacon_host.cc
index c3ad23f..af0741b 100644
--- a/content/browser/renderer_host/pending_beacon_host.cc
+++ b/content/browser/renderer_host/pending_beacon_host.cc
@@ -4,8 +4,12 @@
 
 #include "content/browser/renderer_host/pending_beacon_host.h"
 
+#include "base/memory/scoped_refptr.h"
 #include "content/browser/renderer_host/pending_beacon_service.h"
-#include "net/base/url_util.h"
+#include "content/public/browser/render_frame_host.h"
+#include "services/network/public/cpp/cors/cors.h"
+#include "services/network/public/cpp/data_element.h"
+#include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 namespace content {
@@ -17,7 +21,10 @@
     : DocumentUserData<PendingBeaconHost>(rfh),
       receiver_(this),
       shared_url_factory_(std::move(shared_url_factory)),
-      service_(service) {}
+      service_(service) {
+  DCHECK(shared_url_factory_);
+  DCHECK(service_);
+}
 
 void PendingBeaconHost::CreateBeacon(
     mojo::PendingReceiver<blink::mojom::PendingBeacon> receiver,
@@ -76,23 +83,54 @@
       beacon_host_(beacon_host),
       url_(url),
       method_(method),
-      timeout_(timeout) {}
+      timeout_(timeout) {
+  DCHECK(beacon_host_);
+}
 
 Beacon::~Beacon() = default;
 
-void Beacon::SetData(const std::string& data) {
-  beacon_data_ = data;
+void Beacon::SetRequestData(
+    scoped_refptr<network::ResourceRequestBody> request_body,
+    const std::string& content_type) {
+  if (method_ != blink::mojom::BeaconMethod::kPost) {
+    mojo::ReportBadMessage("Unexpected BeaconMethod from renderer");
+    return;
+  }
+  if (!content_type.empty() &&
+      !network::cors::IsCorsSafelistedContentType(content_type)) {
+    mojo::ReportBadMessage("Unexpected Content-Type from renderer");
+    return;
+  }
+
+  content_type_ = content_type;
+
+  // Move all DataElement into `request_elements_`.
+  if (!request_body->elements_mutable()) {
+    return;
+  }
+  request_elements_ = std::move(*request_body->elements_mutable());
 }
 
 void Beacon::SendNow() {
   beacon_host_->SendBeacon(this);
 }
 
-const GURL Beacon::GenerateRequestURL() const {
+const std::unique_ptr<network::ResourceRequest>
+Beacon::GenerateResourceRequest() const {
+  auto request = std::make_unique<network::ResourceRequest>();
   if (method_ == blink::mojom::BeaconMethod::kGet) {
-    return net::AppendQueryParameter(url_, "data", beacon_data_);
+    request->method = net::HttpRequestHeaders::kGetMethod;
+    request->url = url_;
+  } else {
+    request->method = net::HttpRequestHeaders::kPostMethod;
+    request->url = url_;
+    request->keepalive = true;
+    if (!content_type_.empty()) {
+      request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
+                                 content_type_);
+    }
   }
-  return url_;
-}
+  return request;
+};
 
 }  // namespace content
diff --git a/content/browser/renderer_host/pending_beacon_host.h b/content/browser/renderer_host/pending_beacon_host.h
index 81b8131..16279ae 100644
--- a/content/browser/renderer_host/pending_beacon_host.h
+++ b/content/browser/renderer_host/pending_beacon_host.h
@@ -7,7 +7,6 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
-#include "base/unguessable_token.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/document_user_data.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -15,6 +14,10 @@
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "third_party/blink/public/mojom/frame/pending_beacon.mojom.h"
 
+namespace network {
+class DataElement;
+}  // namespace network
+
 namespace content {
 
 class Beacon;
@@ -103,17 +106,32 @@
 
   // Deletes this beacon from its containing PendingBeaconHost.
   void Deactivate() override;
-  void SetData(const std::string& data) override;
+
+  // Sets request data for the pending beacon.
+  void SetRequestData(scoped_refptr<network::ResourceRequestBody> request_body,
+                      const std::string& content_type) override;
+
   // Sends the beacon immediately, and deletes it from its containing
   // PendingBeaconHost.
   void SendNow() override;
 
-  // Returns the beacon's url to send request with.
-  // * If `method_` is GET, the url is constructed from `url_` and
-  //   a query string data=`beacon_data_`, where the latter will be encoded by
-  //   application/x-www-form-urlencoded serializer.
-  // * If `method_` is POST, the url is from `url_`.
-  const GURL GenerateRequestURL() const;
+  // Creates a request based on the beacon's url and data.
+  // * If `method_` is GET, the request url is constructed from `url_`.
+  // * If `method_` is POST, the request url is from `url_`, and the request
+  //   content is from `request_body_` and `content_type_`.
+  const std::unique_ptr<network::ResourceRequest> GenerateResourceRequest()
+      const;
+
+  const std::string& content_type() const {
+    DCHECK(method_ != blink::mojom::BeaconMethod::kGet ||
+           content_type_.empty());
+    return content_type_;
+  }
+  const std::vector<network::DataElement>& request_elements() const {
+    DCHECK(method_ != blink::mojom::BeaconMethod::kGet ||
+           request_elements_.empty());
+    return request_elements_;
+  }
 
  private:
   mojo::Receiver<blink::mojom::PendingBeacon> receiver_;
@@ -125,10 +143,12 @@
   [[maybe_unused]] const blink::mojom::BeaconMethod method_;
   [[maybe_unused]] const base::TimeDelta timeout_;
 
-  // A string containing the bytes for the data of the beacon. This will be
-  // either used as the body of the beacon request for POST beacons, or
-  // appended to the URL for GET beacons.
-  std::string beacon_data_;
+  // The request content type for POST beacon. If `method_` is GET, this field
+  // should not be used.
+  std::string content_type_;
+  // The beacon data represented as data elements. If `method_` is GET, this
+  // field should not be used.
+  std::vector<network::DataElement> request_elements_;
 };
 
 }  // namespace content
diff --git a/content/browser/renderer_host/pending_beacon_host_unittest.cc b/content/browser/renderer_host/pending_beacon_host_unittest.cc
index f5d5148b..7fc3705 100644
--- a/content/browser/renderer_host/pending_beacon_host_unittest.cc
+++ b/content/browser/renderer_host/pending_beacon_host_unittest.cc
@@ -19,15 +19,16 @@
 
 namespace content {
 
-class PendingBeaconHostTest : public RenderViewHostTestHarness,
-                              public testing::WithParamInterface<std::string> {
+class PendingBeaconHostTestBase
+    : public RenderViewHostTestHarness,
+      public testing::WithParamInterface<std::string> {
  public:
-  PendingBeaconHostTest(const PendingBeaconHostTest&) = delete;
-  PendingBeaconHostTest& operator=(const PendingBeaconHostTest&) = delete;
-  PendingBeaconHostTest() = default;
+  PendingBeaconHostTestBase(const PendingBeaconHostTestBase&) = delete;
+  PendingBeaconHostTestBase& operator=(const PendingBeaconHostTestBase&) =
+      delete;
+  PendingBeaconHostTestBase() = default;
 
-  void SetUp() override { RenderViewHostTestHarness::SetUp(); }
-
+ protected:
   // Creates a new instance of PendingBeaconHost, which uses a new instance of
   // TestURLLoaderFactory stored at `test_url_loader_factory_`.
   // The network requests made by the returned PendingBeaconHost will go through
@@ -42,6 +43,18 @@
     return PendingBeaconHost::GetForCurrentDocument(main_rfh());
   }
 
+  static blink::mojom::BeaconMethod ToBeaconMethod(const std::string& method) {
+    if (method == net::HttpRequestHeaders::kGetMethod) {
+      return blink::mojom::BeaconMethod::kGet;
+    }
+    return blink::mojom::BeaconMethod::kPost;
+  }
+
+  std::unique_ptr<network::TestURLLoaderFactory> test_url_loader_factory_;
+};
+
+class PendingBeaconHostTest : public PendingBeaconHostTestBase {
+ protected:
   // Registers a callback to verify if the most-recent network request's content
   // matches the given `method` and `url`.
   void SetExpectNetworkRequest(const base::Location& location,
@@ -51,6 +64,9 @@
         [location, method, url](const network::ResourceRequest& request) {
           EXPECT_EQ(request.method, method) << location.ToString();
           EXPECT_EQ(request.url, url) << location.ToString();
+          if (method == net::HttpRequestHeaders::kPostMethod) {
+            EXPECT_TRUE(request.keepalive) << location.ToString();
+          }
         }));
   }
 
@@ -61,24 +77,14 @@
     EXPECT_EQ(test_url_loader_factory_->NumPending(), expected)
         << location.ToString();
   }
-
-  static blink::mojom::BeaconMethod ToBeaconMethod(const std::string& method) {
-    if (method == net::HttpRequestHeaders::kGetMethod) {
-      return blink::mojom::BeaconMethod::kGet;
-    }
-    return blink::mojom::BeaconMethod::kPost;
-  }
-
- private:
-  std::unique_ptr<network::TestURLLoaderFactory> test_url_loader_factory_;
 };
 
-// TODO(crbug.com/1293679): Add test for POST.
 INSTANTIATE_TEST_SUITE_P(
     All,
     PendingBeaconHostTest,
     testing::ValuesIn<std::vector<std::string>>(
-        {net::HttpRequestHeaders::kGetMethod}),
+        {net::HttpRequestHeaders::kGetMethod,
+         net::HttpRequestHeaders::kPostMethod}),
     [](const testing::TestParamInfo<PendingBeaconHostTest::ParamType>& info) {
       return info.param;
     });
@@ -181,4 +187,69 @@
   ExpectTotalNetworkRequests(FROM_HERE, total - 1);
 }
 
+class BeaconTest : public PendingBeaconHostTestBase {
+ protected:
+  void TearDown() override {
+    host_ = nullptr;
+    PendingBeaconHostTestBase::TearDown();
+  }
+
+  mojo::Remote<blink::mojom::PendingBeacon> CreateBeaconAndPassRemote(
+      const std::string& method) {
+    const base::TimeDelta timeout = base::Milliseconds(0);
+    const auto url = GURL("/test_send_beacon");
+    host_ = CreateHost();
+    mojo::Remote<blink::mojom::PendingBeacon> remote;
+    auto receiver = remote.BindNewPipeAndPassReceiver();
+    host_->CreateBeacon(std::move(receiver), url, ToBeaconMethod(method),
+                        timeout);
+    return remote;
+  }
+
+  scoped_refptr<network::ResourceRequestBody> CreateRequestBody(
+      const std::string& data) {
+    return network::ResourceRequestBody::CreateFromBytes(data.data(),
+                                                         data.size());
+  }
+
+ private:
+  // Owned by `main_rfh()`.
+  PendingBeaconHost* host_;
+};
+
+TEST_F(BeaconTest, AttemptToSetDataForGetBeaconAndTerminated) {
+  auto beacon_remote =
+      CreateBeaconAndPassRemote(net::HttpRequestHeaders::kGetMethod);
+  // Intercepts Mojo bad-message error.
+  std::string bad_message;
+  mojo::SetDefaultProcessErrorHandler(
+      base::BindLambdaForTesting([&](const std::string& error) {
+        ASSERT_TRUE(bad_message.empty());
+        bad_message = error;
+      }));
+
+  beacon_remote->SetRequestData(CreateRequestBody("data"), "");
+  beacon_remote.FlushForTesting();
+
+  EXPECT_EQ(bad_message, "Unexpected BeaconMethod from renderer");
+}
+
+TEST_F(BeaconTest, AttemptToSetUnsafeContentTypeAndTerminated) {
+  auto beacon_remote =
+      CreateBeaconAndPassRemote(net::HttpRequestHeaders::kPostMethod);
+  // Intercepts Mojo bad-message error.
+  std::string bad_message;
+  mojo::SetDefaultProcessErrorHandler(
+      base::BindLambdaForTesting([&](const std::string& error) {
+        ASSERT_TRUE(bad_message.empty());
+        bad_message = error;
+      }));
+
+  beacon_remote->SetRequestData(CreateRequestBody("data"),
+                                "application/unsafe");
+  beacon_remote.FlushForTesting();
+
+  EXPECT_EQ(bad_message, "Unexpected Content-Type from renderer");
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/pending_beacon_service.cc b/content/browser/renderer_host/pending_beacon_service.cc
index 043f09c..96baec8 100644
--- a/content/browser/renderer_host/pending_beacon_service.cc
+++ b/content/browser/renderer_host/pending_beacon_service.cc
@@ -4,13 +4,11 @@
 
 #include "content/browser/renderer_host/pending_beacon_service.h"
 #include "base/bind.h"
-#include "base/time/time.h"
 #include "content/browser/renderer_host/pending_beacon_host.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/data_element.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/simple_url_loader.h"
-#include "third_party/blink/public/mojom/frame/pending_beacon.mojom.h"
 
 constexpr net::NetworkTrafficAnnotationTag kPendingBeaconNetworkTag =
     net::DefineNetworkTrafficAnnotation("pending_beacon_api",
@@ -56,11 +54,18 @@
     const std::vector<std::unique_ptr<Beacon>>& beacons,
     network::SharedURLLoaderFactory* shared_url_loader_factory) {
   for (const auto& beacon : beacons) {
-    auto resource_request = std::make_unique<network::ResourceRequest>();
-    resource_request->url = beacon->GenerateRequestURL();
+    auto resource_request = beacon->GenerateResourceRequest();
     std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
         network::SimpleURLLoader::Create(std::move(resource_request),
                                          kPendingBeaconNetworkTag);
+    for (const auto& element : beacon->request_elements()) {
+      if (element.type() == network::mojom::DataElementDataView::Tag::kBytes) {
+        simple_url_loader->AttachStringForUpload(
+            std::string(
+                element.As<network::DataElementBytes>().AsStringPiece()),
+            beacon->content_type());
+      }
+    }
     network::SimpleURLLoader* simple_url_loader_ptr = simple_url_loader.get();
 
     // Send out the |beacon|.
diff --git a/content/browser/renderer_host/render_frame_host_delegate.cc b/content/browser/renderer_host/render_frame_host_delegate.cc
index faebf4a9..33a41ab 100644
--- a/content/browser/renderer_host/render_frame_host_delegate.cc
+++ b/content/browser/renderer_host/render_frame_host_delegate.cc
@@ -98,8 +98,7 @@
   return false;
 }
 
-RenderFrameHostImpl*
-RenderFrameHostDelegate::GetFocusedFrameIncludingInnerFrameTrees() {
+RenderFrameHostImpl* RenderFrameHostDelegate::GetFocusedFrame() {
   return nullptr;
 }
 
diff --git a/content/browser/renderer_host/render_frame_host_delegate.h b/content/browser/renderer_host/render_frame_host_delegate.h
index 63c82977..009580f7 100644
--- a/content/browser/renderer_host/render_frame_host_delegate.h
+++ b/content/browser/renderer_host/render_frame_host_delegate.h
@@ -362,9 +362,7 @@
   virtual bool IsInnerWebContentsForGuest();
 
   // Returns the focused frame if it exists, potentially in an inner frame tree.
-  // If an inner frame tree has focus, but doesn't have a focused frame, returns
-  // the inner frame tree's main frame. Otherwise returns nullptr.
-  virtual RenderFrameHostImpl* GetFocusedFrameIncludingInnerFrameTrees();
+  virtual RenderFrameHostImpl* GetFocusedFrame();
 
   // Called by when |source_rfh| advances focus to a RenderFrameProxyHost.
   virtual void OnAdvanceFocus(RenderFrameHostImpl* source_rfh) {}
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 2f9446b..41f51aef 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1018,10 +1018,10 @@
     case features::SubframeShutdownDelayType::kMemoryBased: {
       // See subframe-reuse design doc for more detail on these values.
       // docs.google.com/document/d/1x_h4Gg4ForILEj8A4rMBX6d84uHWyQ9RSXmGVqMlBTk
-      static constexpr uint64_t kHighMemoryThreshold = 8'000'000'000;
-      static constexpr uint64_t kMaxMemoryThreshold = 16'000'000'000;
+      static constexpr int64_t kHighMemoryThreshold = 8000000000;
+      static constexpr int64_t kMaxMemoryThreshold = 16000000000;
 
-      const uint64_t available_memory =
+      const int64_t available_memory =
           base::SysInfo::AmountOfAvailablePhysicalMemory();
       if (available_memory <= kHighMemoryThreshold)
         return kShortDelay;
@@ -1030,7 +1030,7 @@
 
       // Scale delay linearly based on where |available_memory| lies between
       // |kHighMemoryThreshold| and |kMaxMemoryThreshold|.
-      const uint64_t available_memory_factor =
+      const int64_t available_memory_factor =
           (available_memory - kHighMemoryThreshold) /
           (kMaxMemoryThreshold - kHighMemoryThreshold);
       return kShortDelay + (kLongDelay - kShortDelay) * available_memory_factor;
@@ -10034,11 +10034,14 @@
   if (!is_main_frame())
     return ui::AXTreeIDUnknown();
 
-  auto* focused_frame = static_cast<RenderFrameHostImpl*>(
-      delegate_->GetFocusedFrameIncludingInnerFrameTrees());
+  RenderFrameHostImpl* focused_frame = delegate_->GetFocusedFrame();
   if (focused_frame)
     return focused_frame->GetAXTreeID();
 
+  // It's possible for there to be no focused RenderFrameHost (e.g. the frame
+  // that had focus was destroyed). Note however, that this doesn't mean that
+  // keyboard events are ignored; they'd be sent by default to the root
+  // RenderWidgetHost.
   return ui::AXTreeIDUnknown();
 }
 
diff --git a/content/browser/service_worker/service_worker_container_host.h b/content/browser/service_worker/service_worker_container_host.h
index 604f4de..290de33 100644
--- a/content/browser/service_worker/service_worker_container_host.h
+++ b/content/browser/service_worker/service_worker_container_host.h
@@ -359,8 +359,9 @@
   // is_response_committed() is true, the URL should no longer change.
   const GURL& url() const { return url_; }
 
-  // Representing the first party for cookies, if any, for this context. See
-  // URLRequest::site_for_cookies() for details.
+  // This returns the first party for cookies as derived from the storage key.
+  // For information on how this may differ from the SiteForCookies in the frame
+  // context please see the comments above StorageKey::ToNetSiteForCookies.
   // For service worker execution contexts, site_for_cookies() always
   // corresponds to the service worker script URL.
   const net::SiteForCookies site_for_cookies() const {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 2cd6806..8a0b6e4 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4049,7 +4049,16 @@
       base::WeakPtr<WebContentsImpl> weak_new_contents =
           new_contents_impl->weak_factory_.GetWeakPtr();
 
-      gfx::Rect initial_rect;  // Report an empty initial rect.
+      gfx::Rect initial_rect;
+      if (params.features->has_width)
+        initial_rect.set_width(params.features->width);
+      if (params.features->has_height)
+        initial_rect.set_height(params.features->height);
+      if (params.features->has_x)
+        initial_rect.set_x(params.features->x);
+      if (params.features->has_y)
+        initial_rect.set_y(params.features->y);
+
       delegate_->AddNewContents(this, std::move(new_contents),
                                 params.target_url, params.disposition,
                                 initial_rect, has_user_gesture, &was_blocked);
@@ -7860,25 +7869,6 @@
   fullscreen_block.RunAndReset();
 }
 
-RenderFrameHostImpl*
-WebContentsImpl::GetFocusedFrameIncludingInnerFrameTrees() {
-  OPTIONAL_TRACE_EVENT0(
-      "content", "WebContentsImpl::GetFocusedFrameIncludingInnerFrameTrees");
-  auto* focused_frame = GetFocusedFrame();
-  if (focused_frame) {
-    return focused_frame;
-  }
-
-  // If there is no focused frame in the primary frame tree, we need to return
-  // null. If an inner frame tree has focus, but doesn't have a focused frame,
-  // treat its main frame as having focus.
-  if (GetFocusedFrameTree() != &primary_frame_tree_) {
-    return GetFocusedFrameTree()->root()->current_frame_host();
-  }
-
-  return nullptr;
-}
-
 void WebContentsImpl::OnAdvanceFocus(RenderFrameHostImpl* source_rfh) {
   OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnAdvanceFocus",
                         "render_frame_host", source_rfh);
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 2ee5a7a78..4f96c01 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -661,7 +661,6 @@
       const GURL& url) override;
   void SetFocusedFrame(FrameTreeNode* node, SiteInstanceGroup* source) override;
   void DidCallFocus() override;
-  RenderFrameHostImpl* GetFocusedFrameIncludingInnerFrameTrees() override;
   void OnFocusedElementChangedInFrame(
       RenderFrameHostImpl* frame,
       const gfx::Rect& bounds_in_root_view,
diff --git a/content/browser/web_package/web_bundle_file_browsertest.cc b/content/browser/web_package/web_bundle_file_browsertest.cc
index c7f37120..77f21e9 100644
--- a/content/browser/web_package/web_bundle_file_browsertest.cc
+++ b/content/browser/web_package/web_bundle_file_browsertest.cc
@@ -142,6 +142,42 @@
 
 // TODO(https://crbug.com/1225178): flaky
 #if BUILDFLAG(IS_LINUX)
+#define MAYBE_InvalidExchangeUrl DISABLED_InvalidExchangeUrl
+#else
+#define MAYBE_InvalidExchangeUrl InvalidExchangeUrl
+#endif
+IN_PROC_BROWSER_TEST_P(WebBundleFileBrowserTest, MAYBE_InvalidExchangeUrl) {
+  const GURL test_data_url =
+      GetTestUrlForFile(web_bundle_browsertest_utils::GetTestDataPath(
+          "foo_base_url_bundle_b2.wbn"));
+
+  std::string console_message = web_bundle_browsertest_utils::
+      ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
+                                                     test_data_url);
+
+  EXPECT_EQ(web_bundle_utils::kInvalidExchangeUrlErrorMessage, console_message);
+}
+
+// TODO(https://crbug.com/1225178): flaky
+#if BUILDFLAG(IS_LINUX)
+#define MAYBE_InvalidPrimaryUrl DISABLED_InvalidPrimaryUrl
+#else
+#define MAYBE_InvalidPrimaryUrl InvalidPrimaryUrl
+#endif
+IN_PROC_BROWSER_TEST_P(WebBundleFileBrowserTest, MAYBE_InvalidPrimaryUrl) {
+  const GURL test_data_url =
+      GetTestUrlForFile(web_bundle_browsertest_utils::GetTestDataPath(
+          "foo_primary_url_bundle_b2.wbn"));
+
+  std::string console_message = web_bundle_browsertest_utils::
+      ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
+                                                     test_data_url);
+
+  EXPECT_EQ(web_bundle_utils::kInvalidPrimaryUrlErrorMessage, console_message);
+}
+
+// TODO(https://crbug.com/1225178): flaky
+#if BUILDFLAG(IS_LINUX)
 #define MAYBE_ResponseParseErrorInMainResource \
   DISABLED_ResponseParseErrorInMainResource
 #else
diff --git a/content/browser/web_package/web_bundle_interceptor_for_file.cc b/content/browser/web_package/web_bundle_interceptor_for_file.cc
index c3dfdac..b89ff29 100644
--- a/content/browser/web_package/web_bundle_interceptor_for_file.cc
+++ b/content/browser/web_package/web_bundle_interceptor_for_file.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/web_package/web_bundle_interceptor_for_file.h"
 
+#include "base/ranges/algorithm.h"
 #include "content/browser/loader/single_request_url_loader_factory.h"
 #include "content/browser/web_package/web_bundle_reader.h"
 #include "content/browser/web_package/web_bundle_redirect_url_loader.h"
@@ -90,6 +91,20 @@
         web_bundle_utils::kNoPrimaryUrlErrorMessage);
     return;
   }
+  if (!web_bundle_utils::IsAllowedExchangeUrl(primary_url_)) {
+    web_bundle_utils::CompleteWithInvalidWebBundleError(
+        std::move(forwarding_client_), frame_tree_node_id_,
+        web_bundle_utils::kInvalidPrimaryUrlErrorMessage);
+    return;
+  }
+  if (!base::ranges::all_of(reader_->GetEntries(),
+                            &web_bundle_utils::IsAllowedExchangeUrl)) {
+    web_bundle_utils::CompleteWithInvalidWebBundleError(
+        std::move(forwarding_client_), frame_tree_node_id_,
+        web_bundle_utils::kInvalidExchangeUrlErrorMessage);
+    return;
+  }
+
   url_loader_factory_ = std::make_unique<WebBundleURLLoaderFactory>(
       std::move(reader_), frame_tree_node_id_);
 
diff --git a/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.cc b/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.cc
index d2db7221..69c5a84d 100644
--- a/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.cc
+++ b/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.cc
@@ -56,8 +56,7 @@
   if (metadata_error_) {
     web_bundle_utils::CompleteWithInvalidWebBundleError(
         mojo::Remote<network::mojom::URLLoaderClient>(std::move(client)),
-        frame_tree_node_id_,
-        web_bundle_utils::GetMetadataParseErrorMessage(metadata_error_));
+        frame_tree_node_id_, *metadata_error_);
     return;
   }
 
@@ -77,9 +76,17 @@
   DCHECK(!url_loader_factory_);
 
   if (error) {
-    metadata_error_ = std::move(error);
+    metadata_error_ =
+        web_bundle_utils::GetMetadataParseErrorMessage(std::move(error));
   } else {
-    CreateWebBundleURLLoaderFactory(std::move(reader_));
+    if (!web_bundle_utils::IsAllowedExchangeUrl(reader_->GetPrimaryURL())) {
+      metadata_error_ = web_bundle_utils::kInvalidPrimaryUrlErrorMessage;
+    } else if (!base::ranges::all_of(reader_->GetEntries(),
+                                     &web_bundle_utils::IsAllowedExchangeUrl)) {
+      metadata_error_ = web_bundle_utils::kInvalidExchangeUrlErrorMessage;
+    } else {
+      CreateWebBundleURLLoaderFactory(std::move(reader_));
+    }
   }
 
   if (pending_receiver_) {
diff --git a/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.h b/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.h
index a692f965..fcd59f3b 100644
--- a/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.h
+++ b/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_file_or_from_trustable_file.h
@@ -70,7 +70,7 @@
   mojo::PendingReceiver<network::mojom::URLLoader> pending_receiver_;
   mojo::PendingRemote<network::mojom::URLLoaderClient> pending_client_;
 
-  web_package::mojom::BundleMetadataParseErrorPtr metadata_error_;
+  absl::optional<std::string> metadata_error_;
 
   base::WeakPtrFactory<
       WebBundleInterceptorForHistoryNavigationFromFileOrFromTrustableFile>
diff --git a/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_network.cc b/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_network.cc
index f170488..e7dd64dd 100644
--- a/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_network.cc
+++ b/content/browser/web_package/web_bundle_interceptor_for_history_navigation_from_network.cc
@@ -136,6 +136,19 @@
         web_bundle_utils::GetMetadataParseErrorMessage(error));
     return;
   }
+  if (!web_bundle_utils::IsAllowedExchangeUrl(reader_->GetPrimaryURL())) {
+    web_bundle_utils::CompleteWithInvalidWebBundleError(
+        std::move(forwarding_client_), frame_tree_node_id_,
+        web_bundle_utils::kInvalidPrimaryUrlErrorMessage);
+    return;
+  }
+  if (!base::ranges::all_of(reader_->GetEntries(),
+                            &web_bundle_utils::IsAllowedExchangeUrl)) {
+    web_bundle_utils::CompleteWithInvalidWebBundleError(
+        std::move(forwarding_client_), frame_tree_node_id_,
+        web_bundle_utils::kInvalidExchangeUrlErrorMessage);
+    return;
+  }
   if (!reader_->HasEntry(target_inner_url_)) {
     web_bundle_utils::CompleteWithInvalidWebBundleError(
         std::move(forwarding_client_), frame_tree_node_id_,
diff --git a/content/browser/web_package/web_bundle_interceptor_for_network.cc b/content/browser/web_package/web_bundle_interceptor_for_network.cc
index e924245..2999aed 100644
--- a/content/browser/web_package/web_bundle_interceptor_for_network.cc
+++ b/content/browser/web_package/web_bundle_interceptor_for_network.cc
@@ -115,6 +115,19 @@
         web_bundle_utils::kNoPrimaryUrlErrorMessage);
     return;
   }
+  if (!web_bundle_utils::IsAllowedExchangeUrl(primary_url_)) {
+    web_bundle_utils::CompleteWithInvalidWebBundleError(
+        std::move(forwarding_client_), frame_tree_node_id_,
+        web_bundle_utils::kInvalidPrimaryUrlErrorMessage);
+    return;
+  }
+  if (!base::ranges::all_of(reader_->GetEntries(),
+                            &web_bundle_utils::IsAllowedExchangeUrl)) {
+    web_bundle_utils::CompleteWithInvalidWebBundleError(
+        std::move(forwarding_client_), frame_tree_node_id_,
+        web_bundle_utils::kInvalidExchangeUrlErrorMessage);
+    return;
+  }
   if (!reader_->HasEntry(primary_url_)) {
     web_bundle_utils::CompleteWithInvalidWebBundleError(
         std::move(forwarding_client_), frame_tree_node_id_,
diff --git a/content/browser/web_package/web_bundle_interceptor_for_trustable_file.cc b/content/browser/web_package/web_bundle_interceptor_for_trustable_file.cc
index c703c91..173526a 100644
--- a/content/browser/web_package/web_bundle_interceptor_for_trustable_file.cc
+++ b/content/browser/web_package/web_bundle_interceptor_for_trustable_file.cc
@@ -50,8 +50,7 @@
   if (metadata_error_) {
     web_bundle_utils::CompleteWithInvalidWebBundleError(
         mojo::Remote<network::mojom::URLLoaderClient>(std::move(client)),
-        frame_tree_node_id_,
-        web_bundle_utils::GetMetadataParseErrorMessage(metadata_error_));
+        frame_tree_node_id_, *metadata_error_);
     return;
   }
 
@@ -64,13 +63,6 @@
     return;
   }
 
-  if (primary_url_.is_empty()) {
-    web_bundle_utils::CompleteWithInvalidWebBundleError(
-        mojo::Remote<network::mojom::URLLoaderClient>(std::move(client)),
-        frame_tree_node_id_, web_bundle_utils::kNoPrimaryUrlErrorMessage);
-    return;
-  }
-
   // Currently |source_| must be a local file. And the bundle's primary URL
   // can't be a local file URL. So while handling redirected request to the
   // primary URL, |resource_request.url| must not be same as the |source_|'s
@@ -100,11 +92,22 @@
   DCHECK(!url_loader_factory_);
 
   if (error) {
-    metadata_error_ = std::move(error);
+    metadata_error_ =
+        web_bundle_utils::GetMetadataParseErrorMessage(std::move(error));
   } else {
     primary_url_ = reader_->GetPrimaryURL();
-    url_loader_factory_ = std::make_unique<WebBundleURLLoaderFactory>(
-        std::move(reader_), frame_tree_node_id_);
+
+    if (primary_url_.is_empty()) {
+      metadata_error_ = web_bundle_utils::kNoPrimaryUrlErrorMessage;
+    } else if (!web_bundle_utils::IsAllowedExchangeUrl(primary_url_)) {
+      metadata_error_ = web_bundle_utils::kInvalidPrimaryUrlErrorMessage;
+    } else if (!base::ranges::all_of(reader_->GetEntries(),
+                                     &web_bundle_utils::IsAllowedExchangeUrl)) {
+      metadata_error_ = web_bundle_utils::kInvalidExchangeUrlErrorMessage;
+    } else {
+      url_loader_factory_ = std::make_unique<WebBundleURLLoaderFactory>(
+          std::move(reader_), frame_tree_node_id_);
+    }
   }
 
   if (pending_receiver_) {
diff --git a/content/browser/web_package/web_bundle_interceptor_for_trustable_file.h b/content/browser/web_package/web_bundle_interceptor_for_trustable_file.h
index a495e973..db4c1b64 100644
--- a/content/browser/web_package/web_bundle_interceptor_for_trustable_file.h
+++ b/content/browser/web_package/web_bundle_interceptor_for_trustable_file.h
@@ -74,7 +74,7 @@
   std::unique_ptr<WebBundleURLLoaderFactory> url_loader_factory_;
 
   GURL primary_url_;
-  web_package::mojom::BundleMetadataParseErrorPtr metadata_error_;
+  absl::optional<std::string> metadata_error_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/content/browser/web_package/web_bundle_network_browsertest.cc b/content/browser/web_package/web_bundle_network_browsertest.cc
index 916f7dbe..52c7f3bef 100644
--- a/content/browser/web_package/web_bundle_network_browsertest.cc
+++ b/content/browser/web_package/web_bundle_network_browsertest.cc
@@ -6,6 +6,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "content/browser/web_package/web_bundle_browsertest_base.h"
+#include "content/browser/web_package/web_bundle_utils.h"
 #include "content/public/test/back_forward_cache_util.h"
 #include "content/public/test/browser_test.h"
 #include "net/dns/mock_host_resolver.h"
@@ -260,6 +261,46 @@
       wbn_url, "Web Bundle is missing the Primary URL to navigate to.");
 }
 
+IN_PROC_BROWSER_TEST_F(WebBundleNetworkBrowserTest,
+                       PrimaryURLHasInvalidScheme) {
+  const std::string wbn_path = "/web_bundle/test.wbn";
+  RegisterRequestHandler(wbn_path);
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  const GURL wbn_url = embedded_test_server()->GetURL(wbn_path);
+  web_package::WebBundleBuilder builder;
+  builder.AddPrimaryURL("foo://bar/");
+  builder.AddExchange("foo://bar/",
+                      {{":status", "200"}, {"content-type", "text/html"}},
+                      "<title>Ready</title>");
+  std::vector<uint8_t> bundle = builder.CreateBundle();
+  SetContents(std::string(bundle.begin(), bundle.end()));
+  TestNavigationFailure(wbn_url,
+                        web_bundle_utils::kInvalidPrimaryUrlErrorMessage);
+}
+
+IN_PROC_BROWSER_TEST_F(WebBundleNetworkBrowserTest, ExchangeHasInvalidScheme) {
+  const std::string wbn_path = "/web_bundle/test.wbn";
+  const std::string primary_url_path = "/web_bundle/test.html";
+  RegisterRequestHandler(wbn_path);
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  const GURL wbn_url = embedded_test_server()->GetURL(wbn_path);
+  const GURL primary_url = embedded_test_server()->GetURL(primary_url_path);
+  web_package::WebBundleBuilder builder;
+  builder.AddPrimaryURL(primary_url.spec());
+  builder.AddExchange(primary_url.spec(),
+                      {{":status", "200"}, {"content-type", "text/html"}},
+                      "<title>Ready</title>");
+  builder.AddExchange("foo://bar",
+                      {{":status", "200"}, {"content-type", "text/html"}},
+                      "<title>Ready</title>");
+  std::vector<uint8_t> bundle = builder.CreateBundle();
+  SetContents(std::string(bundle.begin(), bundle.end()));
+  TestNavigationFailure(wbn_url,
+                        web_bundle_utils::kInvalidExchangeUrlErrorMessage);
+}
+
 IN_PROC_BROWSER_TEST_F(WebBundleNetworkBrowserTest, OriginMismatch) {
   const std::string wbn_path = "/web_bundle/test.wbn";
   const std::string primary_url_path = "/web_bundle/test.html";
diff --git a/content/browser/web_package/web_bundle_reader.cc b/content/browser/web_package/web_bundle_reader.cc
index 4b29b8e6..4d3e9668 100644
--- a/content/browser/web_package/web_bundle_reader.cc
+++ b/content/browser/web_package/web_bundle_reader.cc
@@ -315,6 +315,17 @@
   return entries_.contains(net::SimplifyUrlForRequest(url));
 }
 
+std::vector<GURL> WebBundleReader::GetEntries() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK_NE(state_, State::kInitial);
+
+  std::vector<GURL> entries;
+  entries.reserve(entries_.size());
+  base::ranges::transform(entries_, std::back_inserter(entries),
+                          [](const auto& entry) { return entry.first; });
+  return entries;
+}
+
 const GURL& WebBundleReader::GetPrimaryURL() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_NE(state_, State::kInitial);
diff --git a/content/browser/web_package/web_bundle_reader.h b/content/browser/web_package/web_bundle_reader.h
index c34ebd2c..94caf7f 100644
--- a/content/browser/web_package/web_bundle_reader.h
+++ b/content/browser/web_package/web_bundle_reader.h
@@ -82,6 +82,10 @@
   // Should be called after ReadMetadata finishes.
   bool HasEntry(const GURL& url) const;
 
+  // Returns a list of the URLs of all exchanges contained in this web bundle.
+  // Should be called after ReadMetadata finishes.
+  std::vector<GURL> GetEntries() const;
+
   // Returns the bundle's primary URL.
   // Should be called after ReadMetadata finishes.
   const GURL& GetPrimaryURL() const;
diff --git a/content/browser/web_package/web_bundle_reader_unittest.cc b/content/browser/web_package/web_bundle_reader_unittest.cc
index ece54fa..a47fd2fb 100644
--- a/content/browser/web_package/web_bundle_reader_unittest.cc
+++ b/content/browser/web_package/web_bundle_reader_unittest.cc
@@ -73,6 +73,8 @@
       GetReader()->HasEntry(GURL("https://user:pass@test.example.org/")));
   EXPECT_TRUE(GetReader()->HasEntry(GURL("https://test.example.org/#ref")));
   EXPECT_FALSE(GetReader()->HasEntry(GURL("https://test.example.org/404")));
+  EXPECT_EQ(GetReader()->GetEntries(),
+            std::vector({GURL("https://test.example.org")}));
 }
 
 TEST_F(WebBundleReaderTest, ReadResponse) {
diff --git a/content/browser/web_package/web_bundle_trustable_file_browsertest.cc b/content/browser/web_package/web_bundle_trustable_file_browsertest.cc
index 82c986a..ad04cf04 100644
--- a/content/browser/web_package/web_bundle_trustable_file_browsertest.cc
+++ b/content/browser/web_package/web_bundle_trustable_file_browsertest.cc
@@ -307,6 +307,56 @@
   EXPECT_EQ(web_bundle_utils::kNoPrimaryUrlErrorMessage, console_message);
 }
 
+// TODO(https://crbug.com/1225178): flaky
+#if BUILDFLAG(IS_LINUX)
+#define MAYBE_InvalidExchangeUrl DISABLED_InvalidExchangeUrl
+#else
+#define MAYBE_InvalidExchangeUrl InvalidExchangeUrl
+#endif
+IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
+                       MAYBE_InvalidExchangeUrl) {
+  std::string contents;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    ASSERT_TRUE(
+        base::ReadFileToString(web_bundle_browsertest_utils::GetTestDataPath(
+                                   "foo_base_url_bundle_b2.wbn"),
+                               &contents));
+  }
+  WriteWebBundleFile(contents);
+
+  std::string console_message = web_bundle_browsertest_utils::
+      ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
+                                                     test_data_url());
+
+  EXPECT_EQ(web_bundle_utils::kInvalidExchangeUrlErrorMessage, console_message);
+}
+
+// TODO(https://crbug.com/1225178): flaky
+#if BUILDFLAG(IS_LINUX)
+#define MAYBE_InvalidPrimaryUrl DISABLED_InvalidPrimaryUrl
+#else
+#define MAYBE_InvalidPrimaryUrl InvalidPrimaryUrl
+#endif
+IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
+                       MAYBE_InvalidPrimaryUrl) {
+  std::string contents;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    ASSERT_TRUE(
+        base::ReadFileToString(web_bundle_browsertest_utils::GetTestDataPath(
+                                   "foo_primary_url_bundle_b2.wbn"),
+                               &contents));
+  }
+  WriteWebBundleFile(contents);
+
+  std::string console_message = web_bundle_browsertest_utils::
+      ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
+                                                     test_data_url());
+
+  EXPECT_EQ(web_bundle_utils::kInvalidPrimaryUrlErrorMessage, console_message);
+}
+
 INSTANTIATE_TEST_SUITE_P(WebBundleTrustableFileBrowserTest,
                          WebBundleTrustableFileBrowserTest,
                          TEST_FILE_PATH_MODE_PARAMS);
diff --git a/content/browser/web_package/web_bundle_utils.cc b/content/browser/web_package/web_bundle_utils.cc
index 7ffe49aa3..24b6b6b 100644
--- a/content/browser/web_package/web_bundle_utils.cc
+++ b/content/browser/web_package/web_bundle_utils.cc
@@ -129,6 +129,10 @@
   return web_bundle_file_url.ReplaceComponents(replacements);
 }
 
+bool IsAllowedExchangeUrl(const GURL& url) {
+  return url.SchemeIsHTTPOrHTTPS();
+}
+
 void CompleteWithInvalidWebBundleError(
     mojo::Remote<network::mojom::URLLoaderClient> client,
     int frame_tree_node_id,
diff --git a/content/browser/web_package/web_bundle_utils.h b/content/browser/web_package/web_bundle_utils.h
index 0dc673ff..4e870a9 100644
--- a/content/browser/web_package/web_bundle_utils.h
+++ b/content/browser/web_package/web_bundle_utils.h
@@ -49,6 +49,11 @@
 constexpr char kNoPrimaryUrlErrorMessage[] =
     "Web Bundle is missing the Primary URL to navigate to.";
 
+constexpr char kInvalidPrimaryUrlErrorMessage[] =
+    "Primary URL is not a valid exchange URL.";
+
+constexpr char kInvalidExchangeUrlErrorMessage[] = "Exchange URL is not valid.";
+
 extern const net::NetworkTrafficAnnotationTag kTrafficAnnotation;
 
 // Adds |error_message| to the console and calls OnComplete() of |client|.
@@ -96,6 +101,11 @@
 GetSynthesizedUrlForWebBundle(const GURL& web_bundle_file_url,
                               const GURL& url_in_bundles);
 
+// Checks whether the URL is allowed to be used as the URL of an exchange.
+// TODO(crbug.com/966753): Revisit this once
+// https://github.com/WICG/webpackage/issues/468 is resolved.
+bool IsAllowedExchangeUrl(const GURL& url);
+
 }  // namespace web_bundle_utils
 }  // namespace content
 
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc
index 9c6c301..93145a97 100644
--- a/content/browser/webauth/authenticator_common.cc
+++ b/content/browser/webauth/authenticator_common.cc
@@ -41,6 +41,8 @@
 #include "crypto/sha2.h"
 #include "device/base/features.h"
 #include "device/fido/attestation_statement.h"
+#include "device/fido/authenticator_data.h"
+#include "device/fido/authenticator_get_assertion_response.h"
 #include "device/fido/ctap_make_credential_request.h"
 #include "device/fido/features.h"
 #include "device/fido/fido_authenticator.h"
@@ -1016,9 +1018,7 @@
           blink::mojom::AuthenticatorStatus::RESIDENT_CREDENTIALS_UNSUPPORTED);
       return;
     }
-    if (!options->is_conditional) {
-      maybe_show_account_picker_ = true;
-    }
+    discoverable_credential_request_ = true;
   }
 
   if (options->large_blob_read && options->large_blob_write) {
@@ -1510,31 +1510,40 @@
       authenticator->GetType() == device::FidoAuthenticator::Type::kWinNative);
 #endif
 
-  // Show an account picker for requests with empty allow lists.
-  // Authenticators may omit the identifying information in the user entity
-  // if only one credential matches, or if they have account selection UI
-  // built-in. In that case, consider that credential pre-selected.
-  // Authenticators can also use the userSelected signal (from CTAP 2.1)
-  // to indicate that selection has already occurred.
-  if (maybe_show_account_picker_ && !response_data->at(0).user_selected &&
-      (response_data->size() > 1 ||
-       (response_data->at(0).user_entity &&
-        (response_data->at(0).user_entity->name ||
-         response_data->at(0).user_entity->display_name)))) {
-    std::vector<device::PublicKeyCredentialUserEntity> users_list;
-    users_list.reserve(response_data->size());
-    for (const auto& response : *response_data) {
-      if (response.user_entity) {
-        users_list.push_back(*response.user_entity);
-      }
+  // Show an account picker for discoverable credential requests (empty allow
+  // lists). Responses with a single credential are considered pre-selected if
+  // one of the following is true:
+  // - The authenticator omitted user entity information because only one
+  // credential matched (only valid in CTAP 2.0).
+  // - The `userSelected` flag is set, because the user chose an account on an
+  // integrated authenticator UI (CTAP 2.1).
+  // - The user already pre-selected a platform authenticator credential from
+  // browser UI prior to the actual GetAssertion request. (The request handler
+  // set the `userSelected` flag in this case.)
+  if (response_data->size() == 1) {
+    const device::AuthenticatorGetAssertionResponse& response =
+        response_data->at(0);
+    if (!discoverable_credential_request_ || response.user_selected ||
+        !response.user_entity || !response.user_entity->name ||
+        !response.user_entity->display_name) {
+      OnAccountSelected(std::move(response_data->at(0)));
+      return;
     }
-    request_delegate_->SelectAccount(
-        std::move(*response_data),
-        base::BindOnce(&AuthenticatorCommon::OnAccountSelected,
-                       weak_factory_.GetWeakPtr()));
-  } else {
-    OnAccountSelected(std::move(response_data->at(0)));
   }
+
+  // Discoverable credential request without preselection UI. Show an account
+  // picker.
+  std::vector<device::PublicKeyCredentialUserEntity> users_list;
+  users_list.reserve(response_data->size());
+  for (const auto& response : *response_data) {
+    if (response.user_entity) {
+      users_list.push_back(*response.user_entity);
+    }
+  }
+  request_delegate_->SelectAccount(
+      std::move(*response_data),
+      base::BindOnce(&AuthenticatorCommon::OnAccountSelected,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void AuthenticatorCommon::OnAccountSelected(
@@ -1897,11 +1906,11 @@
   app_id_.reset();
   caller_origin_ = url::Origin();
   relying_party_id_.clear();
-  maybe_show_account_picker_ = false;
   error_awaiting_user_acknowledgement_ =
       blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR;
   requested_extensions_.clear();
   pending_proxied_request_id_.reset();
+  discoverable_credential_request_ = false;
 }
 
 void AuthenticatorCommon::DisableUI() {
diff --git a/content/browser/webauth/authenticator_common.h b/content/browser/webauth/authenticator_common.h
index 0c819984..3be0e11 100644
--- a/content/browser/webauth/authenticator_common.h
+++ b/content/browser/webauth/authenticator_common.h
@@ -265,10 +265,6 @@
   blink::mojom::Authenticator::GetAssertionCallback
       get_assertion_response_callback_;
   std::string client_data_json_;
-  // maybe_show_account_picker_ is true iff a non conditional UI GetAssertion is
-  // currently pending and the request did not list any credential IDs in the
-  // allow list.
-  bool maybe_show_account_picker_ = false;
   bool disable_ui_ = false;
   url::Origin caller_origin_;
   std::string relying_party_id_;
@@ -288,6 +284,7 @@
       blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR;
   data_decoder::DataDecoder data_decoder_;
   bool enable_request_proxy_api_ = false;
+  bool discoverable_credential_request_ = false;
 
   base::flat_set<RequestExtension> requested_extensions_;
 
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index 44bb3c8..849eec36 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -61,6 +61,7 @@
 #include "device/fido/cable/v2_discovery.h"
 #include "device/fido/cable/v2_handshake.h"
 #include "device/fido/cable/v2_test_util.h"
+#include "device/fido/discoverable_credential_metadata.h"
 #include "device/fido/fake_fido_discovery.h"
 #include "device/fido/features.h"
 #include "device/fido/fido_authenticator.h"
@@ -937,8 +938,8 @@
 
 // Parses its arguments as JSON and expects that all the keys in the first are
 // also in the second, and with the same value.
-void CheckJSONIsSubsetOfJSON(base::StringPiece subset_str,
-                             base::StringPiece test_str) {
+static void CheckJSONIsSubsetOfJSON(base::StringPiece subset_str,
+                                    base::StringPiece test_str) {
   std::unique_ptr<base::Value> subset(
       base::JSONReader::ReadDeprecated(subset_str));
   ASSERT_TRUE(subset);
@@ -2021,7 +2022,7 @@
       base::RepeatingClosure bluetooth_adapter_power_on_callback) override {
     ASSERT_TRUE(action_callbacks_registered_callback_)
         << "RegisterActionCallbacks called twice.";
-    cancel_callback_.emplace(std::move(cancel_callback));
+    cancel_callback_ = std::move(cancel_callback);
     std::move(action_callbacks_registered_callback_).Run();
     if (started_over_callback_) {
       action_callbacks_registered_callback_ = std::move(started_over_callback_);
@@ -2066,7 +2067,7 @@
     // which shows a specific error when no transports are available and lets
     // the user cancel the request.
     if (transport_info.available_transports.empty()) {
-      std::move(*cancel_callback_).Run();
+      std::move(cancel_callback_).Run();
     }
   }
 
@@ -2081,7 +2082,7 @@
   }
 
   base::OnceClosure action_callbacks_registered_callback_;
-  absl::optional<base::OnceClosure> cancel_callback_;
+  base::OnceClosure cancel_callback_;
   const AttestationConsent attestation_consent_;
   base::OnceClosure started_over_callback_;
   base::OnceClosure start_over_callback_;
@@ -6803,15 +6804,40 @@
 class ResidentKeyTestAuthenticatorRequestDelegate
     : public AuthenticatorRequestClientDelegate {
  public:
-  ResidentKeyTestAuthenticatorRequestDelegate(
-      std::string expected_accounts,
-      std::vector<uint8_t> selected_user_id,
-      absl::optional<InterestingFailureReason>* failure_reason,
-      bool* is_conditional)
-      : expected_accounts_(expected_accounts),
-        selected_user_id_(selected_user_id),
-        failure_reason_(failure_reason),
-        is_conditional_(is_conditional) {}
+  struct Config {
+    // A string representation of the accounts expected to be passed to
+    // `SelectAccount()`.
+    std::string expected_accounts;
+
+    // The user ID of the account that should be selected by `SelectAccount()`.
+    std::vector<uint8_t> selected_user_id;
+
+    // Indicates whether `SetConditional(true)` is expected to be called.
+    bool expect_conditional = false;
+
+    // If set, indicates that `DoesBlockRequestOnFailure()` is expected to be
+    // called with this value.
+    absl::optional<AuthenticatorRequestClientDelegate::InterestingFailureReason>
+        expected_failure_reason;
+
+    // If set, indicates that the `AccountPreselectCallback` should be invoked
+    // with this credential ID at the beginning of the request.
+    // `preselected_authenticator_id` contains the authenticator ID to which the
+    // request should be dispatched in this case.
+    absl::optional<std::vector<uint8_t>> preselected_credential_id;
+    absl::optional<std::string> preselected_authenticator_id;
+  };
+
+  explicit ResidentKeyTestAuthenticatorRequestDelegate(Config config)
+      : config_(std::move(config)) {}
+
+  ~ResidentKeyTestAuthenticatorRequestDelegate() override {
+    DCHECK(!config_.expect_conditional || expect_conditional_satisfied_)
+        << "SetConditionalRequest() expected but not called";
+    DCHECK(!config_.expected_failure_reason ||
+           expected_failure_reason_satisfied_)
+        << "DoesRequestBlockOnFailure() expected but not called";
+  }
 
   ResidentKeyTestAuthenticatorRequestDelegate(
       const ResidentKeyTestAuthenticatorRequestDelegate&) = delete;
@@ -6829,6 +6855,16 @@
 
   void FinishCollectToken() override {}
 
+  void RegisterActionCallbacks(
+      base::OnceClosure cancel_callback,
+      base::RepeatingClosure start_over_callback,
+      AccountPreselectedCallback account_preselected_callback,
+      device::FidoRequestHandlerBase::RequestCallback request_callback,
+      base::RepeatingClosure bluetooth_adapter_power_on_callback) override {
+    account_preselected_callback_ = account_preselected_callback;
+    request_callback_ = request_callback;
+  }
+
   void SelectAccount(
       std::vector<device::AuthenticatorGetAssertionResponse> responses,
       base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)>
@@ -6849,12 +6885,12 @@
                  user.name.value_or("") + ":" + user.display_name.value_or("");
         });
 
-    EXPECT_EQ(expected_accounts_, base::JoinString(string_reps, "/"));
+    EXPECT_EQ(config_.expected_accounts, base::JoinString(string_reps, "/"));
 
     const auto selected = std::find_if(
         responses.begin(), responses.end(),
         [this](const device::AuthenticatorGetAssertionResponse& response) {
-          return response.user_entity->id == selected_user_id_;
+          return response.user_entity->id == config_.selected_user_id;
         });
     ASSERT_TRUE(selected != responses.end());
 
@@ -6863,20 +6899,56 @@
   }
 
   bool DoesBlockRequestOnFailure(InterestingFailureReason reason) override {
-    *failure_reason_ = reason;
+    if (config_.expected_failure_reason) {
+      EXPECT_EQ(*config_.expected_failure_reason, reason);
+      expected_failure_reason_satisfied_ = true;
+    }
     return AuthenticatorRequestClientDelegate::DoesBlockRequestOnFailure(
         reason);
   }
 
   void SetConditionalRequest(bool is_conditional) override {
-    *is_conditional_ = is_conditional;
+    EXPECT_EQ(config_.expect_conditional, is_conditional);
+    EXPECT_TRUE(!expect_conditional_satisfied_);
+    expect_conditional_satisfied_ = true;
+  }
+
+  bool EmbedderControlsAuthenticatorDispatch(
+      const device::FidoAuthenticator& authenticator) override {
+    // Don't instantly dispatch platform authenticator requests if the test is
+    // exercising platform credential preselection.
+    // `OnTransportAvailabilityEnumerated()` will run the `request_callback_` in
+    // this case to mimic behavior of the real UI.
+    return authenticator.AuthenticatorTransport() ==
+               device::FidoTransportProtocol::kInternal &&
+           config_.preselected_credential_id;
+  }
+
+  void OnTransportAvailabilityEnumerated(
+      device::FidoRequestHandlerBase::TransportAvailabilityInfo info) override {
+    if (config_.preselected_credential_id) {
+      DCHECK(config_.preselected_authenticator_id);
+      EXPECT_EQ(info.has_platform_authenticator_credential,
+                device::FidoRequestHandlerBase::RecognizedCredential::
+                    kHasRecognizedCredential);
+      EXPECT_TRUE(std::any_of(
+          info.recognized_platform_authenticator_credentials.begin(),
+          info.recognized_platform_authenticator_credentials.end(),
+          [&](const device::DiscoverableCredentialMetadata& credential) {
+            return credential.cred_id == *config_.preselected_credential_id;
+          }));
+      std::move(account_preselected_callback_)
+          .Run(*config_.preselected_credential_id);
+      request_callback_.Run(*config_.preselected_authenticator_id);
+    }
   }
 
  private:
-  const std::string expected_accounts_;
-  const std::vector<uint8_t> selected_user_id_;
-  const raw_ptr<absl::optional<InterestingFailureReason>> failure_reason_;
-  const raw_ptr<bool> is_conditional_;
+  const Config config_;
+  bool expect_conditional_satisfied_ = false;
+  bool expected_failure_reason_satisfied_ = false;
+  device::FidoRequestHandlerBase::RequestCallback request_callback_;
+  AccountPreselectedCallback account_preselected_callback_;
 };
 
 class ResidentKeyTestAuthenticatorContentBrowserClient
@@ -6894,20 +6966,16 @@
   GetWebAuthenticationRequestDelegate(
       RenderFrameHost* render_frame_host) override {
     return std::make_unique<ResidentKeyTestAuthenticatorRequestDelegate>(
-        expected_accounts, selected_user_id, &failure_reason, &is_conditional);
+        delegate_config);
   }
 
   TestWebAuthenticationDelegate web_authentication_delegate;
 
-  std::string expected_accounts;
-  std::vector<uint8_t> selected_user_id;
-  bool is_conditional = false;
-  absl::optional<AuthenticatorRequestClientDelegate::InterestingFailureReason>
-      failure_reason;
+  ResidentKeyTestAuthenticatorRequestDelegate::Config delegate_config;
 };
 
 class ResidentKeyAuthenticatorImplTest : public UVAuthenticatorImplTest {
- public:
+ protected:
   ResidentKeyAuthenticatorImplTest() = default;
 
   ResidentKeyAuthenticatorImplTest(const ResidentKeyAuthenticatorImplTest&) =
@@ -6933,9 +7001,6 @@
     UVAuthenticatorImplTest::TearDown();
   }
 
- protected:
-  ResidentKeyTestAuthenticatorContentBrowserClient test_client_;
-
   static PublicKeyCredentialCreationOptionsPtr make_credential_options(
       device::ResidentKeyRequirement resident_key =
           device::ResidentKeyRequirement::kRequired) {
@@ -6953,22 +7018,12 @@
     return options;
   }
 
+  ResidentKeyTestAuthenticatorContentBrowserClient test_client_;
+
  private:
   raw_ptr<ContentBrowserClient> old_client_ = nullptr;
 };
 
-class ResidentKeyAuthenticatorImplWithFlagsTest
-    : public ResidentKeyAuthenticatorImplTest {
- public:
-  ResidentKeyAuthenticatorImplWithFlagsTest() {
-    scoped_feature_list_.InitWithFeatures({features::kWebAuthCable},
-                                          /*disabled_features=*/{});
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
 TEST_F(ResidentKeyAuthenticatorImplTest, MakeCredentialRkRequired) {
   for (const bool internal_uv : {false, true}) {
     SCOPED_TRACE(::testing::Message() << "internal_uv=" << internal_uv);
@@ -7101,12 +7156,11 @@
       /*credential_id=*/{{4, 3, 2, 1}}, kTestRelyingPartyId,
       /*user_id=*/{{1, 1, 1, 1}}, "test@example.com", "Test User"));
 
+  test_client_.delegate_config.expected_failure_reason =
+      AuthenticatorRequestClientDelegate::InterestingFailureReason::
+          kStorageFull;
   EXPECT_EQ(AuthenticatorMakeCredential(make_credential_options()).status,
             AuthenticatorStatus::NOT_ALLOWED_ERROR);
-  ASSERT_TRUE(test_client_.failure_reason.has_value());
-  EXPECT_EQ(AuthenticatorRequestClientDelegate::InterestingFailureReason::
-                kStorageFull,
-            test_client_.failure_reason);
 }
 
 TEST_F(ResidentKeyAuthenticatorImplTest, GetAssertionSingleNoPII) {
@@ -7117,7 +7171,7 @@
   // |SelectAccount| should not be called when there's only a single response
   // with no identifying user info because the UI is bad in that case: we can
   // only display the single choice of "Unknown user".
-  test_client_.expected_accounts = "<invalid>";
+  test_client_.delegate_config.expected_accounts = "<invalid>";
   GetAssertionResult result =
       AuthenticatorGetAssertion(get_credential_options());
 
@@ -7141,10 +7195,10 @@
 
     // |SelectAccount| should not be called when userSelected is set.
     if (internal_account_chooser) {
-      test_client_.expected_accounts = "<invalid>";
+      test_client_.delegate_config.expected_accounts = "<invalid>";
     } else {
-      test_client_.expected_accounts = "01020304:Test:User";
-      test_client_.selected_user_id = {1, 2, 3, 4};
+      test_client_.delegate_config.expected_accounts = "01020304:Test:User";
+      test_client_.delegate_config.selected_user_id = {1, 2, 3, 4};
     }
     GetAssertionResult result =
         AuthenticatorGetAssertion(get_credential_options());
@@ -7160,8 +7214,8 @@
       /*user_id=*/{{1, 2, 3, 4}}, absl::nullopt, "Test User"));
 
   // |SelectAccount| should be called when PII is available.
-  test_client_.expected_accounts = "01020304::Test User";
-  test_client_.selected_user_id = {1, 2, 3, 4};
+  test_client_.delegate_config.expected_accounts = "01020304::Test User";
+  test_client_.delegate_config.selected_user_id = {1, 2, 3, 4};
   GetAssertionResult result =
       AuthenticatorGetAssertion(get_credential_options());
   EXPECT_EQ(AuthenticatorStatus::SUCCESS, result.status);
@@ -7176,10 +7230,10 @@
       /*credential_id=*/{{4, 3, 2, 2}}, kTestRelyingPartyId,
       /*user_id=*/{{5, 6, 7, 8}}, "test2@example.com", "Test User 2"));
 
-  test_client_.expected_accounts =
+  test_client_.delegate_config.expected_accounts =
       "01020304:test@example.com:Test User/"
       "05060708:test2@example.com:Test User 2";
-  test_client_.selected_user_id = {1, 2, 3, 4};
+  test_client_.delegate_config.selected_user_id = {1, 2, 3, 4};
 
   GetAssertionResult result =
       AuthenticatorGetAssertion(get_credential_options());
@@ -7202,7 +7256,7 @@
 
   // |SelectAccount| should not be called when there's only a single response
   // without identifying information.
-  test_client_.expected_accounts = "<invalid>";
+  test_client_.delegate_config.expected_accounts = "<invalid>";
   PublicKeyCredentialRequestOptionsPtr options(get_credential_options());
   options->user_verification =
       device::UserVerificationRequirement::kDiscouraged;
@@ -7746,7 +7800,7 @@
       ->second.protection = device::CredProtect::kUVRequired;
 
   // |SelectAccount| should not be called when there's only a single response.
-  test_client_.expected_accounts = "<invalid>";
+  test_client_.delegate_config.expected_accounts = "<invalid>";
 
   PublicKeyCredentialRequestOptionsPtr options = get_credential_options();
   options->allow_credentials = GetTestCredentials(5);
@@ -7772,7 +7826,7 @@
 
   // |SelectAccount| should not be called when there's only a single response
   // without identifying information.
-  test_client_.expected_accounts = "<invalid>";
+  test_client_.delegate_config.expected_accounts = "<invalid>";
 
   PublicKeyCredentialRequestOptionsPtr options = get_credential_options();
   options->appid = kTestOrigin1;
@@ -7987,8 +8041,9 @@
     auto prf_value = blink::mojom::PRFValues::New();
     prf_value->first = salt1;
     prf_value->second = salt2;
-    test_client_.expected_accounts = "01020304:name:displayName";
-    test_client_.selected_user_id = {1, 2, 3, 4};
+    test_client_.delegate_config.expected_accounts =
+        "01020304:name:displayName";
+    test_client_.delegate_config.selected_user_id = {1, 2, 3, 4};
     std::vector<blink::mojom::PRFValuesPtr> inputs;
     inputs.emplace_back(std::move(prf_value));
     auto result = assertion(std::move(inputs), /*allowlist_size=*/0);
@@ -8025,14 +8080,55 @@
       /*credential_id=*/{{4, 3, 2, 1}}, kTestRelyingPartyId,
       /*user_id=*/{{1, 2, 3, 4}}, absl::nullopt, absl::nullopt));
 
-  // |SelectAccount| should not be called when there's only a single response
-  // without identifying information.
-  test_client_.expected_accounts = "<invalid>";
+  // |SelectAccount| should not be called for conditional UI requests.
+  test_client_.delegate_config.expected_accounts = "<invalid>";
+  test_client_.delegate_config.expect_conditional = true;
   PublicKeyCredentialRequestOptionsPtr options(get_credential_options());
   options->is_conditional = true;
   GetAssertionResult result = AuthenticatorGetAssertion(std::move(options));
   EXPECT_EQ(AuthenticatorStatus::SUCCESS, result.status);
-  EXPECT_TRUE(test_client_.is_conditional);
+}
+
+// Tests that the AuthenticatorRequestDelegate can choose a known platform
+// authentictor credential as "preselected", which causes the request to be
+// specialized to the chosen credential ID and post-request account selection UI
+// to be skipped.
+TEST_F(ResidentKeyAuthenticatorImplTest, PreselectDiscoverableCredential) {
+  device::VirtualCtap2Device::Config config;
+  config.resident_key_support = true;
+  config.internal_uv_support = true;
+  virtual_device_factory_->SetCtap2Config(config);
+  virtual_device_factory_->SetTransport(
+      device::FidoTransportProtocol::kInternal);
+  virtual_device_factory_->mutable_state()->fingerprints_enrolled = true;
+  constexpr char kAuthenticatorId[] = "internal-authenticator";
+  virtual_device_factory_->mutable_state()->device_id_override =
+      kAuthenticatorId;
+  std::vector<uint8_t> kFirstCredentialId{{1, 2, 3, 4}};
+  std::vector<uint8_t> kSecondCredentialId{{10, 20, 30, 40}};
+  std::vector<uint8_t> kFirstUserId{{2, 3, 4, 5}};
+  std::vector<uint8_t> kSecondUserId{{20, 30, 40, 50}};
+
+  ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectResidentKey(
+      kFirstCredentialId, kTestRelyingPartyId, kFirstUserId, absl::nullopt,
+      absl::nullopt));
+  ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectResidentKey(
+      kSecondCredentialId, kTestRelyingPartyId, kSecondUserId, absl::nullopt,
+      absl::nullopt));
+
+  // |SelectAccount| should not be called if an account was chosen from
+  // pre-select UI.
+  test_client_.delegate_config.expected_accounts = "<invalid>";
+
+  for (const auto& id : {kFirstCredentialId, kSecondCredentialId}) {
+    test_client_.delegate_config.preselected_credential_id = id;
+    test_client_.delegate_config.preselected_authenticator_id =
+        kAuthenticatorId;
+    PublicKeyCredentialRequestOptionsPtr options(get_credential_options());
+    GetAssertionResult result = AuthenticatorGetAssertion(std::move(options));
+    EXPECT_EQ(result.status, AuthenticatorStatus::SUCCESS);
+    EXPECT_EQ(result.response->info->raw_id, id);
+  }
 }
 
 class InternalAuthenticatorImplTest : public AuthenticatorTestBase {
@@ -8322,10 +8418,7 @@
         virtual_device_(new VirtualFidoDevice::State, DeviceConfig()),
         browser_client_(
             base::BindRepeating(&AuthenticatorCableV2Test::MaybeContactPhones,
-                                base::Unretained(this))) {
-    scoped_feature_list_.InitWithFeatures({features::kWebAuthCable},
-                                          /*disabled_features=*/{});
-  }
+                                base::Unretained(this))) {}
 
   void SetUp() override {
     AuthenticatorImplTest::SetUp();
@@ -8506,8 +8599,6 @@
         VirtualCtap2Device::Config::IncludeCredential::ALWAYS;
     return ret;
   }
-
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 TEST_P(AuthenticatorCableV2Test, QRBasedWithNoPairing) {
diff --git a/content/common/partition_alloc_support.cc b/content/common/partition_alloc_support.cc
index a525eb9d..66d91e4 100644
--- a/content/common/partition_alloc_support.cc
+++ b/content/common/partition_alloc_support.cc
@@ -420,7 +420,7 @@
 #if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_32_BITS)
     // Devices almost always report less physical memory than what they actually
     // have, so anything above 3GiB will catch 4GiB and above.
-    if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 3500)
+    if (base::SysInfo::AmountOfPhysicalMemory() <= int64_t{3500} * 1024 * 1024)
       largest_cached_size_ =
           ::partition_alloc::ThreadCacheLimits::kDefaultSizeThreshold;
 #endif  // BUILDFLAG(IS_ANDROID) && !defined(ARCH_CPU_64_BITS)
@@ -449,7 +449,7 @@
 
   if (base::FeatureList::IsEnabled(
           base::features::kPartitionAllocSortActiveSlotSpans)) {
-    base::PartitionRoot<
+    partition_alloc::PartitionRoot<
         partition_alloc::internal::ThreadSafe>::EnableSortActiveSlotSpans();
   }
 }
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 4319dd0..b39621d 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -3021,7 +3021,10 @@
   explicit FrameTreeNodeObserverImpl(FrameTreeNode* owner) : owner_(owner) {
     owner->AddObserver(this);
   }
-  ~FrameTreeNodeObserverImpl() override { owner_->RemoveObserver(this); }
+  ~FrameTreeNodeObserverImpl() override {
+    if (owner_)
+      owner_->RemoveObserver(this);
+  }
 
   void Run() { run_loop_.Run(); }
 
@@ -3030,6 +3033,11 @@
       run_loop_.Quit();
   }
 
+  void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override {
+    if (node == owner_)
+      owner_ = nullptr;
+  }
+
  private:
   raw_ptr<FrameTreeNode> owner_;
   base::RunLoop run_loop_;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index c1910ac3..810e0b1 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1313,6 +1313,7 @@
     "../browser/net/dns_https_protocol_upgrade_browsertest.cc",
     "../browser/net/http_cookie_browsertest.cc",
     "../browser/net/network_field_trial_browsertest.cc",
+    "../browser/net/network_service_memory_cache_browsertest.cc",
     "../browser/net/sandboxed_http_cache_browsertest.cc",
     "../browser/net/sandboxed_nqe_browsertest.cc",
     "../browser/net/sandboxed_socket_broker_browsertest.cc",
diff --git a/content/test/data/cacheable-isolated.jpg b/content/test/data/cacheable-isolated.jpg
new file mode 100644
index 0000000..1cda9a5
--- /dev/null
+++ b/content/test/data/cacheable-isolated.jpg
Binary files differ
diff --git a/content/test/data/cacheable-isolated.jpg.mock-http-headers b/content/test/data/cacheable-isolated.jpg.mock-http-headers
new file mode 100644
index 0000000..a7d2b6c
--- /dev/null
+++ b/content/test/data/cacheable-isolated.jpg.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Content-Type: image/jpeg
+Cache-Control: max-age=300
diff --git a/content/test/data/web_bundle/broken_bundle_base_b2.wbn b/content/test/data/web_bundle/broken_bundle_base_b2.wbn
index aae49e980..e24eeb3 100644
--- a/content/test/data/web_bundle/broken_bundle_base_b2.wbn
+++ b/content/test/data/web_bundle/broken_bundle_base_b2.wbn
Binary files differ
diff --git a/content/test/data/web_bundle/broken_bundle_broken_first_entry_b2.wbn b/content/test/data/web_bundle/broken_bundle_broken_first_entry_b2.wbn
index 87a35b0..fcd4faf4 100644
--- a/content/test/data/web_bundle/broken_bundle_broken_first_entry_b2.wbn
+++ b/content/test/data/web_bundle/broken_bundle_broken_first_entry_b2.wbn
Binary files differ
diff --git a/content/test/data/web_bundle/broken_bundle_broken_script_entry_b2.wbn b/content/test/data/web_bundle/broken_bundle_broken_script_entry_b2.wbn
index 99145a6..3409cc95 100644
--- a/content/test/data/web_bundle/broken_bundle_broken_script_entry_b2.wbn
+++ b/content/test/data/web_bundle/broken_bundle_broken_script_entry_b2.wbn
Binary files differ
diff --git a/content/test/data/web_bundle/foo_base_url_bundle_b2.wbn b/content/test/data/web_bundle/foo_base_url_bundle_b2.wbn
new file mode 100644
index 0000000..eb98a3d
--- /dev/null
+++ b/content/test/data/web_bundle/foo_base_url_bundle_b2.wbn
Binary files differ
diff --git a/content/test/data/web_bundle/foo_primary_url_bundle_b2.wbn b/content/test/data/web_bundle/foo_primary_url_bundle_b2.wbn
new file mode 100644
index 0000000..9734254
--- /dev/null
+++ b/content/test/data/web_bundle/foo_primary_url_bundle_b2.wbn
Binary files differ
diff --git a/content/test/data/web_bundle/foo_url.har b/content/test/data/web_bundle/foo_url.har
new file mode 100644
index 0000000..da27bd6
--- /dev/null
+++ b/content/test/data/web_bundle/foo_url.har
@@ -0,0 +1,44 @@
+{
+  "log": {
+    "entries": [
+      {
+        "request": {
+          "method": "GET",
+          "url": "foo://bar/",
+          "headers": []
+        },
+        "response": {
+          "status": 200,
+          "headers": [
+            {
+              "name": "Content-type",
+              "value": "application/json"
+            }
+          ],
+          "content": {
+            "text": "{ secret: 1 }"
+          }
+        }
+      },
+      {
+        "request": {
+          "method": "GET",
+          "url": "https://test.example.org/",
+          "headers": []
+        },
+        "response": {
+          "status": 200,
+          "headers": [
+            {
+              "name": "Content-type",
+              "value": "text/plain"
+            }
+          ],
+          "content": {
+            "text": "hello"
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/content/test/data/web_bundle/generate-test-wbns.sh b/content/test/data/web_bundle/generate-test-wbns.sh
index 609e7a5..a8f0dcd 100755
--- a/content/test/data/web_bundle/generate-test-wbns.sh
+++ b/content/test/data/web_bundle/generate-test-wbns.sh
@@ -46,6 +46,18 @@
   sed 's/3a737461747573/3a787878787878/3' |
   xxd -r -p > broken_bundle_broken_script_entry_b2.wbn
 
+gen-bundle \
+  -version b2 \
+  -har foo_url.har \
+  -primaryURL foo://bar/ \
+  -o foo_primary_url_bundle_b2.wbn
+
+gen-bundle \
+  -version b2 \
+  -har foo_url.har \
+  -primaryURL https://test.example.org/ \
+  -o foo_base_url_bundle_b2.wbn
+
 # Generate a WBN which will be used as a cross origin bundle.
 gen-bundle \
   -version b2 \
diff --git a/content/test/data/web_bundle/web_bundle_browsertest_b2.wbn b/content/test/data/web_bundle/web_bundle_browsertest_b2.wbn
index 28ae517..ee79df0b 100644
--- a/content/test/data/web_bundle/web_bundle_browsertest_b2.wbn
+++ b/content/test/data/web_bundle/web_bundle_browsertest_b2.wbn
Binary files differ
diff --git a/device/fido/features.cc b/device/fido/features.cc
index 4665117..9ec33792 100644
--- a/device/fido/features.cc
+++ b/device/fido/features.cc
@@ -42,4 +42,8 @@
 extern const base::Feature kWebAuthPasskeysUI{
     "WebAuthenticationPasskeysUI", base::FEATURE_DISABLED_BY_DEFAULT};
 
+extern const base::Feature kWebAuthnNewDiscoverableCredentialsUi{
+    "WebAuthenticationNewDiscoverableCredentialsUi",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace device
diff --git a/device/fido/features.h b/device/fido/features.h
index d2fc2da..75be2ff 100644
--- a/device/fido/features.h
+++ b/device/fido/features.h
@@ -50,6 +50,11 @@
 COMPONENT_EXPORT(DEVICE_FIDO)
 extern const base::Feature kWebAuthPasskeysUI;
 
+// Reshuffle WebAuthn request UI to put account selection for discoverable
+// credentials on platform authenticators first, where applicable.
+COMPONENT_EXPORT(DEVICE_FIDO)
+extern const base::Feature kWebAuthnNewDiscoverableCredentialsUi;
+
 }  // namespace device
 
 #endif  // DEVICE_FIDO_FEATURES_H_
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc
index 30e06c5..b961367 100644
--- a/device/fido/get_assertion_request_handler.cc
+++ b/device/fido/get_assertion_request_handler.cc
@@ -308,9 +308,10 @@
 
 void GetAssertionRequestHandler::PreselectAccount(
     std::vector<uint8_t> credential_id) {
-  request_.allow_list = {device::PublicKeyCredentialDescriptor(
-      CredentialType::kPublicKey, credential_id,
-      {FidoTransportProtocol::kInternal})};
+  // PreselectAccount is only supposed to be invoked for discoverable credential
+  // requests.
+  DCHECK(request_.allow_list.empty());
+  preselected_credential_ = std::move(credential_id);
 }
 
 base::WeakPtr<GetAssertionRequestHandler>
@@ -395,6 +396,13 @@
       return;
   }
 
+  if (preselected_credential_) {
+    DCHECK(request.allow_list.empty());
+    request.allow_list = {device::PublicKeyCredentialDescriptor(
+        CredentialType::kPublicKey, *preselected_credential_,
+        {FidoTransportProtocol::kInternal})};
+  }
+
   ReportGetAssertionRequestTransport(authenticator);
 
   CtapGetAssertionRequest request_copy(request);
@@ -662,6 +670,16 @@
     return;
   }
 
+  if (preselected_credential_) {
+    // A discoverable platform credential was preselected by the user prior to
+    // making the assertion request. Instruct the UI not to show another account
+    // selection dialog by setting the `userSelected` flag.
+    DCHECK_EQ(num_responses, 1u);
+    DCHECK(response->credential &&
+           response->credential->id == preselected_credential_);
+    response->user_selected = true;
+  }
+
   DCHECK(responses_.empty());
   responses_.emplace_back(std::move(*response));
   if (num_responses > 1) {
diff --git a/device/fido/get_assertion_request_handler.h b/device/fido/get_assertion_request_handler.h
index d049954..82c1859 100644
--- a/device/fido/get_assertion_request_handler.h
+++ b/device/fido/get_assertion_request_handler.h
@@ -172,6 +172,12 @@
   std::map<FidoAuthenticator*, std::unique_ptr<AuthTokenRequester>>
       auth_token_requester_map_;
 
+  // preselected_credential_ is set when the UI invokes `PreselectAccount()`. It
+  // contains the ID of a platform authenticator credential chosen by the user
+  // during a resident key request prior to dispatching to that platform
+  // authenticator.
+  absl::optional<std::vector<uint8_t>> preselected_credential_;
+
   SEQUENCE_CHECKER(my_sequence_checker_);
   base::WeakPtrFactory<GetAssertionRequestHandler> weak_factory_{this};
 };
diff --git a/device/fido/virtual_fido_device.cc b/device/fido/virtual_fido_device.cc
index 05fe8a74..ab7a8b9 100644
--- a/device/fido/virtual_fido_device.cc
+++ b/device/fido/virtual_fido_device.cc
@@ -498,7 +498,7 @@
 VirtualFidoDevice::~VirtualFidoDevice() = default;
 
 std::string VirtualFidoDevice::GetId() const {
-  return id_;
+  return state_->device_id_override.value_or(id_);
 }
 
 // static
diff --git a/device/fido/virtual_fido_device.h b/device/fido/virtual_fido_device.h
index 776cf5c6..9052498 100644
--- a/device/fido/virtual_fido_device.h
+++ b/device/fido/virtual_fido_device.h
@@ -256,6 +256,10 @@
     // response after simulating an unsatisfied touch for CTAP2 authenticators.
     FidoDevice::DeviceCallback transact_callback;
 
+    // device_id_override can be used to inject a return value for `GetId()` in
+    // unit tests where a stable device identifier is required.
+    absl::optional<std::string> device_id_override;
+
     // Adds a new credential to the authenticator. Returns true on success,
     // false if there already exists a credential with the given ID.
     bool InjectRegistration(base::span<const uint8_t> credential_id,
diff --git a/docs/vscode.md b/docs/vscode.md
index 395a21b..c8c46f45 100644
--- a/docs/vscode.md
+++ b/docs/vscode.md
@@ -1,11 +1,13 @@
 # Visual Studio Code Dev
 
-Visual Studio Code is a free, lightweight and powerful code editor for Windows,
-Mac and Linux, based on Electron/Chromium. It has built-in support for
-JavaScript, TypeScript and Node.js and a rich extension ecosystem that adds
-intellisense, debugging, syntax highlighting etc. for many languages (C++,
-Python, Go, Java). It works without too much setup. Get started
-[here](https://code.visualstudio.com/docs).
+**Get started [here](#setup)**.
+
+[Visual Studio Code (VS Code)](https://code.visualstudio.com) is a free,
+open source, lightweight and powerful code editor for Windows, Mac and Linux,
+based on [Electron](https://www.electronjs.org/)/Chromium.
+It has built-in support for JavaScript, TypeScript and Node.js and a rich
+extension ecosystem that adds intellisense, debugging, syntax highlighting etc.
+For many languages like C++, Python, Go, Java, it works without too much setup.
 
 It is NOT a full-fledged IDE like Visual Studio. The two are completely
 separate products. The only commonality with Visual Studio is that both are
@@ -13,50 +15,58 @@
 
 Here's what works well:
 
-*   Editing code works well especially when you get used to the [keyboard
-    shortcuts](https://code.visualstudio.com/docs/customization/keybindings).
-    VS Code is very responsive and can handle even big code bases like Chromium.
-*   Git integration is a blast. Built-in side-by-side view, local commit and
+*   **Editing code** works well especially when you get used to the [keyboard
+    shortcuts](#Keyboard-Shortcuts). VS Code is very responsive and can handle
+    even big code bases like Chromium.
+*   **Git integration** is a blast. Built-in side-by-side view, local commit and
     even extensions for
     [history](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory)
     and
     [blame view](https://marketplace.visualstudio.com/items?itemName=ryu1kn.annotator).
-*   [Debugging](https://code.visualstudio.com/Docs/editor/debugging) works
+*   [**Debugging**](https://code.visualstudio.com/Docs/editor/debugging) works
     well, even though startup times can be fairly high (~40 seconds with
     gdb on Linux, much lower on Windows). You can step through code, inspect
     variables, view call stacks for multiple threads etc.
     *   For more information on debugging Python code, see [here](vscode_python.md).
-*   Opening files and searching solution-wide works well now after having
-    problems in earlier versions.
-*   Building works well. Build tools are easy to integrate. Warnings and errors
+*   **Command Palette** makes opening files and searching solution really easy.
+*   **Building** works well. Build tools are easy to integrate. Warnings and errors
     are displayed on a separate page and you can click to jump to the
     corresponding line of code.
-*   VSCode Remote, which allows you to edit remotely-hosted code, and even run
-    computationally expensive plugins like vscode-clangd on the remote
-    server/workstation (see the [Remote section](#Remote)). Great for working-
-    from-home. (Googlers: See [go/vscode-remote](http://go/vscode-remote).)
+*   **VS Code Remote**, which allows you to edit remotely-hosted code, and even
+    run computationally expensive plugins like vscode-clangd on the remote
+    server. Great for working from home. See the [Remote section](#Remote) for
+    more details.
 
 [TOC]
 
+
 ## Updating This Page
 
 Please keep this doc up-to-date. VS Code is still in active development and
 subject to changes. This doc is checked into the Chromium git repo, so if you
 make changes, read the [documentation
-guidelines](documentation_guidelines.md)
-and [submit a change list](contributing.md).
+guidelines](documentation_guidelines.md) and
+[submit a change list](contributing.md).
 
 All file paths and commands have been tested on Linux. Windows and Mac might
 require a slightly different setup (e.g. `Ctrl` -> `Cmd`). Please update this
 page accordingly.
 
+
 ## Setup
 
 ### Installation
 
-Follow the steps on https://code.visualstudio.com/docs/setup/setup-overview. To
-run it on Linux, just navigate to Chromium's `src` folder and type `code .` in a
-terminal. The argument to `code` is the base directory of the workspace. VS
+*** promo
+Googlers: See [go/vscode/install](http://go/vscode/install).
+***
+
+Follow the steps on [Setting up Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview).
+
+### Usage
+
+To run it on Linux, just navigate to Chromium's `src` folder and type `code .`
+in a terminal. The argument to `code` is the base directory of the workspace. VS
 Code does not require project or solution files. However, it does store
 workspace settings in a `.vscode` folder in your base directory.
 
@@ -87,67 +97,102 @@
 
 Up to now, you have a basic version of VS Code without much language support.
 Next, we will install some useful extensions. Jump to the extensions window
-(`Ctrl+Shift+X`) and install these extensions, you will most likely use them
-every day:
+(`Ctrl+Shift+X`) and install the extensions, or run the following commands.
 
-*   ***C/C++*** -
+You will most likely use the following extensions every day:
+
+```bash
+$ echo "ms-vscode.cpptools llvm-vs-code-extensions.vscode-clangd ms-python.python bbenoist.togglehs peterj.proto Google.vscode-mojom npclaudiu.vscode-gn stkb.rewrap ms-vscode-remote.remote-ssh eamodio.gitlens" | xargs -n 1 code --install-extension --force
+```
+
+*   [**C/C++**](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) -
     Code formatting, debugging, Intellisense. Enables the use of clang-format
     (via the `C_Cpp.clang_format_path` setting) and format-on-save (via the
     `editor.formatOnSave` setting).
-*   ***Python*** -
+*   [**vscode-clangd**](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) -
+    Enables VS Code to compile Chromium, provide Chromium XRefs to support
+    functions like jumping to definition, and provide smarter autocompletion
+    than **C/C++** extension's IntelliSense, but they also conflicts with each
+    other. To resolve the conflict, add the following to `settings.json`:
+    `"C_Cpp.intelliSenseEngine": "Disabled"`.  See [clangd.md](clangd.md) for
+    setup instructions.
+*   [**Python**](https://marketplace.visualstudio.com/items?itemName=ms-python.python) -
     Linting, intellisense, code formatting, refactoring, debugging, snippets.
     * If you want type checking, add: `"python.analysis.typeCheckingMode": "basic",`
       to your `settings.json` file (you can also find it in the settings UI).
-*   ***Toggle Header/Source*** -
+*   [**Toggle Header/Source**](https://marketplace.visualstudio.com/items?itemName=bbenoist.togglehs) -
     Toggles between .cc and .h with `F4`. The C/C++ extension supports this as
     well through `Alt+O` but sometimes chooses the wrong file when there are
     multiple files in the workspace that have the same name.
-*   ***Protobuf support*** -
+*   [**Protobuf support**](https://marketplace.visualstudio.com/items?itemName=peterj.proto) -
     Syntax highlighting for .proto files.
-*   [***Mojom IDL support***](https://github.com/GoogleChromeLabs/mojom-language-support) -
+*   [**Mojom IDL support**](https://marketplace.visualstudio.com/items?itemName=Google.vscode-mojom) -
     Syntax highlighting and a
     [language server](https://microsoft.github.io/language-server-protocol/)
     for .mojom files.
-*   ***vscode-clangd*** -
-    If you do not plan to use VSCode for debugging, vscode-clangd is a great
-    alternative to C/C++ IntelliSense. It knows about how to compile Chromium,
-    enabling it to provide smarter autocomplete than C/C++ IntelliSense as well
-    as allowing you to jump from functions to their definitions. See
-    [clangd.md](clangd.md) for setup instructions.
-    If you need to debug, enable C/C++ extension but set "C_Cpp: Intelli Sense Engine" to disabled,
-    and restart VSCode.
-*   ***Rewrap*** -
+*   [**GN**](https://marketplace.visualstudio.com/items?itemName=npclaudiu.vscode-gn) -
+    Syntax highlighting for .gn files.
+*   [**Rewrap**](https://marketplace.visualstudio.com/items?itemName=stkb.rewrap) -
     Wrap lines at 80 characters with `Alt+Q`.
-*   ***Remote*** -
+*   [**Remote**](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) -
     Remotely connect to your workstation through SSH using your laptop. See the
     [Remote](#Remote) section for more information about how to set this up.
+*   [**GitLens**](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) -
+    Git supercharged. A Powerful, feature rich, and highly customizable git
+    extension.
 
 The following extensions might be useful for you as well:
 
-*   ***Annotator*** -
-    Git blame view.
-*   ***Git History (git log)*** -
-    Git history view.
-*   ***chromium-codesearch*** -
+```bash
+$ echo "wmaurer.change-case shd101wyy.markdown-preview-enhanced Gruntfuggly.todo-tree alefragnani.Bookmarks spmeesseman.vscode-taskexplorer streetsidesoftware.code-spell-checker tht13.html-preview-vscode anseki.vscode-color" | xargs -n 1 code --install-extension --force
+```
+
+*   **chromium-codesearch** -
     Mac and Linux only: adds ability to open the current line in [Chromium Code
     Search](https://cs.chromium.org/). All other functionality is deprecated, so
     currently only of limited usefulness.
-*   ***change-case*** -
+*   [**change-case**](https://marketplace.visualstudio.com/items?itemName=wmaurer.change-case) -
     Quickly change the case of the current selection or current word.
-*   ***Instant Markdown*** -
-    Instant markdown (.md) preview in your browser as you type. This document
-    was written with this extension!
+*   [**Markdown Preview Enhanced**](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced) -
+    Preview markdown side-by-side with automatic scroll sync and many other
+    features with `ctrl+k v`. This document was written with this extension!
+*   [**Todo Tree**](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree) -
+    Displays comment tags like TODO/FIXME in a tree view in a dedicated sidebar.
+*   [**Bookmarks**](https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks) -
+    Supports easy mark/unmark positions in the codebase and displays them in a
+    dedicated sidebar. Very useful for a large codebase like Chromium.
+*   [**Task Explorer**](https://marketplace.visualstudio.com/items?itemName=spmeesseman.vscode-taskexplorer) -
+    Displays supported tasks, e.g. vscode tasks, shell scripts and others,
+    organized into a treeview in sidebar.
+*   [**Code Spell Checker**](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) -
+    A basic spell checker that works well with camelCase code. It helps catch
+    common spelling errors.
+*   [**HTML Preview**](https://marketplace.visualstudio.com/items?itemName=tht13.html-preview-vscode) -
+    Previews HTML files while editing with `ctrl+k v`.
+*   [**Color Picker**](https://marketplace.visualstudio.com/items?itemName=anseki.vscode-color) -
+    Visualizes color codes inline and provides color picker GUI to generates new
+    color codes.
+
 
 Also be sure to take a look at the
 [VS Code marketplace](https://marketplace.visualstudio.com/VSCode) to check out
 other useful extensions.
 
 ### Color Scheme
+
 Press `Ctrl+Shift+P, color, Enter` to pick a color scheme for the editor. There
 are also tons of [color schemes available for download on the
 marketplace](https://marketplace.visualstudio.com/search?target=VSCode&category=Themes&sortBy=Downloads).
 
-### Usage Tips
+### Keyboard Shortcuts
+
+#### CheatSheet
+
+*   [Windows](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf)
+*   [Mac](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf)
+
+#### Useful Shortcuts
+
 *   `Ctrl+P` opens a search box to find and open a file.
 *   `F1` or `Ctrl+Shift+P` opens a search box to find a command (e.g. Tasks: Run
     Task). Note: if you want to run one of the [Predefined tasks in
@@ -172,6 +217,11 @@
 *   `Ctrl+X` without anything selected cuts the current line. `Ctrl+V` pastes
     the line.
 
+*** aside
+Note: See also [Key Bindings for Visual Studio Code
+](https://code.visualstudio.com/docs/getstarted/keybindings).
+***
+
 ### Java/Android Support
 
 *Before anything*, add these to your settings.json.
@@ -189,6 +239,7 @@
 in "Extension Pack for Java".
 
 #### Setting up code completion/reference finding/etc.
+
 You'll need to generate a placeholder .classpath file and locate it. In order
 to generate it, right click on any Java source folder in the left panel and
 choose "Add folder to java source path". Its location will depend on whether
@@ -241,13 +292,14 @@
 introduction to VS Code customization.
 
 ### Workspace Settings
+
 Open the file [//tools/vscode/settings.json](/tools/vscode/settings.json),
 and check out the default settings there. Feel free to commit added or removed
 settings to enable better team development, or change settings locally to suit
 personal preference. Remember to replace `<full_path_to_your_home>`! To use
 these settings wholesale, enter the following commands into your terminal while
 at the src directory:
-```
+```bash
 $ mkdir .vscode/
 $ cp tools/vscode/settings.json .vscode
 ```
@@ -257,13 +309,14 @@
 replace any references to ${workspaceFolder} with the path to your `src/`.
 
 ### Tasks
+
 Next, we'll tell VS Code how to compile our code, run tests, and to read
 warnings and errors from the build output. Open the file
 [//tools/vscode/tasks.json](/tools/vscode/tasks.json). This will provide tasks
 to do basic things. You might have to adjust the commands to your situation and
 needs. To use these settings wholesale, enter the following command into your
 terminal:
-```
+```bash
 $ cp tools/vscode/tasks.json .vscode
 ```
 
@@ -299,6 +352,7 @@
 the 8 key.
 
 ### Launch Commands
+
 Launch commands are the equivalent of `F5` in Visual Studio: They launch some
 program or a debugger. Optionally, they can run some task defined in
 `tasks.json`. Launch commands can be run from the debug view (`Ctrl+Shift+D`).
@@ -306,11 +360,13 @@
 adjust the example launch commands to your situation and needs (e.g., the value
 of "type" needs adjustment for Windows). To use these settings wholesale, enter
 the following command into your terminal:
-```
+
+```bash
 $ cp tools/vscode/launch.json .vscode
 ```
 
 ### Key Bindings
+
 To edit key bindings, press `Ctrl+K, Ctrl+S`. You'll see the defaults on the
 left and your overrides on the right stored in the file `keybindings.json`. To
 change a key binding, copy the corresponding key binding to the right. It's
@@ -333,14 +389,20 @@
 [//tools/vscode/keybindings.json](/tools/vscode/keybindings.json). Please
 take a look and adjust them to your situation and needs. To use these settings
 wholesale, enter the following command into your terminal:
-```
+
+```bash
 $ cp tools/vscode/keybindings.json .vscode
 ```
 
 ### Remote
-VSCode now has a
+
+*** promo
+Googlers: See [go/vscode-remote](http://go/vscode-remote).
+***
+
+VS Code now has a
 [Remote](https://code.visualstudio.com/docs/remote/remote-overview) framework
-that allows you to use VSCode on your laptop while your code is hosted
+that allows you to use VS Code on your laptop while your code is hosted
 elsewhere. This really shines when used in conjunction with the vscode-clangd plugin,
 which allows clangd to run remotely as well.
 
@@ -353,10 +415,10 @@
   HostName my-remote-host.corp.company.com
 ```
 
-VSCode will then list this connection in the 'Remote Explorer' section on the
-left. To launch VSCode with this connection, click on the '+window' icon next
+VS Code will then list this connection in the 'Remote Explorer' section on the
+left. To launch VS Code with this connection, click on the '+window' icon next
 to the listed hostname. It has you choose a folder - use the 'src' folder root.
-This will open a new VSCode window in 'Remote' mode. ***Now you can install
+This will open a new VS Code window in 'Remote' mode. ***Now you can install
 extensions specifically for your remote connection, like vscode-clangd, etc.***
 
 #### Chromebooks
@@ -367,9 +429,10 @@
 
 #### Windows & SSH
 
-VSCode remote tools requires 'sshd' which isn't installed on Windows by default.
+VS Code remote tools requires 'sshd' which isn't installed on Windows by
+default.
 
-For Googlers, sshd should already be installed on your workstation, and VSCode
+For Googlers, sshd should already be installed on your workstation, and VS Code
 should work remotely if you followed the setup instructions at
 [go/building-chrome-win](http://go/building-chrome-win). If you are still having
 problems, please refer to
@@ -377,7 +440,7 @@
 
 Non-Googlers may follow may follow Microsoft's instructions for
 [installing the OpenSSH server](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse).
-VSCode should work remotely after following this step.
+VS Code should work remotely after following this step.
 
 ### Snippets
 
@@ -386,19 +449,20 @@
 
 You can either install them in your user profile (path may vary depending on the
 platform):
-```
+```bash
 $ mkdir -p ~/.config/Code/User/snippets
 $ cp tools/vscode/cpp.json ~/.config/Code/User/snippets
 ```
 
 Or install them as project snippets:
-```
+```bash
 $ cp tools/vscode/cpp.json .vscode/cpp.code-snippets
 ```
 
 ### Tips
 
 #### The `out` folder
+
 Automatically generated code is put into a subfolder of out/, which means that
 these files are ignored by VS Code (see files.exclude above) and cannot be
 opened e.g. from quick-open (`Ctrl+P`).
@@ -421,12 +485,14 @@
 in files.exclude instead of the symlink.
 
 #### Using VS Code as git editor
+
 Add `[core] editor = "code --wait"` to your `~/.gitconfig` file in order to use
 VS Code as editor for git commit messages etc. Note that the editor starts up
 significantly slower than nano or vim. To use VS Code as merge tool, add
 `[merge] tool = code`.
 
 #### Task Names
+
 Note that we named the tasks `1-build_chrome_debug`, `2-build_chrome_release`
 etc. This allows you to quickly execute tasks by pressing their number:
 Press `Ctrl+P` and enter `task <n>`, where `<n>` is the number of the task. You
@@ -436,6 +502,7 @@
 sufficient to press `Ctrl+R` and enter `<n>`.
 
 #### Working on Laptop
+
 You might want to disable git status autorefresh to save battery.
 
 ```
@@ -443,6 +510,7 @@
 ```
 
 #### Editing in multiple Git repositories
+
 If you frequently work in multiple Git repositories that are part of the Chromium repository, you might find that the built-in tooling does not work as expected for files that exist below folders that are part of a `.gitignore` file checked in to Chromium.
 
 To work around this, you can add the directories you edit as separate `folders` entries in your workspace configuration, and ensure that the directories that are ignored in Chromium are listed **before** the Chromium `src` path.
@@ -463,16 +531,13 @@
 ```
 
 ### Unable to open $File resource is not available when debugging Chromium on Linux
+
 Chromium [recently changed](https://docs.google.com/document/d/1OX4jY_bOCeNK7PNjVRuBQE9s6BQKS8XRNWGK8FEyh-E/edit?usp=sharing)
 the file path to be relative to the output dir. Check
 `gn args out/$dir --list` if `strip_absolute_paths_from_debug_symbols` is true (which is the default),
 set `cwd` to the output dir. otherwise, set `cwd` to `${workspaceRoot}`.
 
-### You-Complete-Me
-The You-Complete-Me VS Code extension is now
-[deprecated](https://github.com/richard1122/vscode-youcompleteme#deprecated)
-with a suggestion to use clangd.
-
 ### More
+
 More tips and tricks can be found
 [here](https://github.com/Microsoft/vscode-tips-and-tricks/blob/master/README.md).
diff --git a/extensions/browser/extension_prefs.h b/extensions/browser/extension_prefs.h
index bec149b..2ab0738 100644
--- a/extensions/browser/extension_prefs.h
+++ b/extensions/browser/extension_prefs.h
@@ -58,6 +58,7 @@
 class AppSorting;
 class EarlyExtensionPrefsObserver;
 class ExtensionPrefsObserver;
+class PermissionSet;
 class URLPatternSet;
 
 // Class for managing global and per-extension preferences.
diff --git a/extensions/browser/notification_types.h b/extensions/browser/notification_types.h
index 579d25d..04ab1f2 100644
--- a/extensions/browser/notification_types.h
+++ b/extensions/browser/notification_types.h
@@ -38,11 +38,6 @@
   // TODO(https://crbug.com/1174728): Remove.
   NOTIFICATION_CRX_INSTALLER_DONE = NOTIFICATION_EXTENSIONS_START,
 
-  // Sent when an extension's permissions change. The details are an
-  // UpdatedExtensionPermissionsInfo, and the source is a BrowserContext*.
-  // TODO(https://crbug.com/1174733): Remove.
-  NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
-
   // An error occurred during extension install. The details are a string with
   // details about why the install failed.
   // TODO(https://crbug.com/1174734): Remove.
diff --git a/extensions/browser/permissions_manager.cc b/extensions/browser/permissions_manager.cc
index cda3fb4..6b296f4 100644
--- a/extensions/browser/permissions_manager.cc
+++ b/extensions/browser/permissions_manager.cc
@@ -142,6 +142,12 @@
 
 }  // namespace
 
+UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
+    const Extension* extension,
+    const PermissionSet& permissions,
+    Reason reason)
+    : reason(reason), extension(extension), permissions(permissions) {}
+
 // Implementation of UserPermissionsSettings.
 PermissionsManager::UserPermissionsSettings::UserPermissionsSettings() =
     default;
@@ -574,6 +580,13 @@
       std::move(new_explicit_hosts), std::move(new_scriptable_hosts));
 }
 
+void PermissionsManager::NotifyExtensionPermissionsUpdated(
+    const UpdatedExtensionPermissionsInfo& info) {
+  for (Observer& observer : observers_) {
+    observer.OnExtensionPermissionsUpdated(info);
+  }
+}
+
 void PermissionsManager::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
@@ -676,7 +689,7 @@
 
 void PermissionsManager::NotifyObserversOfChange() {
   for (auto& observer : observers_)
-    observer.UserPermissionsSettingsChanged(GetUserPermissionsSettings());
+    observer.OnUserPermissionsSettingsChanged(GetUserPermissionsSettings());
 }
 
 }  // namespace extensions
diff --git a/extensions/browser/permissions_manager.h b/extensions/browser/permissions_manager.h
index e6150c4..14fac59 100644
--- a/extensions/browser/permissions_manager.h
+++ b/extensions/browser/permissions_manager.h
@@ -30,6 +30,29 @@
 class Extension;
 class PermissionSet;
 
+// TODO(crbug.com/1343623): This no longer needs to be a struct.
+struct UpdatedExtensionPermissionsInfo {
+  enum Reason {
+    ADDED,    // The permissions were added to the extension.
+    REMOVED,  // The permissions were removed from the extension.
+    POLICY,   // The policy that affects permissions was updated.
+  };
+
+  Reason reason;
+
+  // The extension whose permissions have changed.
+  raw_ptr<const Extension> extension;
+
+  // The permissions that have changed. For Reason::ADDED, this would contain
+  // only the permissions that have added, and for Reason::REMOVED, this would
+  // only contain the removed permissions.
+  const PermissionSet& permissions;
+
+  UpdatedExtensionPermissionsInfo(const Extension* extension,
+                                  const PermissionSet& permissions,
+                                  Reason reason);
+};
+
 // Class for managing user-scoped extension permissions.
 // Includes blocking all extensions from running on a site and automatically
 // running all extensions on a site.
@@ -65,12 +88,12 @@
     // The extension has access to all sites (or a pattern sufficiently broad
     // as to be functionally similar, such as https://*.com/*). Note that since
     // this includes "broad" patterns, this may be true even if
-    // |has_site_access| is false.
+    // `has_site_access` is false.
     bool has_all_sites_access = false;
     // The extension wants access to all sites (or a pattern sufficiently broad
     // as to be functionally similar, such as https://*.com/*). Note that since
     // this includes "broad" patterns, this may be true even if
-    // |withheld_site_access| is false.
+    // `withheld_site_access` is false.
     bool withheld_all_sites_access = false;
   };
 
@@ -87,8 +110,10 @@
 
   class Observer {
    public:
-    virtual void UserPermissionsSettingsChanged(
+    virtual void OnUserPermissionsSettingsChanged(
         const UserPermissionsSettings& settings) {}
+    virtual void OnExtensionPermissionsUpdated(
+        const UpdatedExtensionPermissionsInfo& info) {}
   };
 
   explicit PermissionsManager(content::BrowserContext* browser_context);
@@ -165,6 +190,11 @@
       const Extension& extension,
       const PermissionSet& desired_permissions) const;
 
+  // Notifies `observers_` that the permissions have been updated for an
+  // extension.
+  void NotifyExtensionPermissionsUpdated(
+      const UpdatedExtensionPermissionsInfo& info);
+
   // Adds or removes observers.
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc
index ff4412d..1170f0c 100644
--- a/extensions/common/extension.cc
+++ b/extensions/common/extension.cc
@@ -867,10 +867,4 @@
 
 ExtensionInfo::~ExtensionInfo() {}
 
-UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
-    const Extension* extension,
-    const PermissionSet& permissions,
-    Reason reason)
-    : reason(reason), extension(extension), permissions(permissions) {}
-
 }   // namespace extensions
diff --git a/extensions/common/extension.h b/extensions/common/extension.h
index 313ee0d..3cccb47 100644
--- a/extensions/common/extension.h
+++ b/extensions/common/extension.h
@@ -37,7 +37,6 @@
 
 namespace extensions {
 class HashedExtensionId;
-class PermissionSet;
 class PermissionsData;
 class PermissionsParser;
 
@@ -512,29 +511,6 @@
   mojom::ManifestLocation extension_location;
 };
 
-// The details sent for EXTENSION_PERMISSIONS_UPDATED notifications.
-struct UpdatedExtensionPermissionsInfo {
-  enum Reason {
-    ADDED,    // The permissions were added to the extension.
-    REMOVED,  // The permissions were removed from the extension.
-    POLICY,   // The policy that affects permissions was updated.
-  };
-
-  Reason reason;
-
-  // The extension who's permissions have changed.
-  raw_ptr<const Extension> extension;
-
-  // The permissions that have changed. For Reason::ADDED, this would contain
-  // only the permissions that have added, and for Reason::REMOVED, this would
-  // only contain the removed permissions.
-  const PermissionSet& permissions;
-
-  UpdatedExtensionPermissionsInfo(const Extension* extension,
-                                  const PermissionSet& permissions,
-                                  Reason reason);
-};
-
 }  // namespace extensions
 
 #endif  // EXTENSIONS_COMMON_EXTENSION_H_
diff --git a/extensions/renderer/bindings/api_binding_hooks.cc b/extensions/renderer/bindings/api_binding_hooks.cc
index b806dd04..719e90b 100644
--- a/extensions/renderer/bindings/api_binding_hooks.cc
+++ b/extensions/renderer/bindings/api_binding_hooks.cc
@@ -351,7 +351,8 @@
   if (delegate_) {
     RequestResult result = delegate_->HandleRequest(
         method_name, signature, context, arguments, type_refs);
-    // If the native hooks handled the call or set a custom callback, use that.
+    // If the native hooks handled the call, set a custom callback or a result
+    // modifier, use that.
     if (result.code != RequestResult::NOT_HANDLED ||
         !result.custom_callback.IsEmpty()) {
       return result;
diff --git a/extensions/renderer/bindings/api_response_validator.cc b/extensions/renderer/bindings/api_response_validator.cc
index 59cdb2e..ad6a2fc 100644
--- a/extensions/renderer/bindings/api_response_validator.cc
+++ b/extensions/renderer/bindings/api_response_validator.cc
@@ -121,6 +121,8 @@
       "chromeWebViewInternal.onClicked",
       "inputMethodPrivate.onFocus",
       "test.onMessage",
+      // https://crbug.com/1343611.
+      "runtime.onMessage",
   };
 
   if (base::ranges::find(kBrokenSignaturesToIgnore, event_name) !=
diff --git a/extensions/test/permissions_manager_waiter.cc b/extensions/test/permissions_manager_waiter.cc
index 2f47fed..5237b0d 100644
--- a/extensions/test/permissions_manager_waiter.cc
+++ b/extensions/test/permissions_manager_waiter.cc
@@ -13,13 +13,31 @@
 
 PermissionsManagerWaiter::~PermissionsManagerWaiter() = default;
 
-void PermissionsManagerWaiter::WaitForPermissionsChange() {
-  run_loop_.Run();
+void PermissionsManagerWaiter::WaitForUserPermissionsSettingsChange() {
+  user_permissions_settings_changed_run_loop_.Run();
 }
 
-void PermissionsManagerWaiter::UserPermissionsSettingsChanged(
+void PermissionsManagerWaiter::WaitForExtensionPermissionsUpdate() {
+  extension_permissions_update_run_loop_.Run();
+}
+
+void PermissionsManagerWaiter::WaitForExtensionPermissionsUpdate(
+    base::OnceCallback<void(const UpdatedExtensionPermissionsInfo&)> callback) {
+  extension_permissions_update_callback_ = std::move(callback);
+  WaitForExtensionPermissionsUpdate();
+}
+
+void PermissionsManagerWaiter::OnUserPermissionsSettingsChanged(
     const PermissionsManager::UserPermissionsSettings& settings) {
-  run_loop_.Quit();
+  user_permissions_settings_changed_run_loop_.Quit();
+}
+
+void PermissionsManagerWaiter::OnExtensionPermissionsUpdated(
+    const UpdatedExtensionPermissionsInfo& info) {
+  if (extension_permissions_update_callback_) {
+    std::move(extension_permissions_update_callback_).Run(info);
+  }
+  extension_permissions_update_run_loop_.Quit();
 }
 
 }  // namespace extensions
diff --git a/extensions/test/permissions_manager_waiter.h b/extensions/test/permissions_manager_waiter.h
index 1a7e7f4..90c45c6 100644
--- a/extensions/test/permissions_manager_waiter.h
+++ b/extensions/test/permissions_manager_waiter.h
@@ -20,17 +20,27 @@
   ~PermissionsManagerWaiter();
 
   // Waits until permissions change.
-  void WaitForPermissionsChange();
+  void WaitForUserPermissionsSettingsChange();
+  void WaitForExtensionPermissionsUpdate();
+  // `callback` is called after waiting for an update.
+  void WaitForExtensionPermissionsUpdate(
+      base::OnceCallback<void(const UpdatedExtensionPermissionsInfo&)>
+          callback);
 
  private:
   // PermissionsManager::Observer:
-  void UserPermissionsSettingsChanged(
+  void OnUserPermissionsSettingsChanged(
       const PermissionsManager::UserPermissionsSettings& settings) override;
+  void OnExtensionPermissionsUpdated(
+      const UpdatedExtensionPermissionsInfo& info) override;
 
-  base::RunLoop run_loop_;
+  base::RunLoop user_permissions_settings_changed_run_loop_;
+  base::RunLoop extension_permissions_update_run_loop_;
   base::ScopedObservation<extensions::PermissionsManager,
                           extensions::PermissionsManager::Observer>
       manager_observation_{this};
+  base::OnceCallback<void(const UpdatedExtensionPermissionsInfo&)>
+      extension_permissions_update_callback_;
 };
 
 }  // namespace extensions
diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc
index 9e79f7e4..b02ab8b6 100644
--- a/gin/v8_platform.cc
+++ b/gin/v8_platform.cc
@@ -371,7 +371,7 @@
 // We only have a reservation on 32-bit Windows systems.
 // TODO(bbudge) Make the #if's in BlinkInitializer match.
 #if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_32_BITS)
-  base::ReleaseReservation();
+  partition_alloc::ReleaseReservation();
 #endif
 }
 
diff --git a/gin/v8_platform_page_allocator.cc b/gin/v8_platform_page_allocator.cc
index 2345b2d7..73dfd87 100644
--- a/gin/v8_platform_page_allocator.cc
+++ b/gin/v8_platform_page_allocator.cc
@@ -74,13 +74,14 @@
                                    size_t length,
                                    size_t alignment,
                                    v8::PageAllocator::Permission permissions) {
-  base::PageAccessibilityConfiguration config = GetPageConfig(permissions);
-  return base::AllocPages(address, length, alignment, config,
-                          base::PageTag::kV8);
+  partition_alloc::PageAccessibilityConfiguration config =
+      GetPageConfig(permissions);
+  return partition_alloc::AllocPages(address, length, alignment, config,
+                                     partition_alloc::PageTag::kV8);
 }
 
 bool PageAllocator::FreePages(void* address, size_t length) {
-  base::FreePages(address, length);
+  partition_alloc::FreePages(address, length);
   return true;
 }
 
@@ -92,12 +93,12 @@
   size_t release_size = length - new_length;
 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
   // On POSIX, we can unmap the trailing pages.
-  base::FreePages(release_base, release_size);
+  partition_alloc::FreePages(release_base, release_size);
 #elif BUILDFLAG(IS_WIN)
   // On Windows, we can only de-commit the trailing pages. FreePages() will
   // still free all pages in the region including the released tail, so it's
   // safe to just decommit the tail.
-  base::DecommitSystemPages(
+  partition_alloc::DecommitSystemPages(
       release_base, release_size,
       ::partition_alloc::PageAccessibilityDisposition::kRequireUpdate);
 #else
@@ -115,38 +116,39 @@
     // optimization, to avoid perf regression (see crrev.com/c/2563038 for
     // details). This may cause the memory region to still be accessible on
     // certain platforms, but at least the physical pages will be discarded.
-    base::DecommitSystemPages(
+    partition_alloc::DecommitSystemPages(
         address, length,
         ::partition_alloc::PageAccessibilityDisposition::kAllowKeepForPerf);
     return true;
   } else {
-    return base::TrySetSystemPagesAccess(address, length,
-                                         GetPageConfig(permissions));
+    return partition_alloc::TrySetSystemPagesAccess(address, length,
+                                                    GetPageConfig(permissions));
   }
 }
 
 bool PageAllocator::RecommitPages(void* address,
                                   size_t length,
                                   Permission permissions) {
-  base::RecommitSystemPages(
+  partition_alloc::RecommitSystemPages(
       reinterpret_cast<uintptr_t>(address), length, GetPageConfig(permissions),
-      base::PageAccessibilityDisposition::kAllowKeepForPerf);
+      partition_alloc::PageAccessibilityDisposition::kAllowKeepForPerf);
   return true;
 }
 
 bool PageAllocator::DiscardSystemPages(void* address, size_t size) {
-  base::DiscardSystemPages(address, size);
+  partition_alloc::DiscardSystemPages(address, size);
   return true;
 }
 
 bool PageAllocator::DecommitPages(void* address, size_t size) {
   // V8 expects the pages to be inaccessible and zero-initialized upon next
   // access.
-  base::DecommitAndZeroSystemPages(address, size);
+  partition_alloc::DecommitAndZeroSystemPages(address, size);
   return true;
 }
 
-base::PageAccessibilityConfiguration PageAllocator::GetPageConfigForTesting(
+partition_alloc::PageAccessibilityConfiguration
+PageAllocator::GetPageConfigForTesting(
     v8::PageAllocator::Permission permission) {
   return GetPageConfig(permission);
 }
diff --git a/gpu/command_buffer/client/shared_memory_limits.h b/gpu/command_buffer/client/shared_memory_limits.h
index d3e13c08..238785d 100644
--- a/gpu/command_buffer/client/shared_memory_limits.h
+++ b/gpu/command_buffer/client/shared_memory_limits.h
@@ -21,7 +21,7 @@
     // Do not use more than 5% of extra shared memory, and do not use any extra
     // for memory contrained devices (<=1GB).
     max_mapped_memory_for_texture_upload =
-        base::SysInfo::AmountOfPhysicalMemory() > 1024ULL * 1024 * 1024
+        base::SysInfo::AmountOfPhysicalMemory() > 1024 * 1024 * 1024
             ? base::saturated_cast<uint32_t>(
                   base::SysInfo::AmountOfPhysicalMemory() / 20)
             : 0;
diff --git a/gpu/command_buffer/service/shared_image_backing_d3d.cc b/gpu/command_buffer/service/shared_image_backing_d3d.cc
index 6e4e5a64..022f089 100644
--- a/gpu/command_buffer/service/shared_image_backing_d3d.cc
+++ b/gpu/command_buffer/service/shared_image_backing_d3d.cc
@@ -399,9 +399,8 @@
   dxgi_shared_handle_state_.reset();
   swap_chain_.Reset();
   d3d11_texture_.Reset();
-
 #if BUILDFLAG(USE_DAWN)
-  external_image_ = nullptr;
+  dawn_external_images_.clear();
 #endif  // BUILDFLAG(USE_DAWN)
 }
 
@@ -650,7 +649,9 @@
       reinterpret_cast<WGPUChainedStruct*>(&internalDesc);
 
   // Persistently open the shared handle by caching it on this backing.
-  if (!external_image_) {
+  auto it = dawn_external_images_.find(device);
+  dawn::native::d3d12::ExternalImageDXGI* external_image_ptr = nullptr;
+  if (it == dawn_external_images_.end()) {
     DCHECK(dxgi_shared_handle_state_);
     const HANDLE shared_handle = dxgi_shared_handle_state_->GetSharedHandle();
     DCHECK(base::win::HandleTraits::IsHandleValid(shared_handle));
@@ -660,17 +661,21 @@
     externalImageDesc.cTextureDescriptor = &texture_descriptor;
     externalImageDesc.sharedHandle = shared_handle;
 
-    external_image_ = dawn::native::d3d12::ExternalImageDXGI::Create(
-        device, &externalImageDesc);
-
-    if (!external_image_) {
+    std::unique_ptr<dawn::native::d3d12::ExternalImageDXGI> external_image =
+        dawn::native::d3d12::ExternalImageDXGI::Create(device,
+                                                       &externalImageDesc);
+    if (!external_image) {
       LOG(ERROR) << "Failed to create external image";
       return nullptr;
     }
+    external_image_ptr = external_image.get();
+    dawn_external_images_.emplace(device, std::move(external_image));
+  } else {
+    external_image_ptr = it->second.get();
   }
-
+  DCHECK(external_image_ptr);
   return std::make_unique<SharedImageRepresentationDawnD3D>(
-      manager, this, tracker, device, external_image_.get());
+      manager, this, tracker, device, external_image_ptr);
 #else
   return nullptr;
 #endif  // BUILDFLAG(USE_DAWN)
diff --git a/gpu/command_buffer/service/shared_image_backing_d3d.h b/gpu/command_buffer/service/shared_image_backing_d3d.h
index d25d735..c749a5b 100644
--- a/gpu/command_buffer/service/shared_image_backing_d3d.h
+++ b/gpu/command_buffer/service/shared_image_backing_d3d.h
@@ -194,10 +194,12 @@
   // Set if this backing corresponds to the back buffer of |swap_chain_|.
   const bool is_back_buffer_;
 
-  // If external_image_ exists, it means Dawn produced the D3D12 side of the
+  // If an external image exists, it means Dawn produced the D3D12 side of the
   // D3D11 texture created by ID3D12Device::OpenSharedHandle.
 #if BUILDFLAG(USE_DAWN)
-  std::unique_ptr<dawn::native::d3d12::ExternalImageDXGI> external_image_;
+  base::flat_map<WGPUDevice,
+                 std::unique_ptr<dawn::native::d3d12::ExternalImageDXGI>>
+      dawn_external_images_;
 #endif  // BUILDFLAG(USE_DAWN)
 
   // Staging texture used for copy to/from shared memory GMB.
diff --git a/gpu/config/skia_limits.cc b/gpu/config/skia_limits.cc
index 390f820..ee23325 100644
--- a/gpu/config/skia_limits.cc
+++ b/gpu/config/skia_limits.cc
@@ -30,7 +30,7 @@
   // Limits for glyph cache textures.
   constexpr size_t kMaxLowEndGlyphCacheTextureBytes = 1024 * 512 * 4;
   // High-end / low-end memory cutoffs.
-  constexpr uint64_t kHighEndMemoryThreshold = 4096ULL * 1024 * 1024;
+  constexpr int64_t kHighEndMemoryThreshold = 4096LL * 1024 * 1024;
 
   if (base::SysInfo::IsLowEndDevice()) {
     *max_resource_cache_bytes = kMaxLowEndGaneshResourceCacheBytes;
diff --git a/infra/config/generated/builders/ci/lacros-arm64-generic-rel/properties.json b/infra/config/generated/builders/ci/lacros-arm64-generic-rel/properties.json
new file mode 100644
index 0000000..abdc7c7
--- /dev/null
+++ b/infra/config/generated/builders/ci/lacros-arm64-generic-rel/properties.json
@@ -0,0 +1,69 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "lacros-arm64-generic-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": "arm",
+                "target_bits": 64,
+                "target_cros_boards": [
+                  "arm64-generic"
+                ],
+                "target_platform": "chromeos"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "checkout_lacros_sdk",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "lacros-arm64-generic-rel",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "lacros-arm64-generic-rel",
+          "group": "tryserver.chromium.chromiumos"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 500,
+    "metrics_project": "chromium-reclient-metrics"
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "chromium.chromiumos",
+  "recipe": "chromium"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-arm64-generic-rel/properties.json b/infra/config/generated/builders/try/lacros-arm64-generic-rel/properties.json
new file mode 100644
index 0000000..5f7bc524
--- /dev/null
+++ b/infra/config/generated/builders/try/lacros-arm64-generic-rel/properties.json
@@ -0,0 +1,64 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "lacros-arm64-generic-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": "arm",
+                "target_bits": 64,
+                "target_cros_boards": [
+                  "arm64-generic"
+                ],
+                "target_platform": "chromeos"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "checkout_lacros_sdk",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "lacros-arm64-generic-rel",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
+  "$build/goma": {
+    "enable_ats": true,
+    "rpc_extra_params": "?prod",
+    "server_host": "goma.chromium.org",
+    "use_luci_auth": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.chromiumos",
+  "recipe": "chromium_trybot"
+}
\ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index b65b38f..8a4a383 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -2385,6 +2385,10 @@
         }
       }
       builders {
+        name: "chromium/try/lacros-arm64-generic-rel"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/layout_test_leak_detection"
         includable_only: true
       }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 67307ed..63f36d0 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -2211,246 +2211,6 @@
       }
     }
     builders {
-      name: "Build Perf Android"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:32"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Ubuntu-18.04"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:1"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/goma": {'
-        '    "enable_ats": true,'
-        '    "rpc_extra_params": "?prod",'
-        '    "server_host": "goma.chromium.org",'
-        '    "use_luci_auth": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-trusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.fyi",'
-        '  "recipe": "build_perf"'
-        '}'
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_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_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-    }
-    builders {
-      name: "Build Perf Linux"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:16"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Ubuntu-18.04"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:1"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/goma": {'
-        '    "enable_ats": true,'
-        '    "rpc_extra_params": "?prod",'
-        '    "server_host": "goma.chromium.org",'
-        '    "use_luci_auth": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-trusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.fyi",'
-        '  "recipe": "build_perf"'
-        '}'
-      execution_timeout_secs: 21600
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_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_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-    }
-    builders {
-      name: "Build Perf Windows"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:32"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:high"
-      dimensions: "os:Windows-10"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:1"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/goma": {'
-        '    "enable_ats": true,'
-        '    "rpc_extra_params": "?prod",'
-        '    "server_host": "goma.chromium.org",'
-        '    "use_luci_auth": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-trusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.fyi",'
-        '  "recipe": "build_perf"'
-        '}'
-      execution_timeout_secs: 21600
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_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_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-    }
-    builders {
       name: "CFI Linux CF"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -28915,6 +28675,165 @@
       }
     }
     builders {
+      name: "build-perf-android"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:32"
+      dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.ci"
+      dimensions: "ssd:1"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/goma": {'
+        '    "enable_ats": true,'
+        '    "rpc_extra_params": "?prod",'
+        '    "server_host": "goma.chromium.org",'
+        '    "use_luci_auth": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-trusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.fyi",'
+        '  "recipe": "build_perf"'
+        '}'
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_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_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
+      name: "build-perf-linux"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:16"
+      dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.ci"
+      dimensions: "ssd:1"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/goma": {'
+        '    "enable_ats": true,'
+        '    "rpc_extra_params": "?prod",'
+        '    "server_host": "goma.chromium.org",'
+        '    "use_luci_auth": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-trusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.fyi",'
+        '  "recipe": "build_perf"'
+        '}'
+      execution_timeout_secs: 21600
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_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_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "chromeos-amd64-generic-asan-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -33961,6 +33880,86 @@
       }
     }
     builders {
+      name: "lacros-arm64-generic-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.ci"
+      dimensions: "ssd:0"
+      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/ci/lacros-arm64-generic-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "chromium.chromiumos",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium"'
+        '}'
+      execution_timeout_secs: 10800
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_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_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "lacros64-archive-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -64965,6 +64964,96 @@
       }
     }
     builders {
+      name: "lacros-arm64-generic-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:0"
+      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/lacros-arm64-generic-rel/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_trybot"'
+        '}'
+      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: "luci.recipes.use_python3"
+        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/.+"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "layout_test_leak_detection"
       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 448c9eb..6b1a625 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -380,6 +380,11 @@
     short_name: "arm"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/lacros-arm64-generic-rel"
+    category: "chromium.chromiumos|lacros|arm64"
+    short_name: "arm64"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/lacros-amd64-generic-binary-size-rel"
     category: "chromium.chromiumos|lacros|size"
   }
@@ -1099,6 +1104,11 @@
     short_name: "arm"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/lacros-arm64-generic-rel"
+    category: "chromium.chromiumos|lacros|arm64"
+    short_name: "arm64"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/chromeos-amd64-generic-lacros-dbg"
     category: "chromium.chromiumos|lacros|x64"
     short_name: "dbg"
@@ -2667,6 +2677,9 @@
     name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/linux-blink-rel"
   }
   builders {
@@ -5022,6 +5035,11 @@
     short_name: "arm"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/lacros-arm64-generic-rel"
+    category: "lacros|arm64"
+    short_name: "arm64"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/lacros-amd64-generic-binary-size-rel"
     category: "lacros|size"
   }
@@ -8000,21 +8018,16 @@
     short_name: "64rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Build Perf Android"
+    name: "buildbucket/luci.chromium.ci/build-perf-android"
     category: "buildperf"
     short_name: "and"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Build Perf Linux"
+    name: "buildbucket/luci.chromium.ci/build-perf-linux"
     category: "buildperf"
     short_name: "lnx"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Build Perf Windows"
-    category: "buildperf"
-    short_name: "win"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/android-fieldtrial-rel"
     category: "android"
   }
@@ -16333,6 +16346,9 @@
     name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/layout_test_leak_detection"
   }
   builders {
@@ -17234,6 +17250,9 @@
     name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/linux-cfm-rel"
   }
   builders {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index 333fb03b..58e7b30 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -346,36 +346,6 @@
   }
 }
 job {
-  id: "Build Perf Android"
-  realm: "ci"
-  acl_sets: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Build Perf Android"
-  }
-}
-job {
-  id: "Build Perf Linux"
-  realm: "ci"
-  acl_sets: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Build Perf Linux"
-  }
-}
-job {
-  id: "Build Perf Windows"
-  realm: "ci"
-  acl_sets: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Build Perf Windows"
-  }
-}
-job {
   id: "CFI Linux CF"
   realm: "ci"
   acl_sets: "ci"
@@ -4888,6 +4858,26 @@
   }
 }
 job {
+  id: "build-perf-android"
+  realm: "ci"
+  acl_sets: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "build-perf-android"
+  }
+}
+job {
+  id: "build-perf-linux"
+  realm: "ci"
+  acl_sets: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "build-perf-linux"
+  }
+}
+job {
   id: "chromeos-amd64-generic-asan-rel"
   realm: "ci"
   acl_sets: "ci"
@@ -5609,6 +5599,16 @@
   }
 }
 job {
+  id: "lacros-arm64-generic-rel"
+  realm: "ci"
+  acl_sets: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "lacros-arm64-generic-rel"
+  }
+}
+job {
   id: "lacros64-archive-rel"
   realm: "ci"
   acl_sets: "ci"
@@ -7123,9 +7123,6 @@
   triggers: "Android arm64 Builder All Targets (dbg)"
   triggers: "Android x64 Builder (dbg)"
   triggers: "Android x86 Builder (dbg)"
-  triggers: "Build Perf Android"
-  triggers: "Build Perf Linux"
-  triggers: "Build Perf Windows"
   triggers: "CFI Linux CF"
   triggers: "CFI Linux ToT"
   triggers: "Cast Android (dbg)"
@@ -7339,6 +7336,8 @@
   triggers: "android-weblayer-x86-rel"
   triggers: "android-webview-pie-x86-wpt-fyi-rel"
   triggers: "android-x86-rel"
+  triggers: "build-perf-android"
+  triggers: "build-perf-linux"
   triggers: "chromeos-amd64-generic-asan-rel"
   triggers: "chromeos-amd64-generic-cfi-thin-lto-rel"
   triggers: "chromeos-amd64-generic-dbg"
@@ -7395,6 +7394,7 @@
   triggers: "lacros-amd64-generic-rel-skylab-fyi"
   triggers: "lacros-arm-archive-rel"
   triggers: "lacros-arm-generic-rel"
+  triggers: "lacros-arm64-generic-rel"
   triggers: "lacros64-archive-rel"
   triggers: "linux-angle-builder"
   triggers: "linux-angle-chromium-builder"
diff --git a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
index eafd471..979dc51 100644
--- a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
@@ -601,6 +601,45 @@
 )
 
 ci.builder(
+    name = "lacros-arm64-generic-rel",
+    branch_selector = branches.STANDARD_MILESTONE,
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "checkout_lacros_sdk",
+                "chromeos",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_arch = builder_config.target_arch.ARM,
+            target_bits = 64,
+            target_cros_boards = [
+                "arm64-generic",
+            ],
+            target_platform = builder_config.target_platform.CHROMEOS,
+        ),
+        build_gs_bucket = "chromium-chromiumos-archive",
+    ),
+    console_view_entry = consoles.console_view_entry(
+        category = "lacros|arm64",
+        short_name = "arm64",
+    ),
+    cq_mirrors_console_view = "mirrors",
+    main_console_view = "main",
+    reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI,
+    # TODO(https://crbug.com/1342761): enable sheriff rotation and tree_closing
+    # when the builder is stable.
+    sheriff_rotations = args.ignore_default(None),
+    tree_closing = False,
+)
+
+ci.builder(
     name = "linux-chromeos-dbg",
     builder_spec = builder_config.builder_spec(
         gclient_config = builder_config.gclient_config(
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 4c4ed87..58844a6 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1056,7 +1056,7 @@
 # Sync specs with android-pie-arm64-rel-compilator
 # in chromium/try/tryserver.chromium.android.star
 ci.builder(
-    name = "Build Perf Android",
+    name = "build-perf-android",
     builderless = True,
     console_view_entry = consoles.console_view_entry(
         category = "buildperf",
@@ -1076,7 +1076,7 @@
 # Sync specs with linux-rel-compilator
 # in chromium/try/tryserver.chromium.linux.star
 ci.builder(
-    name = "Build Perf Linux",
+    name = "build-perf-linux",
     builderless = True,
     console_view_entry = consoles.console_view_entry(
         category = "buildperf",
@@ -1094,28 +1094,6 @@
     ssd = True,
 )
 
-# Sync specs with win10_chromium_x64_rel_ng-compilator
-# in chromium/try/tryserver.chromium.win.star
-ci.builder(
-    name = "Build Perf Windows",
-    builderless = True,
-    console_view_entry = consoles.console_view_entry(
-        category = "buildperf",
-        short_name = "win",
-    ),
-    executable = "recipe:build_perf",
-    execution_timeout = 6 * time.hour,
-    # TODO(b/234807316): Use CQ's RBE instance with a dedicated service account.
-    reclient_instance = rbe_instance.DEFAULT,
-    reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CQ,
-    use_clang_coverage = True,
-    # Target luci-chromium-ci-win10-us-east1-d-1500-ssd-32-*.
-    os = os.WINDOWS_DEFAULT,
-    cores = 32,
-    ssd = True,
-    free_space = builders.free_space.high,
-)
-
 ci.builder(
     name = "Linux Builder (j-500) (reclient)",
     console_view_entry = consoles.console_view_entry(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index 2eedb1e..65e82480 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -119,6 +119,15 @@
 )
 
 try_.builder(
+    name = "lacros-arm64-generic-rel",
+    mirrors = [
+        "ci/lacros-arm64-generic-rel",
+    ],
+    branch_selector = branches.STANDARD_MILESTONE,
+    main_list_view = "try",
+)
+
+try_.builder(
     name = "linux-chromeos-compile-dbg",
     mirrors = [
         "ci/linux-chromeos-dbg",
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index 8876046a..a197d93 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -254,6 +254,22 @@
   ]
 }
 
+source_set("feed_app_agent") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "feed_app_agent.h",
+    "feed_app_agent.mm",
+  ]
+  deps = [
+    "//base",
+    "//ios/chrome/app/application_delegate:app_state_header",
+    "//ios/chrome/app/application_delegate:observing_app_state_agent",
+    "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/discover_feed:discover_feed_factory",
+    "//ios/chrome/browser/ntp:features",
+  ]
+}
+
 source_set("app_internal") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
@@ -276,6 +292,7 @@
     ":app_metrics_app_state_agent",
     ":blocking_scene_commands",
     ":enterprise_app_agent",
+    ":feed_app_agent",
     ":first_run_app_state_agent",
     ":mode",
     ":safe_mode_app_state_agent",
diff --git a/ios/chrome/app/feed_app_agent.h b/ios/chrome/app/feed_app_agent.h
new file mode 100644
index 0000000..abbc84c
--- /dev/null
+++ b/ios/chrome/app/feed_app_agent.h
@@ -0,0 +1,16 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_APP_FEED_APP_AGENT_H_
+#define IOS_CHROME_APP_FEED_APP_AGENT_H_
+
+#import "ios/chrome/app/application_delegate/observing_app_state_agent.h"
+
+// The agent that manages the Feed service creation. This service allows the App
+// and users to perform Feed related operations e.g. Creating a Feed, Following
+// a Website, etc.
+@interface FeedAppAgent : SceneObservingAppAgent
+@end
+
+#endif  // IOS_CHROME_APP_FEED_APP_AGENT_H_
diff --git a/ios/chrome/app/feed_app_agent.mm b/ios/chrome/app/feed_app_agent.mm
new file mode 100644
index 0000000..4b7a93f
--- /dev/null
+++ b/ios/chrome/app/feed_app_agent.mm
@@ -0,0 +1,31 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/app/feed_app_agent.h"
+
+#import "ios/chrome/app/application_delegate/app_state.h"
+#import "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
+#import "ios/chrome/browser/ntp/features.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation FeedAppAgent
+
+#pragma mark - AppStateObserver
+
+- (void)appState:(AppState*)appState
+    willTransitionToInitStage:(InitStage)nextInitStage {
+  if (nextInitStage != InitStageFinal) {
+    return;
+  }
+
+  if (IsWebChannelsEnabled()) {
+    DiscoverFeedServiceFactory::GetForBrowserState(
+        self.appState.mainBrowserState);
+  }
+}
+
+@end
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 43332aa..82a2e59 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -42,6 +42,7 @@
 #import "ios/chrome/app/blocking_scene_commands.h"
 #import "ios/chrome/app/deferred_initialization_runner.h"
 #import "ios/chrome/app/enterprise_app_agent.h"
+#import "ios/chrome/app/feed_app_agent.h"
 #import "ios/chrome/app/first_run_app_state_agent.h"
 #import "ios/chrome/app/memory_monitor.h"
 #import "ios/chrome/app/safe_mode_app_state_agent.h"
@@ -695,6 +696,7 @@
   // Create app state agents.
   [appState addAgent:[[AppMetricsAppStateAgent alloc] init]];
   [appState addAgent:[[SafeModeAppAgent alloc] init]];
+  [appState addAgent:[[FeedAppAgent alloc] init]];
 
   // Create the window accessibility agent only when multiple windows are
   // possible.
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_egtest.mm b/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_egtest.mm
index c88fd5f1..320ef21 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_egtest.mm
+++ b/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_egtest.mm
@@ -30,6 +30,10 @@
 
 namespace {
 
+// Wait for 2 seconds longer than the default promo show time, in case it's
+// slightly delayed.
+const int64_t kShowPromoWebpageLoadWaitTime = 5;
+
 // Returns a matcher to "Link You Copied" row.
 id<GREYMatcher> LinkYouCopiedMatcher() {
   NSString* a11yLabelText = l10n_util::GetNSString(IDS_LINK_FROM_CLIPBOARD);
@@ -83,8 +87,19 @@
       performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:LinkYouCopiedMatcher()]
       performAction:grey_tap()];
-  [[EarlGrey selectElementWithMatcher:NonModalTitleMatcher()]
-      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Wait until the promo appears.
+  NSString* description = @"Wait for the promo to appear.";
+  ConditionBlock condition = ^{
+    NSError* error = nil;
+    [[EarlGrey selectElementWithMatcher:NonModalTitleMatcher()]
+        assertWithMatcher:grey_sufficientlyVisible()
+                    error:&error];
+    return (error == nil);
+  };
+  GREYAssert(
+      WaitUntilConditionOrTimeout(kShowPromoWebpageLoadWaitTime, condition),
+      description);
 }
 
 @end
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn
index 30d9cd82..0fe4a71 100644
--- a/ios/chrome/browser/ui/main/BUILD.gn
+++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -155,8 +155,6 @@
     "//ios/chrome/browser/crash_report:crash_report_internal",
     "//ios/chrome/browser/crash_report/breadcrumbs",
     "//ios/chrome/browser/default_browser",
-    "//ios/chrome/browser/discover_feed",
-    "//ios/chrome/browser/discover_feed:discover_feed_factory",
     "//ios/chrome/browser/first_run",
     "//ios/chrome/browser/geolocation",
     "//ios/chrome/browser/infobars",
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index c3602ef..e7d8749 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -53,8 +53,6 @@
 #include "ios/chrome/browser/crash_report/crash_report_helper.h"
 #import "ios/chrome/browser/crash_report/crash_restore_helper.h"
 #include "ios/chrome/browser/default_browser/promo_source.h"
-#import "ios/chrome/browser/discover_feed/discover_feed_service.h"
-#import "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
 #import "ios/chrome/browser/first_run/first_run.h"
 #import "ios/chrome/browser/geolocation/geolocation_logger.h"
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
@@ -730,12 +728,6 @@
     if (!IsStartSurfaceSplashStartupEnabled()) {
       [self handleShowStartSurfaceIfNecessary];
     }
-
-    if (IsWebChannelsEnabled()) {
-      // Creating the DiscoverFeedService.
-      DiscoverFeedServiceFactory::GetForBrowserState(
-          self.mainInterface.browser->GetBrowserState());
-    }
   }
 
   [self recordWindowCreationForSceneState:self.sceneState];
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn
index 2e8c8746..7d156d8 100644
--- a/ios/chrome/browser/ui/ntp/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -236,6 +236,8 @@
   sources = [
     "feed_metrics_recorder.h",
     "feed_metrics_recorder.mm",
+    "feed_session_recorder.h",
+    "feed_session_recorder.mm",
   ]
   deps = [
     ":ntp",
@@ -250,6 +252,7 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
+    "feed_session_recorder_unittest.mm",
     "new_tab_page_coordinator_unittest.mm",
     "notification_promo_whats_new_unittest.mm",
     "ntp_tile_saver_unittest.mm",
@@ -257,6 +260,7 @@
   deps = [
     ":coordinator",
     ":feature_flags",
+    ":metrics",
     ":ntp",
     ":ntp_internal",
     "//base",
diff --git a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm
index 9dd112e..06366ef 100644
--- a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm
+++ b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm
@@ -14,6 +14,7 @@
 #import "components/feed/core/v2/public/common_enums.h"
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h"
 #import "ios/chrome/browser/ui/ntp/feed_control_delegate.h"
+#import "ios/chrome/browser/ui/ntp/feed_session_recorder.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_follow_delegate.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -308,7 +309,8 @@
 }  // namespace
 
 @interface FeedMetricsRecorder ()
-
+// Helper for recording session time metrics.
+@property(nonatomic, strong) FeedSessionRecorder* sessionRecorder;
 // Tracking property to avoid duplicate recordings of
 // FeedEngagementType::kFeedEngagedSimple.
 @property(nonatomic, assign) BOOL engagedSimpleReportedDiscover;
@@ -328,6 +330,15 @@
 
 @implementation FeedMetricsRecorder
 
+#pragma mark - Properties
+
+- (FeedSessionRecorder*)sessionRecorder {
+  if (!_sessionRecorder) {
+    _sessionRecorder = [[FeedSessionRecorder alloc] init];
+  }
+  return _sessionRecorder;
+}
+
 #pragma mark - Public
 
 - (void)recordFeedScrolled:(int)scrollDistance {
@@ -893,6 +904,8 @@
   if (scrollDistance > kMinScrollThreshold || interacted) {
     [self recordEngaged];
   }
+
+  [self.sessionRecorder recordUserInteractionOrScrolling];
 }
 
 // Records any direct interaction with the Feed, this doesn't include scrolling.
diff --git a/ios/chrome/browser/ui/ntp/feed_session_recorder.h b/ios/chrome/browser/ui/ntp/feed_session_recorder.h
new file mode 100644
index 0000000..cfe8f547
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/feed_session_recorder.h
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_NTP_FEED_SESSION_RECORDER_H_
+#define IOS_CHROME_BROWSER_UI_NTP_FEED_SESSION_RECORDER_H_
+
+#import <Foundation/Foundation.h>
+
+// Records metrics related to user sessions in the feed.
+@interface FeedSessionRecorder : NSObject
+
+// Records metrics related to user sessions in the feed. This must be called at
+// every user interaction or scrolling event. Failure to do so will result in
+// inaccurate reporting.
+- (void)recordUserInteractionOrScrolling;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_NTP_FEED_SESSION_RECORDER_H_
diff --git a/ios/chrome/browser/ui/ntp/feed_session_recorder.mm b/ios/chrome/browser/ui/ntp/feed_session_recorder.mm
new file mode 100644
index 0000000..c2308cc
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/feed_session_recorder.mm
@@ -0,0 +1,169 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/ntp/feed_session_recorder.h"
+
+#import "base/mac/foundation_util.h"
+#import "base/metrics/histogram_functions.h"
+#import "base/metrics/histogram_macros.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// Histogram name to measure the duration of a feed session. Note that
+// `kSessionTimeout` directly affects how this is measured.
+const char kDiscoverFeedSessionDuration[] =
+    "ContentSuggestions.Feed.SessionDuration";
+
+// Histogram name to measure the time between user interactions (including
+// scrolling) in the feed. This can inform how we set `kSessionTimeout`.
+const char kDiscoverFeedTimeBetweenInteractions[] =
+    "ContentSuggestions.Feed.TimeBetweenInteractions";
+
+// Histogram name to measure the time between user sessions in the feed. Note
+// that `kSessionTimeout` directly affects how this is measured.
+const char kDiscoverFeedTimeBetweenSessions[] =
+    "ContentSuggestions.Feed.TimeBetweenSessions";
+
+// Key used to store the date (and time) of the user's previous interaction
+// (including scrolling) with the feed. Can be nil if this is a fresh install or
+// if there was an issue writing to NSUserDefaults.
+NSString* const kFeedPreviousInteractionDateKey =
+    @"DiscoverFeedPreviousInteractionDate";
+
+// Two interactions (including scrolling) are considered to be within the same
+// session if they are at most `kSessionTimeoutInSeconds` apart from each other.
+// Otherwise, the later interaction (including scrolling) is considered a new
+// session.
+const NSTimeInterval kSessionTimeoutInSeconds = 5 * 60;
+
+}  // namespace
+
+@interface FeedSessionRecorder ()
+
+// The date (and time) when the first interaction (including scrolling) was
+// recorded for the current session.
+@property(nonatomic, copy) NSDate* sessionStartDate;
+
+// The date (and time) of the previous interaction (including scrolling).
+@property(nonatomic, copy) NSDate* previousInteractionDate;
+
+// Session duration.
+@property(nonatomic, assign) NSTimeInterval sessionDurationInSeconds;
+
+// Time between sessions.
+@property(nonatomic, assign) NSTimeInterval secondsBetweenSessions;
+
+// Time between interactions.
+@property(nonatomic, assign) NSTimeInterval secondsBetweenInteractions;
+
+@end
+
+@implementation FeedSessionRecorder
+@synthesize previousInteractionDate = _previousInteractionDate;
+
+#pragma mark - Properties
+
+- (NSDate*)previousInteractionDate {
+  if (!_previousInteractionDate) {
+    // Reads from disk if there was a cold start and the property is nil.
+    // Disk value can be nil if this is a fresh install or if there was an issue
+    // writing to NSUserDefaults.
+    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+    _previousInteractionDate =
+        [defaults objectForKey:kFeedPreviousInteractionDateKey];
+  }
+  return _previousInteractionDate;
+}
+
+- (void)setPreviousInteractionDate:(NSDate*)previousInteractionDate {
+  // Sets both in-memory and disk memory at the same time.
+  _previousInteractionDate = previousInteractionDate;
+  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+  [defaults setObject:previousInteractionDate
+               forKey:kFeedPreviousInteractionDateKey];
+  [defaults synchronize];
+}
+
+#pragma mark - Public
+
+- (void)recordUserInteractionOrScrolling {
+  [self recordUserInteractionOrScrollingAtDate:[[NSDate alloc] init]];
+}
+
+#pragma mark - Helpers
+
+- (void)recordUserInteractionOrScrollingAtDate:(NSDate*)interactionDate {
+  if (!self.previousInteractionDate) {
+    // This probably means this is the first feed interaction since a new
+    // install. We cannot record session time metrics without this value so
+    // start a new session.
+    self.sessionStartDate = interactionDate;
+  } else {
+    [self
+        recordTimeBetweenInteractionsWithStartDate:self.previousInteractionDate
+                                           endDate:interactionDate];
+    // Determine if this interaction should start a new session.
+    NSTimeInterval previousInteractionAge =
+        [interactionDate timeIntervalSinceDate:self.previousInteractionDate];
+    if (previousInteractionAge > kSessionTimeoutInSeconds) {
+      // Close out current session.
+      [self recordSessionDurationWithStartDate:self.sessionStartDate
+                                       endDate:self.previousInteractionDate];
+      [self recordTimeBetweenSessionsWithStartDate:self.previousInteractionDate
+                                           endDate:interactionDate];
+      // Start a new session.
+      self.sessionStartDate = interactionDate;
+    }
+  }
+  // Reset the previous active time for session measurement.
+  self.previousInteractionDate = interactionDate;
+}
+
+// Records the session duration histogram. This tests our assumption that
+// session durations are only a few seconds long. Our goal is to increase this
+// over time. The histogram max value is 5 minutes. Session durations of 0
+// indicate that there was only a single interaction or scrolling.
+- (void)recordSessionDurationWithStartDate:(NSDate*)startDate
+                                   endDate:(NSDate*)endDate {
+  self.sessionDurationInSeconds = [endDate timeIntervalSinceDate:startDate];
+  const base::TimeDelta timeDelta =
+      base::Seconds(self.sessionDurationInSeconds);
+  UMA_HISTOGRAM_CUSTOM_TIMES(kDiscoverFeedSessionDuration, timeDelta,
+                             /*min=*/base::Milliseconds(0),
+                             /*max=*/base::Minutes(5), /*bucket_count=*/100);
+}
+
+// Records the time between sessions histogram (i.e., how long it takes for
+// users to return to a feed session). This can help us gauge how useful
+// prefetching can be. The time between sessions is by definition longer than 5
+// minutes. This histogram only captures those users who return to the feed
+// within a day. The histogram max is 24 hours.
+- (void)recordTimeBetweenSessionsWithStartDate:(NSDate*)startDate
+                                       endDate:(NSDate*)endDate {
+  self.secondsBetweenSessions = [endDate timeIntervalSinceDate:startDate];
+  const base::TimeDelta timeDelta = base::Seconds(self.secondsBetweenSessions);
+  UMA_HISTOGRAM_CUSTOM_TIMES(kDiscoverFeedTimeBetweenSessions, timeDelta,
+                             /*min=*/base::Minutes(5),
+                             /*max=*/base::Hours(24), /*bucket_count=*/50);
+}
+
+// Records the time between interactions (including scrolling) histogram. We
+// expect interactions within a single session to be within a few seconds to a
+// minute or two of each other. We want to test if 5 minutes is the right
+// session timeout value. The histogram max value is 10 minutes.
+- (void)recordTimeBetweenInteractionsWithStartDate:(NSDate*)startDate
+                                           endDate:(NSDate*)endDate {
+  self.secondsBetweenInteractions = [endDate timeIntervalSinceDate:startDate];
+  const base::TimeDelta timeDelta =
+      base::Seconds(self.secondsBetweenInteractions);
+  UMA_HISTOGRAM_CUSTOM_TIMES(kDiscoverFeedTimeBetweenInteractions, timeDelta,
+                             /*min=*/base::Milliseconds(1),
+                             /*max=*/base::Minutes(10), /*bucket_count=*/50);
+}
+
+@end
diff --git a/ios/chrome/browser/ui/ntp/feed_session_recorder_unittest.mm b/ios/chrome/browser/ui/ntp/feed_session_recorder_unittest.mm
new file mode 100644
index 0000000..46ac46a
--- /dev/null
+++ b/ios/chrome/browser/ui/ntp/feed_session_recorder_unittest.mm
@@ -0,0 +1,104 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/ntp/feed_session_recorder.h"
+
+#import <Foundation/Foundation.h>
+
+#import "testing/gtest/include/gtest/gtest.h"
+#import "testing/gtest_mac.h"
+#import "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+// Category for exposing properties and methods for testing.
+@interface FeedSessionRecorder (Testing)
+// Exposing the recorded session duration.
+@property(nonatomic, assign) NSTimeInterval sessionDurationInSeconds;
+// Exposing the recorded time between sessions.
+@property(nonatomic, assign) NSTimeInterval secondsBetweenSessions;
+// Exposing the recorded time between interactions.
+@property(nonatomic, assign) NSTimeInterval secondsBetweenInteractions;
+// Exposing a private version of the method `recordUserInteractionOrScrolling`
+// that takes an argument. `interactionDate` is the date (and time) of the user
+// interaction or scrolling event.
+- (void)recordUserInteractionOrScrollingAtDate:(NSDate*)interactionDate;
+@end
+
+// Subclass used for testing the FeedSessionRecorder.
+@interface TestFeedSessionRecorder : FeedSessionRecorder
+// Redefining this property in a subclass prevents reading and writing to
+// NSUserDefaults during testing.
+@property(nonatomic, copy) NSDate* previousInteractionDate;
+@end
+
+@implementation TestFeedSessionRecorder
+@end
+
+using FeedSessionRecorderTest = PlatformTest;
+
+// Tests that the session duration is correctly calculated.
+TEST_F(FeedSessionRecorderTest, SessionDuration) {
+  TestFeedSessionRecorder* recorder = [[TestFeedSessionRecorder alloc] init];
+
+  // Note: time intervals are in seconds.
+  NSDate* date_0 = [NSDate dateWithTimeIntervalSinceReferenceDate:0];
+  NSDate* date_1 = [NSDate dateWithTimeIntervalSinceReferenceDate:5];
+  [recorder recordUserInteractionOrScrollingAtDate:date_0];
+  [recorder recordUserInteractionOrScrollingAtDate:date_1];
+
+  // There should be no session duration yet, since there is no interaction
+  // outside of the session timeout (5 mins).
+  EXPECT_EQ(0, recorder.sessionDurationInSeconds);
+
+  // date_2 must be at least 5 minutes after date_1.
+  NSDate* date_2 = [NSDate dateWithTimeIntervalSinceReferenceDate:6 * 60];
+  [recorder recordUserInteractionOrScrollingAtDate:date_2];
+
+  EXPECT_EQ(5, recorder.sessionDurationInSeconds);
+}
+
+// Tests that the time between session is correctly calculated.
+TEST_F(FeedSessionRecorderTest, TimeBetweenSessions) {
+  TestFeedSessionRecorder* recorder = [[TestFeedSessionRecorder alloc] init];
+
+  // Note: time intervals are in seconds.
+  NSDate* date_0 = [NSDate dateWithTimeIntervalSinceReferenceDate:0];
+  NSDate* date_1 = [NSDate dateWithTimeIntervalSinceReferenceDate:5];
+  [recorder recordUserInteractionOrScrollingAtDate:date_0];
+  [recorder recordUserInteractionOrScrollingAtDate:date_1];
+
+  // A new session hasn't yet begun.
+  EXPECT_EQ(0, recorder.secondsBetweenSessions);
+
+  // date_2 must be at least 5 minutes after date_1.
+  NSDate* date_2 = [NSDate dateWithTimeIntervalSinceReferenceDate:5 + 6 * 60];
+  [recorder recordUserInteractionOrScrollingAtDate:date_2];
+
+  EXPECT_EQ(6 * 60, recorder.secondsBetweenSessions);
+}
+
+// Tests that the time between interactions is correctly calculated.
+TEST_F(FeedSessionRecorderTest, TimeBetweenInteractions) {
+  TestFeedSessionRecorder* recorder = [[TestFeedSessionRecorder alloc] init];
+
+  // Note: time intervals are in seconds.
+  NSDate* date_0 = [NSDate dateWithTimeIntervalSinceReferenceDate:0];
+  [recorder recordUserInteractionOrScrollingAtDate:date_0];
+
+  // Cannot compute the time between interactions if there is only one.
+  EXPECT_EQ(0, recorder.secondsBetweenInteractions);
+
+  NSDate* date_1 = [NSDate dateWithTimeIntervalSinceReferenceDate:5];
+  [recorder recordUserInteractionOrScrollingAtDate:date_1];
+
+  EXPECT_EQ(5, recorder.secondsBetweenInteractions);
+
+  NSDate* date_2 = [NSDate dateWithTimeIntervalSinceReferenceDate:9];
+  [recorder recordUserInteractionOrScrollingAtDate:date_2];
+
+  EXPECT_EQ(4, recorder.secondsBetweenInteractions);
+}
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 c2add26c..7ac2975 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 @@
-6d28d4fd310eb2d6deca738c89a6fa61670a1ac0
\ No newline at end of file
+dbff80888960f9a1d3e3a64febcf3b5719acde2c
\ 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 292065f..28a8a52 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 @@
-ee7eea2d9bbe6cb8eb83b5c1cd374fd0d6cc0b73
\ No newline at end of file
+000a2eb1f7cc647d3a97f319dc8f9477f141cb2c
\ 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 68ceafa..cc1e595 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 @@
-0cdab913688ff3791ab6c204012543e62d1741aa
\ No newline at end of file
+7b91775a127e74a90c7d167540ee8ca65abd0520
\ 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 aff3220..3c6671ec 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 @@
-462c3420f890d7cec9154a7e2b46c7b1e83287a3
\ No newline at end of file
+c7901b659bf4b20c823a0fed7fd9462fedf9bc6c
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index 181147b..220eb6b 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-38cec7af31e7f728fa85c89f4a2a39a7973592b2
\ No newline at end of file
+063ba44b730363a79da6acfff6336897633ac51d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index ad594b4c..150286c 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-3860d4e0e7e222bc5d0a2743f4aafa73d7d27633
\ No newline at end of file
+ec3e4f725b925b2c9e9139dbe86874fc6f2755e1
\ 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 ddf3bed..ec9c00ea 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 @@
-2ea55542d8b5c3e6a8c4c3dfb9bc8bceebbce805
\ No newline at end of file
+7be2e61ab96dc021b5aa42819dae902a8b8222c2
\ 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 1efb107d..efb3ad7 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 @@
-202feb3dbbb45f7490ac991d8feeaf28181ad84e
\ No newline at end of file
+3b63c49fa355109f269c5d213bc89e429910d7dc
\ 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 e194f0a..7be3241d3 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 @@
-2f00a930a7673bbff5e1f538e9e87a140f51ac8f
\ No newline at end of file
+38fd3c24110568cdc976d75a54bdb1c12fc167eb
\ 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 934ca5b..205082c 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 @@
-46bbc63b28f0c172e8b0490cdc3be07a45892c9f
\ No newline at end of file
+a5a8cb53e3fdfb337a1a7d04243df4ce38d2bfce
\ No newline at end of file
diff --git a/media/gpu/test/video_player/decoder_wrapper.cc b/media/gpu/test/video_player/decoder_wrapper.cc
index 5aaa744..0535c4e 100644
--- a/media/gpu/test/video_player/decoder_wrapper.cc
+++ b/media/gpu/test/video_player/decoder_wrapper.cc
@@ -15,6 +15,7 @@
 #include "media/base/waiting.h"
 #include "media/gpu/macros.h"
 #include "media/gpu/test/video.h"
+#include "media/gpu/test/video_frame_helpers.h"
 #include "media/gpu/test/video_player/frame_renderer_dummy.h"
 #include "media/gpu/test/video_player/test_vda_video_decoder.h"
 #include "media/gpu/test/video_test_helpers.h"
diff --git a/media/gpu/test/video_player/video_player.cc b/media/gpu/test/video_player/video_player.cc
index 72d3e3e..2d22329 100644
--- a/media/gpu/test/video_player/video_player.cc
+++ b/media/gpu/test/video_player/video_player.cc
@@ -8,6 +8,7 @@
 #include "base/memory/ptr_util.h"
 #include "media/gpu/macros.h"
 #include "media/gpu/test/video.h"
+#include "media/gpu/test/video_frame_helpers.h"
 #include "media/gpu/test/video_player/decoder_wrapper.h"
 #include "media/gpu/test/video_player/frame_renderer_dummy.h"
 
@@ -65,7 +66,6 @@
     std::unique_ptr<FrameRendererDummy> frame_renderer,
     std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_EQ(state_, VideoPlayerState::kUninitialized);
   DCHECK(frame_renderer);
   DVLOGF(4);
 
@@ -90,8 +90,6 @@
 
 bool VideoPlayer::Initialize(const Video* video) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(state_ == VideoPlayerState::kUninitialized ||
-         state_ == VideoPlayerState::kIdle);
   DCHECK(video);
   DVLOGF(4);
 
@@ -101,13 +99,11 @@
   if (!WaitForEvent(VideoPlayerEvent::kInitialized))
     return false;
 
-  state_ = VideoPlayerState::kIdle;
   return true;
 }
 
 void VideoPlayer::Play() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_EQ(state_, VideoPlayerState::kIdle);
   DVLOGF(4);
 
   // Play until the end of the video.
@@ -116,11 +112,9 @@
 
 void VideoPlayer::PlayUntil(VideoPlayerEvent event) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_EQ(state_, VideoPlayerState::kIdle);
   DVLOGF(4);
 
   play_until_ = event;
-  state_ = VideoPlayerState::kDecoding;
   decoder_wrapper_->Play();
 }
 
@@ -210,21 +204,12 @@
 
 bool VideoPlayer::NotifyEvent(VideoPlayerEvent event) {
   base::AutoLock auto_lock(event_lock_);
-  if (event == VideoPlayerEvent::kFlushDone ||
-      event == VideoPlayerEvent::kResetDone) {
-    state_ = VideoPlayerState::kIdle;
-  }
-
   video_player_events_.push(event);
   video_player_event_counts_[static_cast<size_t>(event)]++;
   event_cv_.Signal();
 
-  // Check whether video playback should be paused after this event.
-  if (play_until_.has_value() && play_until_ == event) {
-    state_ = VideoPlayerState::kIdle;
-    return false;
-  }
-  return true;
+  const bool should_pause = play_until_.has_value() && play_until_ == event;
+  return !should_pause;
 }
 
 }  // namespace test
diff --git a/media/gpu/test/video_player/video_player.h b/media/gpu/test/video_player/video_player.h
index 002e3c2..f12263e 100644
--- a/media/gpu/test/video_player/video_player.h
+++ b/media/gpu/test/video_player/video_player.h
@@ -17,13 +17,14 @@
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
-#include "media/gpu/test/video_frame_helpers.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace media {
 namespace test {
 
 class FrameRendererDummy;
 class Video;
+class VideoFrameProcessor;
 class DecoderWrapper;
 struct DecoderWrapperConfig;
 
@@ -54,9 +55,7 @@
 
   ~VideoPlayer();
 
-  // Create an instance of the video player. The |frame_renderer| and
-  // |frame_processors| will not be owned by the video player. The caller should
-  // guarantee they outlive the video player.
+  // Create an instance of this class. Must be Initialize()d before use.
   static std::unique_ptr<VideoPlayer> Create(
       const DecoderWrapperConfig& config,
       std::unique_ptr<FrameRendererDummy> frame_renderer,
@@ -108,12 +107,6 @@
   size_t GetFrameDecodedCount() const;
 
  private:
-  enum class VideoPlayerState : size_t {
-    kUninitialized = 0,
-    kIdle,
-    kDecoding,
-  };
-
   VideoPlayer();
 
   bool CreateWrapper(
@@ -125,7 +118,6 @@
   // whether the decoder client should continue decoding frames.
   bool NotifyEvent(VideoPlayerEvent event);
 
-  VideoPlayerState state_ = VideoPlayerState::kUninitialized;
   std::unique_ptr<DecoderWrapper> decoder_wrapper_;
 
   // The timeout used when waiting for events.
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc
index fa31f7d..66da6d3e 100644
--- a/media/renderers/paint_canvas_video_renderer.cc
+++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -792,11 +792,13 @@
       sk_sp<SkImage> sk_image,
       const gpu::Mailbox& mailbox,
       bool wraps_video_frame_texture,
-      scoped_refptr<viz::RasterContextProvider> raster_context_provider)
+      scoped_refptr<viz::RasterContextProvider> raster_context_provider,
+      std::unique_ptr<ScopedSharedImageAccess> access)
       : sk_image_(std::move(sk_image)),
         sk_image_info_(sk_image_->imageInfo()),
         mailbox_(mailbox),
-        wraps_video_frame_texture_(wraps_video_frame_texture) {
+        wraps_video_frame_texture_(wraps_video_frame_texture),
+        access_(std::move(access)) {
     DCHECK(sk_image_->isTextureBacked());
     raster_context_provider_ = std::move(raster_context_provider);
   }
@@ -832,13 +834,22 @@
   }
 
   // Used only for recycling this TextureBacking - where we need to keep the
-  // texture/mailbox alive, but replace the SkImage.
-  void ReplaceAcceleratedSkImage(sk_sp<SkImage> sk_image) {
+  // texture/mailbox alive, but replace the SkImage. |access| is the access to
+  // the SharedImage backing this SkImage.
+  void ReplaceAcceleratedSkImage(
+      sk_sp<SkImage> sk_image,
+      std::unique_ptr<ScopedSharedImageAccess> access) {
     DCHECK(sk_image->isTextureBacked());
     sk_image_ = sk_image;
     sk_image_info_ = sk_image->imageInfo();
+
+    // The client should have called clear_access() before invoking this method.
+    DCHECK(!access_);
+    access_ = std::move(access);
   }
 
+  void clear_access() { access_.reset(); }
+
   sk_sp<SkImage> GetSkImageViaReadback() override {
     sk_sp<SkData> image_pixels =
         SkData::MakeUninitialized(sk_image_info_.computeMinByteSize());
@@ -865,7 +876,6 @@
         DLOG(ERROR) << "Failed to getGLTextureInfo for VideoTextureBacking.";
         return false;
       }
-      ScopedSharedImageAccess scoped_access(ri, texture_info.fID, mailbox_);
       return sk_image_->readPixels(dst_info, dst_pixels, dst_row_bytes, src_x,
                                    src_y);
     }
@@ -894,6 +904,8 @@
   // Whether |mailbox_| directly points to a texture of the VideoFrame
   // (if true), or to an allocated shared image (if false).
   const bool wraps_video_frame_texture_;
+
+  std::unique_ptr<ScopedSharedImageAccess> access_;
 };
 
 PaintCanvasVideoRenderer::PaintCanvasVideoRenderer()
@@ -962,14 +974,6 @@
   cc::PaintImage image = cache_->paint_image;
   DCHECK(image);
 
-  absl::optional<ScopedSharedImageAccess> source_access;
-  if (video_frame->HasTextures() && cache_->source_texture) {
-    DCHECK(cache_->texture_backing);
-    source_access.emplace(raster_context_provider->RasterInterface(),
-                          cache_->source_texture,
-                          cache_->texture_backing->GetMailbox());
-  }
-
   cc::PaintFlags video_flags;
   video_flags.setAlpha(flags.getAlpha());
   video_flags.setBlendMode(flags.getBlendMode());
@@ -1067,7 +1071,6 @@
   canvas->flush();
 
   if (video_frame->HasTextures()) {
-    source_access.reset();
     // Synchronize |video_frame| with the read operations in UpdateLastImage(),
     // which are triggered by canvas->flush().
     SynchronizeVideoFrameRead(std::move(video_frame),
@@ -1859,6 +1862,12 @@
         // We can reuse the shared image from the previous cache.
         cache_->frame_id = video_frame->unique_id();
         mailbox = cache_->texture_backing->GetMailbox();
+
+        // NOTE: It is necessary to let go of read access to the cached copy
+        // here because the below copy operation takes readwrite access to that
+        // cached copy, and requesting RW access while already holding R access
+        // on a single service-side texture causes a DCHECK to fire.
+        cache_->texture_backing->clear_access();
       } else {
         cache_.emplace(video_frame->unique_id());
         auto* sii = raster_context_provider->SharedImageInterface();
@@ -1915,10 +1924,8 @@
     if (!supports_oop_raster) {
       cache_->source_texture = ri->CreateAndConsumeForGpuRaster(mailbox);
 
-      // TODO(nazabris): Handle scoped access correctly. This follows the
-      // current pattern but is most likely bugged. Access should last for
-      // the lifetime of the SkImage.
-      ScopedSharedImageAccess access(ri, cache_->source_texture, mailbox);
+      auto access = std::make_unique<ScopedSharedImageAccess>(
+          ri, cache_->source_texture, mailbox);
       auto source_image = WrapGLTexture(
           wraps_video_frame_texture
               ? video_frame->mailbox_holder(0).texture_target
@@ -1933,10 +1940,10 @@
       if (!cache_->texture_backing) {
         cache_->texture_backing = sk_make_sp<VideoTextureBacking>(
             std::move(source_image), mailbox, wraps_video_frame_texture,
-            raster_context_provider);
+            raster_context_provider, std::move(access));
       } else {
         cache_->texture_backing->ReplaceAcceleratedSkImage(
-            std::move(source_image));
+            std::move(source_image), std::move(access));
       }
     } else if (!cache_->texture_backing) {
       SkImageInfo sk_image_info =
diff --git a/media/video/video_encode_accelerator_adapter.cc b/media/video/video_encode_accelerator_adapter.cc
index 47b6f94..0a62632a 100644
--- a/media/video/video_encode_accelerator_adapter.cc
+++ b/media/video/video_encode_accelerator_adapter.cc
@@ -45,18 +45,48 @@
       std::numeric_limits<uint32_t>::max());
 }
 
+uint32_t ComputeCheckedPeakBitrate(uint32_t target_bitrate) {
+  // TODO(crbug.com/1342850): Reconsider whether this is good peak bps.
+  base::CheckedNumeric<uint32_t> checked_bitrate_product =
+      base::CheckMul<uint32_t>(target_bitrate, 10u);
+  return checked_bitrate_product.ValueOrDefault(
+      std::numeric_limits<uint32_t>::max());
+}
+
+Bitrate CreateBitrate(
+    const absl::optional<Bitrate>& requested_bitrate,
+    const gfx::Size& frame_size,
+    VideoEncodeAccelerator::SupportedRateControlMode supported_rc_modes) {
+  uint32_t default_bitrate = ComputeCheckedDefaultBitrate(frame_size);
+  if (supported_rc_modes & VideoEncodeAccelerator::kVariableMode) {
+    // VEA supports VBR. Use |requested_bitrate| or VBR if bitrate is not
+    // specified.
+    return requested_bitrate.value_or(Bitrate::VariableBitrate(
+        default_bitrate, ComputeCheckedPeakBitrate(default_bitrate)));
+  }
+  // VEA doesn't support VBR. The bitrate configured to VEA must be CBR. In
+  // other words, if |requested_bitrate| is CBR, bitrate mode fallbacks to VBR.
+  if (requested_bitrate &&
+      requested_bitrate->mode() == Bitrate::Mode::kConstant) {
+    return *requested_bitrate;
+  }
+
+  return Bitrate::ConstantBitrate(
+      requested_bitrate ? requested_bitrate->target_bps() : default_bitrate);
+}
+
 VideoEncodeAccelerator::Config SetUpVeaConfig(
     VideoCodecProfile profile,
     const VideoEncoder::Options& opts,
     VideoPixelFormat format,
-    VideoFrame::StorageType storage_type) {
+    VideoFrame::StorageType storage_type,
+    VideoEncodeAccelerator::SupportedRateControlMode supported_rc_modes) {
   absl::optional<uint32_t> initial_framerate;
   if (opts.framerate.has_value())
     initial_framerate = static_cast<uint32_t>(opts.framerate.value());
 
-  uint32_t default_bitrate = ComputeCheckedDefaultBitrate(opts.frame_size);
   Bitrate bitrate =
-      opts.bitrate.value_or(Bitrate::ConstantBitrate(default_bitrate));
+      CreateBitrate(opts.bitrate, opts.frame_size, supported_rc_modes);
   auto config =
       VideoEncodeAccelerator::Config(format, opts.frame_size, profile, bitrate,
                                      initial_framerate, opts.keyframe_interval);
@@ -198,7 +228,34 @@
     return;
   }
 
+  auto supported_profiles =
+      gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles();
+  if (!supported_profiles) {
+    InitCompleted(
+        EncoderStatus(EncoderStatus::Codes::kEncoderInitializationError,
+                      "No profile is supported by video encode accelerator."));
+    return;
+  }
+
+  auto supported_rc_modes =
+      VideoEncodeAccelerator::SupportedRateControlMode::kNoMode;
+  for (const auto& supported_profile : *supported_profiles) {
+    if (supported_profile.profile == profile) {
+      supported_rc_modes = supported_profile.rate_control_modes;
+      break;
+    }
+  }
+
+  if (supported_rc_modes ==
+      VideoEncodeAccelerator::SupportedRateControlMode::kNoMode) {
+    std::move(done_cb).Run(EncoderStatus(
+        EncoderStatus::Codes::kEncoderInitializationError,
+        "The profile is not supported by video encode accelerator."));
+    return;
+  }
+
   profile_ = profile;
+  supported_rc_modes_ = supported_rc_modes;
   options_ = options;
   output_cb_ = std::move(output_cb);
   state_ = State::kWaitingForFirstFrame;
@@ -237,7 +294,8 @@
   }
 
   auto vea_config =
-      SetUpVeaConfig(profile_, options_, format, first_frame->storage_type());
+      SetUpVeaConfig(profile_, options_, format, first_frame->storage_type(),
+                     supported_rc_modes_);
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   // Linux/ChromeOS require a special configuration to use dmabuf storage.
@@ -374,11 +432,16 @@
     std::move(done_cb).Run(status);
     return;
   }
+  if (options.bitrate && options_.bitrate &&
+      options.bitrate->mode() != options_.bitrate->mode()) {
+    std::move(done_cb).Run(
+        EncoderStatus(EncoderStatus::Codes::kEncoderInitializationError,
+                      "Bitrate mode change is not supported."));
+    return;
+  }
 
-  uint32_t default_bitrate = ComputeCheckedDefaultBitrate(options.frame_size);
   Bitrate bitrate =
-      options.bitrate.value_or(Bitrate::ConstantBitrate(default_bitrate));
-
+      CreateBitrate(options.bitrate, options.frame_size, supported_rc_modes_);
   uint32_t framerate = base::ClampRound<uint32_t>(
       options.framerate.value_or(VideoEncodeAccelerator::kDefaultFramerate));
 
diff --git a/media/video/video_encode_accelerator_adapter.h b/media/video/video_encode_accelerator_adapter.h
index 25f3075..65b3cb8 100644
--- a/media/video/video_encode_accelerator_adapter.h
+++ b/media/video/video_encode_accelerator_adapter.h
@@ -165,6 +165,8 @@
   std::vector<uint8_t> resize_buf_;
 
   VideoCodecProfile profile_ = VIDEO_CODEC_PROFILE_UNKNOWN;
+  VideoEncodeAccelerator::SupportedRateControlMode supported_rc_modes_ =
+      VideoEncodeAccelerator::kNoMode;
   Options options_;
   OutputCB output_cb_;
 
diff --git a/media/video/video_encode_accelerator_adapter_test.cc b/media/video/video_encode_accelerator_adapter_test.cc
index 916f9cc..63e8baa 100644
--- a/media/video/video_encode_accelerator_adapter_test.cc
+++ b/media/video/video_encode_accelerator_adapter_test.cc
@@ -53,6 +53,19 @@
     vea_ = new FakeVideoEncodeAccelerator(vea_runner_);
     gpu_factories_ =
         std::make_unique<MockGpuVideoAcceleratorFactories>(nullptr);
+    supported_profiles_ = {
+        VideoEncodeAccelerator::SupportedProfile(
+            profile_,
+            /*max_resolution=*/gfx::Size(3840, 2160),
+            /*max_framerate_numerator=*/30,
+            /*max_framerate_denominator=*/1,
+            /*rc_modes=*/VideoEncodeAccelerator::kConstantMode |
+                VideoEncodeAccelerator::kVariableMode),
+    };
+
+    EXPECT_CALL(*gpu_factories_.get(),
+                GetVideoEncodeAcceleratorSupportedProfiles())
+        .WillRepeatedly(Return(supported_profiles_));
     EXPECT_CALL(*gpu_factories_.get(), DoCreateVideoEncodeAccelerator())
         .WillRepeatedly(Return(vea_.get()));
     EXPECT_CALL(*gpu_factories_.get(), GetTaskRunner())
@@ -172,6 +185,7 @@
 
  protected:
   VideoCodecProfile profile_ = VP8PROFILE_ANY;
+  std::vector<VideoEncodeAccelerator::SupportedProfile> supported_profiles_;
   base::test::TaskEnvironment task_environment_;
   raw_ptr<FakeVideoEncodeAccelerator> vea_;  // owned by |vae_adapter_|
   std::unique_ptr<MockGpuVideoAcceleratorFactories> gpu_factories_;
@@ -328,8 +342,11 @@
         EXPECT_TRUE(false) << "should never come here";
         return BitstreamBufferMetadata(1, keyframe, frame->timestamp());
       }));
-  adapter()->Initialize(VIDEO_CODEC_PROFILE_UNKNOWN, options,
-                        std::move(output_cb), ValidatingStatusCB());
+  adapter()->Initialize(
+      VIDEO_CODEC_PROFILE_UNKNOWN, options, std::move(output_cb),
+      base::BindLambdaForTesting([](EncoderStatus s) {
+        EXPECT_EQ(s.code(), EncoderStatus::Codes::kEncoderInitializationError);
+      }));
 
   auto frame =
       CreateGreenFrame(options.frame_size, pixel_format, base::Milliseconds(1));
diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h
index 6466deac..96d1a51 100644
--- a/net/base/load_flags_list.h
+++ b/net/base/load_flags_list.h
@@ -101,12 +101,3 @@
 // is considered privileged, and therefore this flag must only be set from a
 // trusted process.
 LOAD_FLAG(CAN_USE_RESTRICTED_PREFETCH, 1 << 16)
-
-// True if the request should attempt to use the single-keyed cache to satisfy
-// the request. The single-keyed cache will only be used if the "unusable" flag
-// on the cache entry is not true. Otherwise it will fall back to the
-// partitioned cache. This flag also enables checksumming of the response to set
-// the "unusable" flag if necessary.
-//
-// Cannot be used together with BYPASS_CACHE, ONLY_FROM_CACHE, or DISABLE_CACHE.
-LOAD_FLAG(USE_SINGLE_KEYED_CACHE, 1 << 17)
diff --git a/net/disk_cache/blockfile/backend_impl.cc b/net/disk_cache/blockfile/backend_impl.cc
index 9cdd801..a0f9d6d 100644
--- a/net/disk_cache/blockfile/backend_impl.cc
+++ b/net/disk_cache/blockfile/backend_impl.cc
@@ -2106,17 +2106,18 @@
 }
 
 int BackendImpl::MaxBuffersSize() {
-  static uint64_t total_memory = base::SysInfo::AmountOfPhysicalMemory();
+  static int64_t total_memory = base::SysInfo::AmountOfPhysicalMemory();
   static bool done = false;
 
   if (!done) {
-    done = true;
+    const int kMaxBuffersSize = 30 * 1024 * 1024;
 
-    // We want to use up to 2% of the computer's memory, limit 30 MB.
+    // We want to use up to 2% of the computer's memory.
     total_memory = total_memory * 2 / 100;
-    constexpr uint64_t kMaxBuffersSize = 30 * 1024 * 1024;
-    if (total_memory > kMaxBuffersSize || total_memory == 0)
+    if (total_memory > kMaxBuffersSize || total_memory <= 0)
       total_memory = kMaxBuffersSize;
+
+    done = true;
   }
 
   return static_cast<int>(total_memory);
diff --git a/net/disk_cache/memory/mem_backend_impl.cc b/net/disk_cache/memory/mem_backend_impl.cc
index ab9f041..951427d 100644
--- a/net/disk_cache/memory/mem_backend_impl.cc
+++ b/net/disk_cache/memory/mem_backend_impl.cc
@@ -76,9 +76,9 @@
   if (max_size_)
     return true;
 
-  uint64_t total_memory = base::SysInfo::AmountOfPhysicalMemory();
+  int64_t total_memory = base::SysInfo::AmountOfPhysicalMemory();
 
-  if (total_memory == 0) {
+  if (total_memory <= 0) {
     max_size_ = kDefaultInMemoryCacheSize;
     return true;
   }
@@ -86,7 +86,7 @@
   // We want to use up to 2% of the computer's memory, with a limit of 50 MB,
   // reached on system with more than 2.5 GB of RAM.
   total_memory = total_memory * 2 / 100;
-  if (total_memory > static_cast<uint64_t>(kDefaultInMemoryCacheSize) * 5)
+  if (total_memory > kDefaultInMemoryCacheSize * 5)
     max_size_ = kDefaultInMemoryCacheSize * 5;
   else
     max_size_ = static_cast<int32_t>(total_memory);
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 638f0cf1..61ee20a1 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -1038,12 +1038,12 @@
   mode_ = NONE;
 
   if (!ShouldPassThrough()) {
-    // The flag LOAD_USE_SINGLE_KEYED_CACHE will have been changed to false if
-    // the entry was marked unusable and the transaction was restarted in
-    //  DoCacheReadResponseComplete(), so it will no longer match the value in
-    //  `request_`. So we pass it through explicitly.
-    cache_key_ = cache_->GenerateCacheKeyForRequest(
-        request_, effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE);
+    // The flag `use_single_keyed_cache_` will have been changed back to false
+    // if the entry was marked unusable and the transaction was restarted in
+    // DoCacheReadResponseComplete(), even though `request_` will still have a
+    // checksum. So it needs to be passed explicitly.
+    cache_key_ =
+        cache_->GenerateCacheKeyForRequest(request_, use_single_keyed_cache_);
 
     // Requested cache access mode.
     if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) {
@@ -1575,9 +1575,9 @@
 
     // We've read the single keyed entry and it turned out to be unusable. Let's
     // retry reading from the split cache.
-    if (effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) {
+    if (use_single_keyed_cache_) {
       DCHECK(!network_trans_);
-      effective_load_flags_ &= ~LOAD_USE_SINGLE_KEYED_CACHE;
+      use_single_keyed_cache_ = false;
       DoneWithEntryForRestartWithCache();
       TransitionToState(STATE_GET_BACKEND);
       return OK;
@@ -1926,7 +1926,7 @@
 
   // The single-keyed cache only accepts responses with code 200 or 304.
   // Anything else is considered unusable.
-  if ((effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) &&
+  if (use_single_keyed_cache_ &&
       !(new_response->headers->response_code() == 200 ||
         new_response->headers->response_code() == 304)) {
     // Either the new response will be written back to the cache, in which case
@@ -2046,7 +2046,7 @@
     }
     TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE);
   } else {
-    if (effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) {
+    if (use_single_keyed_cache_) {
       DCHECK_EQ(method_, "GET");
       ChecksumHeaders();
     }
@@ -2137,7 +2137,7 @@
 
   SetResponse(*new_response_);
 
-  if (effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) {
+  if (use_single_keyed_cache_) {
     DCHECK_EQ(method_, "GET");
     ChecksumHeaders();
   }
@@ -2513,7 +2513,7 @@
 }
 
 int HttpCache::Transaction::DoMarkSingleKeyedCacheEntryUnusable() {
-  DCHECK(effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE);
+  DCHECK(use_single_keyed_cache_);
   response_.single_keyed_cache_entry_unusable = true;
   TransitionToState(STATE_MARK_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE_COMPLETE);
   return WriteResponseInfoToEntry(response_, /*truncated=*/false);
@@ -2549,6 +2549,9 @@
   effective_load_flags_ = request_->load_flags;
   method_ = request_->method;
 
+  if (!request_->checksum.empty())
+    use_single_keyed_cache_ = true;
+
   if (cache_->mode() == DISABLE)
     effective_load_flags_ |= LOAD_DISABLE_CACHE;
 
@@ -3933,7 +3936,7 @@
 }
 
 void HttpCache::Transaction::ChecksumHeaders() {
-  DCHECK(effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE);
+  DCHECK(use_single_keyed_cache_);
   DCHECK(!checksum_);
   checksum_ = crypto::SecureHash::Create(crypto::SecureHash::SHA256);
   // For efficiency and concision, we list known headers matching a wildcard
@@ -3993,7 +3996,7 @@
   if (!checksum_)
     return true;
 
-  DCHECK(effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE);
+  DCHECK(use_single_keyed_cache_);
   return ResponseChecksumMatches(std::move(checksum_));
 }
 
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index bc5ace70..624279ed 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -669,6 +669,8 @@
       false;  // Fail ConditionalizeRequest.
   bool mark_single_keyed_cache_entry_unusable_ =
       false;  // Set single_keyed_cache_entry_unusable.
+  // This is initialised in Start().
+  bool use_single_keyed_cache_ = false;
 
   scoped_refptr<IOBuffer> read_buf_;
 
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index 5dee8e9..1674ed5 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -13520,9 +13520,8 @@
       const NetworkIsolationKey& network_isolation_key,
       const std::string& checksum) {
     MockTransaction transaction(trans_info);
-    transaction.load_flags |= LOAD_USE_SINGLE_KEYED_CACHE;
-
     AddMockTransaction(&transaction);
+
     MockHttpRequest request(transaction);
     request.network_isolation_key = network_isolation_key;
     request.checksum = checksum;
diff --git a/net/quic/quic_chromium_client_stream.cc b/net/quic/quic_chromium_client_stream.cc
index 6392c9458..7a7c1ac 100644
--- a/net/quic/quic_chromium_client_stream.cc
+++ b/net/quic/quic_chromium_client_stream.cc
@@ -99,6 +99,11 @@
   if (!read_body_callback_)
     return;  // Wait for ReadBody to be called.
 
+  // TODO(https://crbug.com/1335423): Change to DCHECK() or remove after bug is
+  // fixed.
+  CHECK(read_body_buffer_);
+  CHECK_GT(read_body_buffer_len_, 0);
+
   int rv = stream_->Read(read_body_buffer_, read_body_buffer_len_);
   if (rv == ERR_IO_PENDING)
     return;  // Spurrious, likely because of trailers?
@@ -203,6 +208,11 @@
   if (rv != ERR_IO_PENDING)
     return rv;
 
+  // TODO(https://crbug.com/1335423): Change to DCHECK() or remove after bug is
+  // fixed.
+  CHECK(buffer);
+  CHECK_GT(buffer_len, 0);
+
   SetCallback(std::move(callback), &read_body_callback_);
   read_body_buffer_ = buffer;
   read_body_buffer_len_ = buffer_len;
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index 7c21404..c9b66d1 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -1061,8 +1061,8 @@
   int pervasive_payloads_index_for_logging_ = -1;
 
   // A SHA-256 checksum of the response and selected headers, stored as
-  // upper-case hexadecimal. This is only used if the
-  // LOAD_USE_SINGLE_KEYED_CACHE flag is set. On failure to match the cache
+  // upper-case hexadecimal. If this is set to a non-empty value the transaction
+  // will attempt to use the single-keyed cache. On failure to match the cache
   // entry will be marked as unusable and will not be re-used.
   std::string expected_response_checksum_;
 
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc
index f83aa27..f7b0de8 100644
--- a/sandbox/policy/win/sandbox_win.cc
+++ b/sandbox/policy/win/sandbox_win.cc
@@ -543,13 +543,13 @@
   size_t memory_limit = static_cast<size_t>(kDataSizeLimit);
 
   if (sandbox_type == Sandbox::kGpu || sandbox_type == Sandbox::kRenderer) {
-    constexpr uint64_t GB = 1024 * 1024 * 1024;
+    int64_t GB = 1024 * 1024 * 1024;
     // Allow the GPU/RENDERER process's sandbox to access more physical memory
     // if it's available on the system.
     //
     // Renderer processes are allowed to access 16 GB; the GPU process, up
     // to 64 GB.
-    uint64_t physical_memory = base::SysInfo::AmountOfPhysicalMemory();
+    int64_t physical_memory = base::SysInfo::AmountOfPhysicalMemory();
     if (sandbox_type == Sandbox::kGpu && physical_memory > 64 * GB) {
       memory_limit = 64 * GB;
     } else if (sandbox_type == Sandbox::kGpu && physical_memory > 32 * GB) {
diff --git a/services/network/network_service_memory_cache.cc b/services/network/network_service_memory_cache.cc
index 986138fc..ceb33520 100644
--- a/services/network/network_service_memory_cache.cc
+++ b/services/network/network_service_memory_cache.cc
@@ -286,7 +286,8 @@
   if (data_pipe_capacity_for_testing_.has_value())
     return *data_pipe_capacity_for_testing_;
 
-  uint32_t default_capacity = features::GetDataPipeDefaultAllocationSize();
+  uint32_t default_capacity = features::GetDataPipeDefaultAllocationSize(
+      features::DataPipeAllocationSize::kLargerSizeIfPossible);
   if (content_length > default_capacity)
     return default_capacity;
   return static_cast<size_t>(content_length);
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 04ed3a3..0244f5e 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -779,8 +779,6 @@
         cache_not_used_reason =
             CacheTransparencyCacheNotUsedReason::kIncompatibleRequestHeaders;
       } else {
-        request_load_flags |= net::LOAD_USE_SINGLE_KEYED_CACHE;
-
         url_request_->set_expected_response_checksum(checksum.value());
       }
       base::UmaHistogramEnumeration("Network.CacheTransparency.CacheNotUsed",
diff --git a/services/network/web_bundle/web_bundle_url_loader_factory.cc b/services/network/web_bundle/web_bundle_url_loader_factory.cc
index 3872626..ca2aa47 100644
--- a/services/network/web_bundle/web_bundle_url_loader_factory.cc
+++ b/services/network/web_bundle/web_bundle_url_loader_factory.cc
@@ -5,6 +5,7 @@
 #include "services/network/web_bundle/web_bundle_url_loader_factory.h"
 
 #include "base/metrics/histogram_functions.h"
+#include "base/ranges/algorithm.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
@@ -709,6 +710,20 @@
     return;
   }
 
+  if (!base::ranges::all_of(metadata->requests, [this](const auto& entry) {
+        return IsAllowedExchangeUrl(entry.first);
+      })) {
+    std::string error_message = "Exchange URL is not valid.";
+    ReportErrorAndCancelPendingLoaders(
+        SubresourceWebBundleLoadResult::kMetadataParseError,
+        mojom::WebBundleErrorType::kMetadataParseError, error_message);
+    if (devtools_request_id_) {
+      devtools_observer_->OnSubresourceWebBundleMetadataError(
+          *devtools_request_id_, error_message);
+    }
+    return;
+  }
+
   metadata_ = std::move(metadata);
   if (devtools_observer_ && devtools_request_id_) {
     std::vector<GURL> urls;
@@ -734,6 +749,11 @@
   pending_loaders_.clear();
 }
 
+bool WebBundleURLLoaderFactory::IsAllowedExchangeUrl(const GURL& relative_url) {
+  GURL url = bundle_url_.Resolve(relative_url.spec());
+  return url.SchemeIsHTTPOrHTTPS() || web_package::IsValidUuidInPackageURL(url);
+}
+
 void WebBundleURLLoaderFactory::OnResponseParsed(
     base::WeakPtr<URLLoader> loader,
     web_package::mojom::BundleResponsePtr response,
diff --git a/services/network/web_bundle/web_bundle_url_loader_factory.h b/services/network/web_bundle/web_bundle_url_loader_factory.h
index 3937071..a6c59900 100644
--- a/services/network/web_bundle/web_bundle_url_loader_factory.h
+++ b/services/network/web_bundle/web_bundle_url_loader_factory.h
@@ -86,6 +86,7 @@
   void StartLoad(base::WeakPtr<URLLoader> loader);
   void OnMetadataParsed(web_package::mojom::BundleMetadataPtr metadata,
                         web_package::mojom::BundleMetadataParseErrorPtr error);
+  bool IsAllowedExchangeUrl(const GURL& relative_url);
   void OnResponseParsed(base::WeakPtr<URLLoader> loader,
                         web_package::mojom::BundleResponsePtr response,
                         web_package::mojom::BundleResponseParseErrorPtr error);
diff --git a/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc b/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc
index 3714d22..a63fea7 100644
--- a/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc
+++ b/services/network/web_bundle/web_bundle_url_loader_factory_unittest.cc
@@ -30,6 +30,7 @@
 const char kResourceUrl[] = "https://example.com/";
 const char kResourceUrl2[] = "https://example.com/another";
 const char kResourceUrl3[] = "https://example.com/yetanother";
+const char kInvalidResourceUrl[] = "ftp://foo";
 const char kResourceRequestId[] = "resource-1-devtools-request-id";
 const char kResourceRequestId2[] = "resource-2-devtools-request-id";
 const char kResourceRequestId3[] = "resource-3-devtools-request-id";
@@ -300,6 +301,44 @@
       1);
 }
 
+TEST_F(WebBundleURLLoaderFactoryTest, MetadataWithInvalidExchangeUrl) {
+  base::HistogramTester histogram_tester;
+  auto request = StartRequest(GURL(kInvalidResourceUrl), kResourceRequestId);
+
+  web_package::WebBundleBuilder builder;
+  builder.AddExchange(kInvalidResourceUrl,
+                      {{":status", "200"}, {"content-type", "text/plain"}},
+                      "body");
+  WriteBundle(builder.CreateBundle());
+  FinishWritingBundle();
+
+  EXPECT_CALL(*devtools_observer_,
+              OnSubresourceWebBundleMetadataError(
+                  kBundleRequestId, Eq("Exchange URL is not valid.")));
+  EXPECT_CALL(*devtools_observer_, OnSubresourceWebBundleInnerResponse(_, _, _))
+      .Times(0);
+  request.client->RunUntilComplete();
+  RunUntilBundleError();
+
+  EXPECT_EQ(net::ERR_INVALID_WEB_BUNDLE,
+            request.client->completion_status().error_code);
+  EXPECT_EQ(last_bundle_error()->first,
+            mojom::WebBundleErrorType::kMetadataParseError);
+  EXPECT_EQ(last_bundle_error()->second, "Exchange URL is not valid.");
+
+  // Requests made after metadata parse error should also fail.
+  auto request2 = StartRequest(GURL(kInvalidResourceUrl), kResourceRequestId);
+  request2.client->RunUntilComplete();
+
+  EXPECT_EQ(net::ERR_INVALID_WEB_BUNDLE,
+            request2.client->completion_status().error_code);
+  histogram_tester.ExpectUniqueSample(
+      "SubresourceWebBundles.LoadResult",
+      WebBundleURLLoaderFactory::SubresourceWebBundleLoadResult::
+          kMetadataParseError,
+      1);
+}
+
 TEST_F(WebBundleURLLoaderFactoryTest, ResponseParseError) {
   web_package::WebBundleBuilder builder;
   // An invalid response.
@@ -483,7 +522,7 @@
   EXPECT_EQ(last_bundle_error()->second, "Error reading response header.");
 }
 
-TEST_F(WebBundleURLLoaderFactoryTest, CrossOiginJson) {
+TEST_F(WebBundleURLLoaderFactoryTest, CrossOriginJson) {
   WriteBundle(CreateCrossOriginBundle());
   FinishWritingBundle();
 
diff --git a/services/tracing/public/cpp/perfetto/trace_string_lookup.cc b/services/tracing/public/cpp/perfetto/trace_string_lookup.cc
index 8b4baf30..6f0b79d 100644
--- a/services/tracing/public/cpp/perfetto/trace_string_lookup.cc
+++ b/services/tracing/public/cpp/perfetto/trace_string_lookup.cc
@@ -54,7 +54,7 @@
      ChromeProcessDescriptor::PROCESS_SERVICE_PRINTING},
     {"Service: quarantine.mojom.Quarantine",
      ChromeProcessDescriptor::PROCESS_SERVICE_QUARANTINE},
-    {"Service: ash.local_search_service.mojom.LocalSearchService",
+    {"Service: chromeos.local_search_service.mojom.LocalSearchService",
      ChromeProcessDescriptor::PROCESS_SERVICE_CROS_LOCALSEARCH},
     {"Service: chromeos.assistant.mojom.AssistantAudioDecoderFactory",
      ChromeProcessDescriptor::PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER},
diff --git a/storage/browser/blob/blob_memory_controller.cc b/storage/browser/blob/blob_memory_controller.cc
index 87c87f83..f5d1e16 100644
--- a/storage/browser/blob/blob_memory_controller.cc
+++ b/storage/browser/blob/blob_memory_controller.cc
@@ -82,11 +82,11 @@
 BlobStorageLimits CalculateBlobStorageLimitsImpl(
     const FilePath& storage_dir,
     bool disk_enabled,
-    absl::optional<uint64_t> optional_memory_size_for_testing) {
+    absl::optional<int64_t> optional_memory_size_for_testing) {
   int64_t disk_size = 0ull;
-  uint64_t memory_size = optional_memory_size_for_testing
-                             ? optional_memory_size_for_testing.value()
-                             : base::SysInfo::AmountOfPhysicalMemory();
+  int64_t memory_size = optional_memory_size_for_testing
+                            ? optional_memory_size_for_testing.value()
+                            : base::SysInfo::AmountOfPhysicalMemory();
   if (disk_enabled && CreateBlobDirectory(storage_dir) == base::File::FILE_OK)
     disk_size = base::SysInfo::AmountOfTotalDiskSpace(storage_dir);
 
@@ -99,9 +99,9 @@
     constexpr size_t kTwoGigabytes = 2ull * 1024 * 1024 * 1024;
     limits.max_blob_in_memory_space = kTwoGigabytes;
 #elif BUILDFLAG(IS_ANDROID)
-    limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 100);
+    limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 100ll);
 #else
-    limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 5);
+    limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 5ll);
 #endif
   }
   // Devices just on the edge (RAM == 256MB) should not fail because
diff --git a/storage/browser/blob/blob_memory_controller.h b/storage/browser/blob/blob_memory_controller.h
index 168c100..ecb449b 100644
--- a/storage/browser/blob/blob_memory_controller.h
+++ b/storage/browser/blob/blob_memory_controller.h
@@ -204,7 +204,7 @@
   // synchronously.
   void CallWhenStorageLimitsAreKnown(base::OnceClosure callback);
 
-  void set_amount_of_physical_memory_for_testing(uint64_t amount_of_memory) {
+  void set_amount_of_physical_memory_for_testing(int64_t amount_of_memory) {
     amount_of_memory_for_testing_ = amount_of_memory;
   }
 
@@ -283,7 +283,7 @@
   bool did_calculate_storage_limits_ = false;
   std::vector<base::OnceClosure> on_calculate_limits_callbacks_;
 
-  absl::optional<uint64_t> amount_of_memory_for_testing_;
+  absl::optional<int64_t> amount_of_memory_for_testing_;
 
   // Memory bookkeeping. These numbers are all disjoint.
   // This is the amount of memory we're using for blobs in RAM, including the
diff --git a/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc b/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc
index e9db5bb9..326e9d85d 100644
--- a/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc
+++ b/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc
@@ -10,7 +10,6 @@
 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
 #include "base/files/file_util.h"
 #include "base/numerics/checked_math.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/system/sys_info.h"
 #include "build/build_config.h"
 #include "net/base/io_buffer.h"
@@ -27,14 +26,14 @@
 // crash possibility.
 // Note that quota assignment is the same for on-disk filesystem and the
 // assigned quota is not guaranteed to be allocatable later.
-bool IsMemoryAvailable(size_t required_memory) {
+bool IsMemoryAvailable(int64_t required_memory) {
 #if BUILDFLAG(IS_FUCHSIA)
   // This function is not implemented on FUCHSIA, yet. (crbug.com/986608)
   return true;
 #else
-  uint64_t max_allocatable =
+  int64_t max_allocatable =
       std::min(base::SysInfo::AmountOfAvailablePhysicalMemory(),
-               static_cast<uint64_t>(partition_alloc::MaxDirectMapped()));
+               static_cast<int64_t>(partition_alloc::MaxDirectMapped()));
 
   return max_allocatable >= required_memory;
 #endif
@@ -336,13 +335,12 @@
     return base::File::FILE_ERROR_NOT_FOUND;
 
   // Fail if enough memory is not available.
-  if (!base::IsValueInRangeForNumericType<size_t>(length) ||
-      (static_cast<size_t>(length) > dp->entry->file_content.capacity() &&
-       !IsMemoryAvailable(static_cast<size_t>(length)))) {
+  if (static_cast<size_t>(length) > dp->entry->file_content.capacity() &&
+      !IsMemoryAvailable(length)) {
     return base::File::FILE_ERROR_NO_SPACE;
   }
 
-  dp->entry->file_content.resize(static_cast<size_t>(length));
+  dp->entry->file_content.resize(length);
   return base::File::FILE_OK;
 }
 
@@ -622,7 +620,7 @@
   }
 
   // Fail if enough memory is not available.
-  if (!IsMemoryAvailable(static_cast<size_t>(source_info.size)))
+  if (!IsMemoryAvailable(source_info.size))
     return base::File::FILE_ERROR_NO_SPACE;
 
   // Create file.
diff --git a/storage/browser/quota/quota_device_info_helper.cc b/storage/browser/quota/quota_device_info_helper.cc
index cf12c20..8f41544 100644
--- a/storage/browser/quota/quota_device_info_helper.cc
+++ b/storage/browser/quota/quota_device_info_helper.cc
@@ -17,7 +17,7 @@
   return disk_space;
 }
 
-uint64_t QuotaDeviceInfoHelper::AmountOfPhysicalMemory() const {
+int64_t QuotaDeviceInfoHelper::AmountOfPhysicalMemory() const {
   return base::SysInfo::AmountOfPhysicalMemory();
 }
 
diff --git a/storage/browser/quota/quota_device_info_helper.h b/storage/browser/quota/quota_device_info_helper.h
index 1f865d8..2ce8b16 100644
--- a/storage/browser/quota/quota_device_info_helper.h
+++ b/storage/browser/quota/quota_device_info_helper.h
@@ -25,7 +25,7 @@
 
   virtual int64_t AmountOfTotalDiskSpace(const base::FilePath& path) const;
 
-  virtual uint64_t AmountOfPhysicalMemory() const;
+  virtual int64_t AmountOfPhysicalMemory() const;
 };  // class QuotaDeviceInfoHelper
 
 }  // namespace storage
diff --git a/storage/browser/quota/quota_settings.cc b/storage/browser/quota/quota_settings.cc
index 718e6cf..c2a5a20 100644
--- a/storage/browser/quota/quota_settings.cc
+++ b/storage/browser/quota/quota_settings.cc
@@ -37,7 +37,7 @@
 }
 
 QuotaSettings CalculateIncognitoDynamicSettings(
-    uint64_t physical_memory_amount) {
+    int64_t physical_memory_amount) {
   // The incognito pool size is a fraction of the amount of system memory.
   double incognito_pool_size_ratio =
       kIncognitoQuotaRatioLowerBound +
diff --git a/storage/browser/quota/quota_settings_unittest.cc b/storage/browser/quota/quota_settings_unittest.cc
index 84e03cb..ef2bf9a 100644
--- a/storage/browser/quota/quota_settings_unittest.cc
+++ b/storage/browser/quota/quota_settings_unittest.cc
@@ -8,7 +8,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
@@ -23,8 +22,8 @@
 
 namespace {
 
-constexpr uint64_t kLowPhysicalMemory = 1024 * 1024;
-constexpr uint64_t kHighPhysicalMemory = 65536 * kLowPhysicalMemory;
+constexpr int64_t kLowPhysicalMemory = 1024 * 1024;
+constexpr int64_t kHighPhysicalMemory = 65536 * kLowPhysicalMemory;
 
 }  // namespace
 
@@ -34,7 +33,7 @@
  public:
   MockQuotaDeviceInfoHelper() = default;
   MOCK_CONST_METHOD1(AmountOfTotalDiskSpace, int64_t(const base::FilePath&));
-  MOCK_CONST_METHOD0(AmountOfPhysicalMemory, uint64_t());
+  MOCK_CONST_METHOD0(AmountOfPhysicalMemory, int64_t());
 };
 
 class QuotaSettingsTest : public testing::Test {
@@ -72,25 +71,23 @@
 
  protected:
   void SetUpDeviceInfoHelper(const int expected_calls,
-                             const uint64_t physical_memory_amount) {
+                             const int64_t physical_memory_amount) {
     ON_CALL(device_info_helper_, AmountOfPhysicalMemory())
         .WillByDefault(::testing::Return(physical_memory_amount));
     EXPECT_CALL(device_info_helper_, AmountOfPhysicalMemory())
         .Times(expected_calls);
   }
 
-  void GetAndTestSettings(const uint64_t physical_memory_amount) {
+  void GetAndTestSettings(const int64_t physical_memory_amount) {
     absl::optional<QuotaSettings> settings =
         GetSettings(true, &device_info_helper_);
     ASSERT_TRUE(settings.has_value());
-    const uint64_t pool_size =
-        base::checked_cast<uint64_t>(settings->pool_size);
     EXPECT_LE(
         physical_memory_amount * GetIncognitoQuotaRatioLowerBound_ForTesting(),
-        pool_size);
+        settings->pool_size);
     EXPECT_GE(
         physical_memory_amount * GetIncognitoQuotaRatioUpperBound_ForTesting(),
-        pool_size);
+        settings->pool_size);
   }
 
  private:
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index 73463a2..cadbf01d 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1808,7 +1808,6 @@
   "lacros-amd64-generic-chrome": {
     "additional_compile_targets": [
       "chrome",
-      "lacros_version_metadata",
       "linux_symbols",
       "symupload",
       "strip_chrome_binary"
@@ -1909,7 +1908,6 @@
   "lacros-amd64-generic-chrome-skylab": {
     "additional_compile_targets": [
       "chrome",
-      "lacros_version_metadata",
       "linux_symbols",
       "symupload",
       "strip_chrome_binary"
@@ -2048,7 +2046,6 @@
   "lacros-arm-generic-chrome": {
     "additional_compile_targets": [
       "chrome",
-      "lacros_version_metadata",
       "linux_symbols",
       "symupload",
       "strip_chrome_binary"
@@ -2082,7 +2079,6 @@
   "lacros-arm-generic-chrome-skylab": {
     "additional_compile_targets": [
       "chrome",
-      "lacros_version_metadata",
       "linux_symbols",
       "symupload",
       "strip_chrome_binary"
@@ -2387,7 +2383,6 @@
   "lacros-arm64-generic-chrome": {
     "additional_compile_targets": [
       "chrome",
-      "lacros_version_metadata",
       "linux_symbols",
       "symupload",
       "strip_chrome_binary"
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index e0b8a9d..ee14d51 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1061,7 +1061,7 @@
           "--browser=cros-chrome",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --force_high_performance_gpu",
+          "--extra-browser-args=--log-level=0 --js-flags=--expose-gc --force_high_performance_gpu --disable-features=BackgroundVideoPauseOptimization",
           "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json",
           "--remote=127.0.0.1",
           "--remote-ssh-port=9222"
@@ -1492,6 +1492,11 @@
       "chrome"
     ]
   },
+  "lacros-arm64-generic-rel": {
+    "additional_compile_targets": [
+      "chrome"
+    ]
+  },
   "linux-ash-chromium-generator-rel": {
     "additional_compile_targets": [
       "chromiumos_preflight",
diff --git a/testing/buildbot/chromium.json b/testing/buildbot/chromium.json
index 6faf5fa..10fb630 100644
--- a/testing/buildbot/chromium.json
+++ b/testing/buildbot/chromium.json
@@ -23,14 +23,12 @@
   },
   "lacros-arm-archive-rel": {
     "additional_compile_targets": [
-      "chrome",
-      "lacros_version_metadata"
+      "chrome"
     ]
   },
   "lacros64-archive-rel": {
     "additional_compile_targets": [
-      "chrome",
-      "lacros_version_metadata"
+      "chrome"
     ]
   },
   "linux-archive-dbg": {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index f18e17c..ffc9b61 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -1312,8 +1312,7 @@
   },
   "chromeos-amd64-generic-lacros-builder-perf": {
     "additional_compile_targets": [
-      "chrome",
-      "lacros_version_metadata"
+      "chrome"
     ],
     "isolated_scripts": [
       {
@@ -1351,8 +1350,7 @@
   },
   "chromeos-arm-generic-lacros-builder-perf": {
     "additional_compile_targets": [
-      "chrome",
-      "lacros_version_metadata"
+      "chrome"
     ],
     "isolated_scripts": [
       {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 31b08fc..4eaca50 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1177,10 +1177,6 @@
       "--logs-dir=${ISOLATED_OUTDIR}",
     ],
   },
-  "lacros_version_metadata": {
-    "label": "//build/lacros:lacros_version_metadata",
-    "type": "additional_compile_target",
-  },
   "lacros_variations_tast_tests" : {
     "label": "//chromeos/lacros:lacros_variations_tast_tests",
     "type": "generated_script",
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index 1695c61..282e66f 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1031,8 +1031,7 @@
   },
   "lacros-amd64-generic-chrome-fyi": {
     "additional_compile_targets": [
-      "chrome",
-      "lacros_version_metadata"
+      "chrome"
     ],
     "skylab_tests": [
       {
@@ -1179,8 +1178,7 @@
   },
   "lacros-arm-generic-chrome-fyi": {
     "additional_compile_targets": [
-      "chrome",
-      "lacros_version_metadata"
+      "chrome"
     ],
     "skylab_tests": [
       {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 5f4d6e71..ff111a1 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -3741,6 +3741,10 @@
     ],
     'modifications': {
       'chromeos-amd64-generic-rel': {
+        'args': [
+          # Added to debug crbug.com/1293967.
+          '--extra-browser-args=--disable-features=BackgroundVideoPauseOptimization',
+        ],
         'swarming': {
           'quickrun_shards': 40,
         },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index d6e2a48..edcd1c4f4 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -181,7 +181,6 @@
       'lacros-amd64-generic-chrome': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
           'linux_symbols',
           'symupload',
           'strip_chrome_binary',
@@ -202,7 +201,6 @@
       'lacros-amd64-generic-chrome-skylab': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
           'linux_symbols',
           'symupload',
           'strip_chrome_binary',
@@ -218,7 +216,6 @@
       'lacros-arm-generic-chrome': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
           'linux_symbols',
           'symupload',
           'strip_chrome_binary'
@@ -236,7 +233,6 @@
       'lacros-arm-generic-chrome-skylab': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
           'linux_symbols',
           'symupload',
           'strip_chrome_binary'
@@ -252,7 +248,6 @@
       'lacros-arm64-generic-chrome': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
           'linux_symbols',
           'symupload',
           'strip_chrome_binary'
@@ -378,14 +373,12 @@
       'lacros-arm-archive-rel': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
         ],
         'os_type': 'chromeos',
       },
       'lacros64-archive-rel': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
         ],
         'os_type': 'chromeos',
       },
@@ -1613,6 +1606,12 @@
         ],
         'os_type': 'chromeos'
       },
+      'lacros-arm64-generic-rel': {
+        'additional_compile_targets': [
+          'chrome',
+        ],
+        'os_type': 'chromeos'
+      },
       'linux-ash-chromium-generator-rel': {
         'additional_compile_targets': [
           'chromiumos_preflight',
@@ -6510,7 +6509,6 @@
       'lacros-amd64-generic-chrome-fyi': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
         ],
         'test_suites': {
           'skylab_tests': 'lacros_skylab_tests_amd64_generic_fyi',
@@ -6527,7 +6525,6 @@
       'lacros-arm-generic-chrome-fyi': {
         'additional_compile_targets': [
           'chrome',
-          'lacros_version_metadata',
         ],
         'test_suites': {
           'skylab_tests': 'lacros_skylab_arm_fyi',
diff --git a/testing/libfuzzer/fuzzers/woff2_corpus/6df91fe5cbca947ae7b7b43d4cd4a861213fae9f b/testing/libfuzzer/fuzzers/woff2_corpus/6df91fe5cbca947ae7b7b43d4cd4a861213fae9f
new file mode 100644
index 0000000..3b3da26e
--- /dev/null
+++ b/testing/libfuzzer/fuzzers/woff2_corpus/6df91fe5cbca947ae7b7b43d4cd4a861213fae9f
Binary files differ
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 126c075..ea70534 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2719,6 +2719,21 @@
             ]
         }
     ],
+    "CommerceHintAndroid": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "enabled_commerce_hint_20220623",
+                    "enable_features": [
+                        "CommerceHintAndroid"
+                    ]
+                }
+            ]
+        }
+    ],
     "CommerceMerchantViewer": [
         {
             "platforms": [
@@ -9378,6 +9393,46 @@
                         "VerifyDidCommitParams"
                     ],
                     "disable_features": []
+                },
+                {
+                    "name": "EnabledWithoutShouldReplace",
+                    "params": {
+                        "gesture": "true",
+                        "http_status_code": "true",
+                        "intended_as_new_entry": "true",
+                        "is_overriding_user_agent": "true",
+                        "method": "true",
+                        "origin": "true",
+                        "post_id": "true",
+                        "should_replace_current_entry": "false",
+                        "should_update_history": "true",
+                        "url": "true",
+                        "url_is_unreachable": "true"
+                    },
+                    "enable_features": [
+                        "VerifyDidCommitParams"
+                    ],
+                    "disable_features": []
+                },
+                {
+                    "name": "EnabledWithoutShouldReplaceAndURLIsUnreachable",
+                    "params": {
+                        "gesture": "true",
+                        "http_status_code": "true",
+                        "intended_as_new_entry": "true",
+                        "is_overriding_user_agent": "true",
+                        "method": "true",
+                        "origin": "true",
+                        "post_id": "true",
+                        "should_replace_current_entry": "false",
+                        "should_update_history": "true",
+                        "url": "true",
+                        "url_is_unreachable": "false"
+                    },
+                    "enable_features": [
+                        "VerifyDidCommitParams"
+                    ],
+                    "disable_features": []
                 }
             ]
         }
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index c366835..b5cf29c3 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -1479,9 +1479,6 @@
     "AllowSourceSwitchOnPausedVideoMediaStream",
     base::FEATURE_ENABLED_BY_DEFAULT};
 
-const base::Feature kDispatchPopstateSync{"DispatchPopstateSync",
-                                          base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Exposes non-standard stats in the WebRTC getStats() API.
 const base::Feature kWebRtcExposeNonStandardStats{
     "WebRtc-ExposeNonStandardStats", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 56ffce0ed..cd7a895f 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -729,10 +729,6 @@
 BLINK_COMMON_EXPORT extern const base::Feature
     kAllowSourceSwitchOnPausedVideoMediaStream;
 
-// Kill switch for firing popstate immediately, instead of deferring it until
-// after onload.
-BLINK_COMMON_EXPORT extern const base::Feature kDispatchPopstateSync;
-
 // If enabled, expose non-standard stats in the WebRTC getStats API.
 BLINK_COMMON_EXPORT extern const base::Feature kWebRtcExposeNonStandardStats;
 
diff --git a/third_party/blink/public/mojom/frame/pending_beacon.mojom b/third_party/blink/public/mojom/frame/pending_beacon.mojom
index 406f3b1..2e8576a 100644
--- a/third_party/blink/public/mojom/frame/pending_beacon.mojom
+++ b/third_party/blink/public/mojom/frame/pending_beacon.mojom
@@ -5,6 +5,7 @@
 module blink.mojom;
 
 import "mojo/public/mojom/base/time.mojom";
+import "services/network/public/mojom/url_request.mojom";
 import "url/mojom/url.mojom";
 
 // The HTTP methods that pending beacons can use.
@@ -41,8 +42,12 @@
   // further calls can be made.
   Deactivate();
 
-  // Sets data for the pending beacon.
-  SetData(string data);
+  // Sets request data for the pending beacon.
+  // It is only allowed when the receiving pending beacon's `BeaconMethod` is
+  // kPost.
+  // `content_type` must be empty string or a safelisted one.
+  SetRequestData(network.mojom.URLRequestBody request_body,
+                 string content_type);
 
   // Sends the pending beacon immediately.
   // Calling this will close the message pipe for the interface as well, so no
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index ab7f0b5..c1f153a 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -729,8 +729,10 @@
   ArrayBufferAllocator() : total_allocation_(0) {
     // size_t may be equivalent to uint32_t or uint64_t, cast all values to
     // uint64_t to compare.
-    uint64_t virtual_size = base::SysInfo::AmountOfVirtualMemory();
-    uint64_t size_t_max = std::numeric_limits<std::size_t>::max();
+    uint64_t virtual_size =
+        static_cast<uint64_t>(base::SysInfo::AmountOfVirtualMemory());
+    uint64_t size_t_max =
+        static_cast<uint64_t>(std::numeric_limits<std::size_t>::max());
     DCHECK(virtual_size < size_t_max);
     // If AmountOfVirtualMemory() returns 0, there is no limit on virtual
     // memory, do not limit the total allocation. Otherwise, Limit the total
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py b/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py
index 7a581d4..d8a8067a 100644
--- a/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py
+++ b/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py
@@ -270,8 +270,19 @@
                 or matched_global_count > 0)
     else:
         for entry in exposure.global_names_and_features:
-            pred_term = _Expr("${{execution_context}}->{}()".format(
-                GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name]))
+            try:
+                execution_context_check = GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[
+                    entry.global_name]
+            except KeyError:
+                # We don't currently have a general way of checking the exposure
+                # of [TargetOfExposed] exposure. If this is actually a global,
+                # add it to GLOBAL_NAME_TO_EXECUTION_CONTEXT_CHECK.
+                return _Expr(
+                    "(NOTREACHED() << \"{} exposure test is not supported at runtime\", false)"
+                    .format(entry.global_name))
+
+            pred_term = _Expr(
+                "${{execution_context}}->{}()".format(execution_context_check))
             if not entry.feature:
                 uncond_exposed_terms.append(pred_term)
             else:
@@ -314,6 +325,8 @@
             top_level_terms.append(expr_or(cond_exposed_terms))
         if feature_enabled_terms:
             top_level_terms.append(expr_and(feature_enabled_terms))
+        if context_enabled_terms:
+            top_level_terms.append(expr_or(context_enabled_terms))
         return expr_and(top_level_terms)
 
     all_enabled_terms = [_Expr("${feature_selector}.IsAll()")]
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
index 675d1f6..98a5e7a9 100644
--- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
+++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -6754,6 +6754,46 @@
 
 
 # ----------------------------------------------------------------------------
+# IsExposed
+# ----------------------------------------------------------------------------
+
+
+def make_is_exposed(cg_context, function_name):
+    assert isinstance(cg_context, CodeGenContext)
+    assert function_name == "IsExposed"
+    class_like = cg_context.class_like
+
+    is_exposed_decl = CxxFuncDeclNode(name=function_name,
+                                      arg_decls=["ExecutionContext*"],
+                                      return_type="bool",
+                                      static=True)
+    is_exposed_decl.accumulate(
+        CodeGenAccumulator.require_class_decls(["ExecutionContext"]))
+
+    is_exposed_def = CxxFuncDefNode(
+        name=function_name,
+        arg_decls=["ExecutionContext* execution_context"],
+        return_type="bool",
+        class_name=cg_context.class_name)
+    is_exposed_def.accumulate(
+        CodeGenAccumulator.require_include_headers([
+            "third_party/blink/renderer/core/execution_context/execution_context.h"
+        ]))
+    is_exposed_def.body.add_template_vars(
+        {"execution_context": "execution_context"})
+    bind_installer_local_vars(is_exposed_def.body, cg_context)
+    # If [Exposed] exists at all, then this exposure condition should be valid.
+    # Otherwise, it is not an exposed interface at all.
+    if class_like.exposure.global_names_and_features:
+        is_exposed_def.body.append(
+            FormatNode("return {};",
+                       expr_from_exposure(class_like.exposure).to_text()))
+    else:
+        is_exposed_def.body.append(TextNode("return false;"))
+    return (is_exposed_decl, is_exposed_def)
+
+
+# ----------------------------------------------------------------------------
 # WrapperTypeInfo
 # ----------------------------------------------------------------------------
 
@@ -7479,6 +7519,10 @@
          has_context_dependent_props=bool(
              install_context_dependent_props_decl))
 
+    # Exposure
+    (is_exposed_decl,
+     is_exposed_def) = make_is_exposed(cg_context, "IsExposed")
+
     # Cross-component trampolines
     if is_cross_components:
         (cross_component_init_decl, cross_component_init_def,
@@ -7610,6 +7654,15 @@
             EmptyNode(),
         ])
 
+    api_class_def.public_section.extend([
+        is_exposed_decl,
+        EmptyNode(),
+    ])
+    api_source_blink_ns.body.extend([
+        is_exposed_def,
+        EmptyNode(),
+    ])
+
     api_class_def.public_section.append(get_wrapper_type_info_def)
     api_class_def.public_section.append(EmptyNode())
     api_class_def.private_section.append(wrapper_type_info_var_def)
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc
index b517c39..f2c0662 100644
--- a/third_party/blink/renderer/controller/blink_initializer.cc
+++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -135,7 +135,7 @@
     // Try to reserve as much address space as we reasonably can.
     const size_t kMB = 1024 * 1024;
     for (size_t size = 512 * kMB; size >= 32 * kMB; size -= 16 * kMB) {
-      if (base::ReserveAddressSpace(size)) {
+      if (partition_alloc::ReserveAddressSpace(size)) {
         break;
       }
     }
diff --git a/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc b/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc
index dec4baf..8e2ba7b 100644
--- a/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc
+++ b/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc
@@ -69,15 +69,21 @@
 }
 
 double MemoryThresholdParam() {
-  int physical_memory_mb = base::SysInfo::AmountOfPhysicalMemoryMB();
-  if (physical_memory_mb > 3.1 * 1024)
-    return MemoryThresholdParamOf4GbDevices();
-  if (physical_memory_mb > 2.1 * 1024)
-    return MemoryThresholdParamOf3GbDevices();
-  if (physical_memory_mb > 1.1 * 1024)
-    return MemoryThresholdParamOf2GbDevices();
-  return (physical_memory_mb > 600) ? MemoryThresholdParamOf1GbDevices()
-                                    : MemoryThresholdParamOf512MbDevices();
+  int64_t physical_memory = base::SysInfo::AmountOfPhysicalMemory();
+  double memory_threshold_mb = kDefaultMemoryThresholdMB;
+
+  if (physical_memory > 3.1 * 1024 * 1024 * 1024)
+    memory_threshold_mb = MemoryThresholdParamOf4GbDevices();
+  else if (physical_memory > 2.1 * 1024 * 1024 * 1024)
+    memory_threshold_mb = MemoryThresholdParamOf3GbDevices();
+  else if (physical_memory > 1.1 * 1024 * 1024 * 1024)
+    memory_threshold_mb = MemoryThresholdParamOf2GbDevices();
+  else if (physical_memory > 600 * 1024 * 1024)
+    memory_threshold_mb = MemoryThresholdParamOf1GbDevices();
+  else
+    memory_threshold_mb = MemoryThresholdParamOf512MbDevices();
+
+  return memory_threshold_mb;
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
index 7975006..651cf78 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -133,6 +133,38 @@
   style.SetTextUnderlinePosition(kTextUnderlinePositionAuto);
 }
 
+// Adjust style for anchor() and anchor-size() queries.
+void AdjustAnchorQueryStyles(ComputedStyle& style) {
+  if (!RuntimeEnabledFeatures::CSSAnchorPositioningEnabled())
+    return;
+
+  // anchor() and anchor-size() can only be used on absolutely positioned
+  // elements.
+  if (style.GetPosition() != EPosition::kAbsolute &&
+      style.GetPosition() != EPosition::kFixed) {
+    if (style.Left().HasAnchorQueries())
+      style.SetLeft(Length::Auto());
+    if (style.Right().HasAnchorQueries())
+      style.SetRight(Length::Auto());
+    if (style.Top().HasAnchorQueries())
+      style.SetTop(Length::Auto());
+    if (style.Bottom().HasAnchorQueries())
+      style.SetBottom(Length::Auto());
+    if (style.Width().HasAnchorQueries())
+      style.SetWidth(Length::Auto());
+    if (style.MinWidth().HasAnchorQueries())
+      style.SetMinWidth(Length::Auto());
+    if (style.MaxWidth().HasAnchorQueries())
+      style.SetMaxWidth(Length::Auto());
+    if (style.Height().HasAnchorQueries())
+      style.SetHeight(Length::Auto());
+    if (style.MinHeight().HasAnchorQueries())
+      style.SetMinHeight(Length::Auto());
+    if (style.MaxHeight().HasAnchorQueries())
+      style.SetMaxHeight(Length::Auto());
+  }
+}
+
 // Returns the `<display-outside>` for a `EDisplay` value.
 // https://drafts.csswg.org/css-display-3/#propdef-display
 EDisplay DisplayOutside(EDisplay display) {
@@ -1004,6 +1036,8 @@
     }
   }
 
+  AdjustAnchorQueryStyles(style);
+
   if (!HasFullNGFragmentationSupport()) {
     // When establishing a block fragmentation context for LayoutNG, we require
     // that everything fragmentable inside can be laid out by NG natively, since
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 6eb9475..071481b 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3790,7 +3790,6 @@
 }
 
 void WebViewImpl::StopDeferringMainFrameUpdate() {
-  DCHECK(MainFrameImpl());
   scoped_defer_main_frame_update_ = nullptr;
 }
 
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 8287e4c..2b9a90b0 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -776,9 +776,6 @@
   // 4.6.4. Fire an event named pageshow at the Document object's relevant
   // global object, ...
   EnqueueNonPersistedPageshowEvent();
-
-  if (pending_state_object_)
-    EnqueuePopstateEvent(std::move(pending_state_object_));
 }
 
 void LocalDOMWindow::EnqueueNonPersistedPageshowEvent() {
@@ -843,29 +840,12 @@
                      TaskType::kDOMManipulation);
 }
 
-void LocalDOMWindow::EnqueuePopstateEvent(
+void LocalDOMWindow::DispatchPopstateEvent(
     scoped_refptr<SerializedScriptValue> state_object) {
-  // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs
-  // to fire asynchronously
+  DCHECK(GetFrame());
   DispatchEvent(*PopStateEvent::Create(std::move(state_object), history()));
 }
 
-void LocalDOMWindow::StatePopped(
-    scoped_refptr<SerializedScriptValue> state_object) {
-  if (!GetFrame())
-    return;
-
-  // TODO(crbug.com/1254926): Remove pending_state_object_ and the capacity to
-  // delay popstate until after the load event once the behavior is proven
-  // compatible in M103.
-  if (document()->IsLoadCompleted() ||
-      base::FeatureList::IsEnabled(features::kDispatchPopstateSync)) {
-    EnqueuePopstateEvent(std::move(state_object));
-  } else {
-    pending_state_object_ = std::move(state_object);
-  }
-}
-
 LocalDOMWindow::~LocalDOMWindow() = default;
 
 void LocalDOMWindow::Dispose() {
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index 42a9669a..3d9872cb 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -399,10 +399,9 @@
   void EnqueueDocumentEvent(Event&, TaskType);
   void EnqueueNonPersistedPageshowEvent();
   void EnqueueHashchangeEvent(const String& old_url, const String& new_url);
-  void EnqueuePopstateEvent(scoped_refptr<SerializedScriptValue>);
+  void DispatchPopstateEvent(scoped_refptr<SerializedScriptValue>);
   void DispatchWindowLoadEvent();
   void DocumentWasClosed();
-  void StatePopped(scoped_refptr<SerializedScriptValue>);
 
   void AcceptLanguagesChanged();
 
@@ -532,8 +531,6 @@
   String status_;
   String default_status_;
 
-  scoped_refptr<SerializedScriptValue> pending_state_object_;
-
   HeapHashSet<WeakMember<EventListenerObserver>> event_listener_observers_;
 
   // Trackers for delegated payment and fullscreen requests.  These are related
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index d5da97b..b7555f31 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -4555,11 +4555,6 @@
 }
 
 void LocalFrameView::BeginLifecycleUpdates() {
-  // Avoid pumping frames for the initially empty document.
-  // TODO(schenney): This seems pointless because main frame updates do occur
-  // for pages like about:blank, at least according to log messages.
-  if (GetFrame().GetDocument()->IsInitialEmptyDocument())
-    return;
   lifecycle_updates_throttled_ = false;
 
   LayoutView* layout_view = GetLayoutView();
@@ -4573,6 +4568,10 @@
   ScheduleAnimation();
   SetIntersectionObservationState(kRequired);
 
+  // Do not report paint timing for the initially empty document.
+  if (GetFrame().GetDocument()->IsInitialEmptyDocument())
+    MarkIneligibleToPaint();
+
   // Non-main-frame lifecycle and commit deferral are controlled by their
   // main frame.
   if (!GetFrame().IsMainFrame())
diff --git a/third_party/blink/renderer/core/frame/local_frame_view_test.cc b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
index ae45169..834c2f2 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view_test.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
@@ -79,6 +79,8 @@
   Persistent<AnimationMockChromeClient> chrome_client_;
 };
 
+using LocalFrameViewSimTest = SimTest;
+
 TEST_F(LocalFrameViewTest, SetPaintInvalidationDuringUpdateAllLifecyclePhases) {
   SetBodyInnerHTML("<div id='a' style='color: blue'>A</div>");
   GetDocument().getElementById("a")->setAttribute(html_names::kStyleAttr,
@@ -345,7 +347,7 @@
 // Ensure the fragment navigation "scroll into view and focus" behavior doesn't
 // activate synchronously while rendering is blocked waiting on a stylesheet.
 // See https://crbug.com/851338.
-TEST_F(SimTest, FragmentNavChangesFocusWhileRenderingBlocked) {
+TEST_F(LocalFrameViewSimTest, FragmentNavChangesFocusWhileRenderingBlocked) {
   SimRequest main_resource("https://example.com/test.html", "text/html");
   SimSubresourceRequest css_resource("https://example.com/sheet.css",
                                      "text/css");
@@ -403,7 +405,7 @@
       << "Scroll offset wasn't changed after load completed.";
 }
 
-TEST_F(SimTest, ForcedLayoutWithIncompleteSVGChildFrame) {
+TEST_F(LocalFrameViewSimTest, ForcedLayoutWithIncompleteSVGChildFrame) {
   SimRequest main_resource("https://example.com/test.html", "text/html");
   SimRequest svg_resource("https://example.com/file.svg", "image/svg+xml");
 
@@ -441,9 +443,6 @@
   GetDocument().View()->MarkFirstEligibleToPaint();
   EXPECT_FALSE(parent_timing.FirstEligibleToPaint().is_null());
 
-  // Subframes are throttled when first loaded.
-  EXPECT_TRUE(ChildDocument().View()->ShouldThrottleRenderingForTest());
-
   // Toggle paint elgibility to true.
   ChildDocument().OverrideIsInitialEmptyDocument();
   ChildDocument().View()->BeginLifecycleUpdates();
@@ -468,7 +467,7 @@
   GetFrame().View()->SetTargetStateForTest(DocumentLifecycle::kUninitialized);
 }
 
-TEST_F(SimTest, PaintEligibilityNoSubframe) {
+TEST_F(LocalFrameViewSimTest, PaintEligibilityNoSubframe) {
   SimRequest resource("https://example.com/", "text/html");
 
   LoadURL("https://example.com/");
@@ -485,12 +484,12 @@
   EXPECT_FALSE(timing.FirstEligibleToPaint().is_null());
 }
 
-TEST_F(SimTest, SameOriginPaintEligibility) {
+TEST_F(LocalFrameViewSimTest, SameOriginPaintEligibility) {
   SimRequest resource("https://example.com/", "text/html");
 
   LoadURL("https://example.com/");
   resource.Complete(R"HTML(
-      <iframe id=frame top=4000px left=4000px>
+      <iframe id=frame style="position:absolute;top:4000px;left:4000px">
         <p>Hello</p>
       </iframe>
     )HTML");
@@ -502,7 +501,8 @@
 
   EXPECT_FALSE(GetDocument().View()->ShouldThrottleRenderingForTest());
 
-  // Same origin frames are not throttled.
+  // Same origin frames are not throttled, but initially empty frame
+  // are not eligible to paint.
   EXPECT_FALSE(frame_document->View()->ShouldThrottleRenderingForTest());
   EXPECT_TRUE(frame_timing.FirstEligibleToPaint().is_null());
 
@@ -513,12 +513,13 @@
   EXPECT_FALSE(frame_timing.FirstEligibleToPaint().is_null());
 }
 
-TEST_F(SimTest, CrossOriginPaintEligibility) {
+TEST_F(LocalFrameViewSimTest, CrossOriginPaintEligibility) {
   SimRequest resource("https://example.com/", "text/html");
 
   LoadURL("https://example.com/");
   resource.Complete(R"HTML(
-      <iframe id=frame srcdoc ="<p>Hello</p>" sandbox top=4000px left=4000px>
+      <iframe id=frame srcdoc ="<p>Hello</p>" sandbox
+        style="position:absolute;top:4000px;left:4000px">
       </iframe>
     )HTML");
 
@@ -527,6 +528,11 @@
   auto* frame_document = frame_element->contentDocument();
   PaintTiming& frame_timing = PaintTiming::From(*frame_document);
 
+  // We do one lifecycle update before throttling initially empty documents.
+  GetDocument().View()->UpdateAllLifecyclePhasesForTest();
+  // And another to mark ineligible for paint.
+  GetDocument().View()->UpdateAllLifecyclePhasesForTest();
+
   EXPECT_FALSE(GetDocument().View()->ShouldThrottleRenderingForTest());
 
   // Hidden cross origin frames are throttled.
@@ -540,7 +546,7 @@
   EXPECT_TRUE(frame_timing.FirstEligibleToPaint().is_null());
 }
 
-TEST_F(SimTest, NestedCrossOriginPaintEligibility) {
+TEST_F(LocalFrameViewSimTest, NestedCrossOriginPaintEligibility) {
   // Create a document with doubly nested iframes.
   SimRequest main_resource("https://example.com/", "text/html");
   SimRequest frame_resource("https://example.com/iframe.html", "text/html");
@@ -548,7 +554,8 @@
   LoadURL("https://example.com/");
   main_resource.Complete("<iframe id=outer src=iframe.html></iframe>");
   frame_resource.Complete(R"HTML(
-      <iframe id=inner srcdoc ="<p>Hello</p>" sandbox top=4000px left=4000px>
+      <iframe id=inner srcdoc ="<p>Hello</p>" sandbox
+        style="position:absolute;top:4000px;left:4000px">
       </iframe>
     )HTML");
 
@@ -562,9 +569,14 @@
   auto* inner_frame_document = inner_frame_element->contentDocument();
   PaintTiming& inner_frame_timing = PaintTiming::From(*inner_frame_document);
 
+  // We do one lifecycle update before throttling initially empty documents.
+  GetDocument().View()->UpdateAllLifecyclePhasesForTest();
+  // And another to mark ineligible for paint.
+  GetDocument().View()->UpdateAllLifecyclePhasesForTest();
+
   EXPECT_FALSE(GetDocument().View()->ShouldThrottleRenderingForTest());
   EXPECT_FALSE(outer_frame_document->View()->ShouldThrottleRenderingForTest());
-  EXPECT_TRUE(outer_frame_timing.FirstEligibleToPaint().is_null());
+  EXPECT_FALSE(outer_frame_timing.FirstEligibleToPaint().is_null());
   EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRenderingForTest());
   EXPECT_TRUE(inner_frame_timing.FirstEligibleToPaint().is_null());
 
diff --git a/third_party/blink/renderer/core/frame/pending_beacon.cc b/third_party/blink/renderer/core/frame/pending_beacon.cc
index 9460ae3..0bcb3c9 100644
--- a/third_party/blink/renderer/core/frame/pending_beacon.cc
+++ b/third_party/blink/renderer/core/frame/pending_beacon.cc
@@ -6,14 +6,15 @@
 
 #include "third_party/blink/public/mojom/frame/pending_beacon.mojom-blink.h"
 #include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/public/platform/web_url_request_util.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_beacon_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_blob_formdata_readablestream_urlsearchparams_usvstring.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/html/forms/form_data.h"
-#include "third_party/blink/renderer/core/url/url_search_params.h"
+#include "third_party/blink/renderer/core/loader/beacon_data.h"
+#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
 #include "third_party/blink/renderer/platform/network/encoded_form_data.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
@@ -108,23 +109,39 @@
 
 void PendingBeacon::setData(
     const V8UnionReadableStreamOrXMLHttpRequestBodyInit* data) {
+  if (method_ == http_names::kGET) {
+    // TODO(crbug.com/1293679): Throw errors.
+    return;
+  }
+  using ContentType =
+      V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType;
   switch (data->GetContentType()) {
-    case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
-        kUSVString: {
-      auto string_data = data->GetAsUSVString();
-      remote_->SetData(string_data);
+    case ContentType::kUSVString: {
+      SetDataInternal(BeaconString(data->GetAsUSVString()));
       return;
     }
-    case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
-        kArrayBuffer:
-    case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
-        kArrayBufferView:
-    case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::kFormData:
-    case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
-        kURLSearchParams:
-    case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::kBlob:
-    case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
-        kReadableStream: {
+    case ContentType::kArrayBuffer: {
+      SetDataInternal(BeaconDOMArrayBuffer(data->GetAsArrayBuffer()));
+      return;
+    }
+    case ContentType::kArrayBufferView: {
+      SetDataInternal(
+          BeaconDOMArrayBufferView(data->GetAsArrayBufferView().Get()));
+      return;
+    }
+    case ContentType::kFormData: {
+      SetDataInternal(BeaconFormData(data->GetAsFormData()));
+      return;
+    }
+    case ContentType::kURLSearchParams: {
+      SetDataInternal(BeaconURLSearchParams(data->GetAsURLSearchParams()));
+      return;
+    }
+    case ContentType::kBlob:
+      // TODO(crbug.com/1293679): Decide whether to support blob/file.
+    case ContentType::kReadableStream: {
+      // TODO(crbug.com/1293679): Throw errors.
+      break;
     }
   }
   NOTIMPLEMENTED();
@@ -141,4 +158,17 @@
   }
 }
 
+void PendingBeacon::SetDataInternal(const BeaconData& data) {
+  ResourceRequest request;
+
+  data.Serialize(request);
+  // `WrappedResourceRequest` only works for POST request.
+  request.SetHttpMethod(http_names::kPOST);
+  scoped_refptr<network::ResourceRequestBody> request_body =
+      GetRequestBodyForWebURLRequest(WrappedResourceRequest(request));
+  AtomicString content_type = request.HttpContentType();
+  remote_->SetRequestData(std::move(request_body),
+                          content_type.IsNull() ? "" : content_type);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/pending_beacon.h b/third_party/blink/renderer/core/frame/pending_beacon.h
index 2464a697..00bb9a1 100644
--- a/third_party/blink/renderer/core/frame/pending_beacon.h
+++ b/third_party/blink/renderer/core/frame/pending_beacon.h
@@ -5,18 +5,16 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_PENDING_BEACON_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_PENDING_BEACON_H_
 
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/blink/public/mojom/frame/pending_beacon.mojom-blink.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
-#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h"
 
 namespace blink {
 
+class BeaconData;
 class BeaconOptions;
 
 // Implementation of the Pending Beacon API.
@@ -54,6 +52,8 @@
   void Trace(Visitor*) const override;
 
  private:
+  void SetDataInternal(const BeaconData& beacon_data);
+
   HeapMojoRemote<mojom::blink::PendingBeacon> remote_;
   const String url_;
   const String method_;
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 9f7c3ab..7672f2d 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -38,6 +38,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_focus_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_selection_mode.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
@@ -2072,7 +2073,7 @@
 void HTMLInputElement::setRangeText(const String& replacement,
                                     unsigned start,
                                     unsigned end,
-                                    const String& selection_mode,
+                                    const V8SelectionMode& selection_mode,
                                     ExceptionState& exception_state) {
   if (!input_type_->SupportsSelectionAPI()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index 3ac575e..1505b2e 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -318,7 +318,7 @@
   void setRangeText(const String& replacement,
                     unsigned start,
                     unsigned end,
-                    const String& selection_mode,
+                    const V8SelectionMode& selection_mode,
                     ExceptionState&) final;
 
   HTMLImageLoader* ImageLoader() const { return image_loader_.Get(); }
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc
index 6847276..74180ea6 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/core/html/forms/text_control_element.h"
 
 #include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_selection_mode.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -303,14 +304,15 @@
 
 void TextControlElement::setRangeText(const String& replacement,
                                       ExceptionState& exception_state) {
-  setRangeText(replacement, selectionStart(), selectionEnd(), "preserve",
+  setRangeText(replacement, selectionStart(), selectionEnd(),
+               V8SelectionMode(V8SelectionMode::Enum::kPreserve),
                exception_state);
 }
 
 void TextControlElement::setRangeText(const String& replacement,
                                       unsigned start,
                                       unsigned end,
-                                      const String& selection_mode,
+                                      const V8SelectionMode& selection_mode,
                                       ExceptionState& exception_state) {
   if (start > end) {
     exception_state.ThrowDOMException(
@@ -340,26 +342,31 @@
   SetValue(text.ToString(), TextFieldEventBehavior::kDispatchNoEvent,
            TextControlSetValueSelection::kDoNotSet);
 
-  if (selection_mode == "select") {
-    new_selection_start = start;
-    new_selection_end = start + replacement_length;
-  } else if (selection_mode == "start") {
-    new_selection_start = new_selection_end = start;
-  } else if (selection_mode == "end") {
-    new_selection_start = new_selection_end = start + replacement_length;
-  } else {
-    DCHECK_EQ(selection_mode, "preserve");
-    int delta = replacement_length - (end - start);
-
-    if (new_selection_start > end)
-      new_selection_start += delta;
-    else if (new_selection_start > start)
+  switch (selection_mode.AsEnum()) {
+    case V8SelectionMode::Enum::kSelect:
       new_selection_start = start;
-
-    if (new_selection_end > end)
-      new_selection_end += delta;
-    else if (new_selection_end > start)
       new_selection_end = start + replacement_length;
+      break;
+    case V8SelectionMode::Enum::kStart:
+      new_selection_start = new_selection_end = start;
+      break;
+    case V8SelectionMode::Enum::kEnd:
+      new_selection_start = new_selection_end = start + replacement_length;
+      break;
+    case V8SelectionMode::Enum::kPreserve: {
+      int delta = replacement_length - (end - start);
+
+      if (new_selection_start > end)
+        new_selection_start += delta;
+      else if (new_selection_start > start)
+        new_selection_start = start;
+
+      if (new_selection_end > end)
+        new_selection_end += delta;
+      else if (new_selection_end > start)
+        new_selection_end = start + replacement_length;
+      break;
+    }
   }
 
   setSelectionRangeForBinding(new_selection_start, new_selection_end);
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.h b/third_party/blink/renderer/core/html/forms/text_control_element.h
index 101e703..f96ef1a2 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.h
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.h
@@ -36,6 +36,7 @@
 namespace blink {
 
 class ExceptionState;
+class V8SelectionMode;
 
 enum TextFieldSelectionDirection {
   kSelectionHasNoDirection,
@@ -91,7 +92,7 @@
   virtual void setRangeText(const String& replacement,
                             unsigned start,
                             unsigned end,
-                            const String& selection_mode,
+                            const V8SelectionMode& selection_mode,
                             ExceptionState&);
   // Web-exposed setSelectionRange() function. This schedule to dispatch
   // 'select' event.
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
index 9747534..096058a1 100644
--- a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
+++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
@@ -11,11 +11,13 @@
 #include "third_party/blink/public/platform/web_effective_connection_type.h"
 #include "third_party/blink/public/web/web_local_frame_client.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/frame/frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/html/loading_attribute.h"
 #include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
 #include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
@@ -31,6 +33,41 @@
 
 namespace {
 
+// Determine if the |bounding_client_rect| for a frame indicates that the frame
+// is probably hidden according to some experimental heuristics. Since hidden
+// frames are often used for analytics or communication, and lazily loading them
+// could break their functionality, so these heuristics are used to recognize
+// likely hidden frames and immediately load them so that they can function
+// properly.
+bool IsFrameProbablyHidden(const PhysicalRect& bounding_client_rect,
+                           const Element& element) {
+  // Tiny frames that are 4x4 or smaller are likely not intended to be seen by
+  // the user. Note that this condition includes frames marked as
+  // "display:none", since those frames would have dimensions of 0x0.
+  if (bounding_client_rect.Width() <= 4.0f ||
+      bounding_client_rect.Height() <= 4.0f)
+    return true;
+
+  // Frames that are positioned completely off the page above or to the left are
+  // likely never intended to be visible to the user.
+  if (bounding_client_rect.Right() < 0.0f ||
+      bounding_client_rect.Bottom() < 0.0f)
+    return true;
+
+  const ComputedStyle* style = element.GetComputedStyle();
+  if (style) {
+    switch (style->Visibility()) {
+      case EVisibility::kHidden:
+      case EVisibility::kCollapse:
+        return true;
+      case EVisibility::kVisible:
+        break;
+    }
+  }
+
+  return false;
+}
+
 int GetLazyFrameLoadingViewportDistanceThresholdPx(const Document& document) {
   const Settings* settings = document.GetSettings();
   if (!settings)
@@ -110,12 +147,21 @@
   if (entries.back()->isIntersecting()) {
     RecordInitialDeferralAction(
         FrameInitialDeferralAction::kLoadedNearOrInViewport);
-  } else {
-    RecordInitialDeferralAction(FrameInitialDeferralAction::kDeferred);
+    LoadImmediately();
     return;
   }
 
-  LoadImmediately();
+  LoadingAttributeValue loading_attr = GetLoadingAttributeValue(
+      element_->FastGetAttribute(html_names::kLoadingAttr));
+  if (loading_attr != LoadingAttributeValue::kLazy &&
+      IsFrameProbablyHidden(entries.back()->GetGeometry().TargetRect(),
+                            *element_)) {
+    RecordInitialDeferralAction(FrameInitialDeferralAction::kLoadedHidden);
+    LoadImmediately();
+    return;
+  }
+
+  RecordInitialDeferralAction(FrameInitialDeferralAction::kDeferred);
 }
 
 void LazyLoadFrameObserver::LoadImmediately() {
@@ -176,6 +222,16 @@
   DCHECK(!entries.IsEmpty());
   DCHECK_EQ(element_, entries.back()->target());
 
+  LoadingAttributeValue loading_attr = GetLoadingAttributeValue(
+      element_->FastGetAttribute(html_names::kLoadingAttr));
+  if (loading_attr != LoadingAttributeValue::kLazy &&
+      IsFrameProbablyHidden(entries.back()->GetGeometry().TargetRect(),
+                            *element_)) {
+    visibility_metrics_observer_->disconnect();
+    visibility_metrics_observer_.Clear();
+    return;
+  }
+
   if (!has_above_the_fold_been_set_) {
     is_initially_above_the_fold_ = entries.back()->isIntersecting();
     has_above_the_fold_been_set_ = true;
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer.h b/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
index 85cd7e9..a87d618b 100644
--- a/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
+++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
@@ -37,10 +37,9 @@
     kLoadedNearOrInViewport = 1,
     // The frame was determined to likely be a hidden frame (e.g. analytics or
     // communication iframes), so it was loaded immediately.
-    // Deprecated in Jan 2022.
-    kDeprecatedLoadedHidden = 2,
+    kLoadedHidden = 2,
 
-    kMaxValue = kDeprecatedLoadedHidden
+    kMaxValue = kLoadedHidden
   };
 
   // The loading pipeline for an iframe differs depending on whether the
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
index 11e170f..897c491 100644
--- a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
+++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <tuple>
 
+#include "base/test/scoped_feature_list.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/platform/web_effective_connection_type.h"
 #include "third_party/blink/renderer/core/dom/element.h"
@@ -1041,6 +1042,203 @@
                           WebEffectiveConnectionType::kType3G,
                           WebEffectiveConnectionType::kType4G)));
 
+class LazyEmbedsTest : public LazyLoadFramesParamsTest {
+ public:
+  LazyEmbedsTest() {
+    feature_list_.InitWithFeaturesAndParameters(
+        {
+            {features::kAutomaticLazyFrameLoadingToEmbeds,
+             {{"timeout", "3000"}}},
+            {features::kAutomaticLazyFrameLoadingToEmbedUrls,
+             {{"allowed_websites",
+               "https://crossorigin.com|/display_none.html,"
+               "https://crossorigin.com|/visibility_hidden.html,"
+               "https://crossorigin.com|/tiny.html,"
+               "https://crossorigin.com|/tiny_width.html,"
+               "https://crossorigin.com/|tiny_height.html,"
+               "https://crossorigin.com|/off_screen_left.html,"
+               "https://crossorigin.com|/off_screen_top.html"}}},
+        },
+        {/* disabled_features */});
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_P(LazyEmbedsTest, HiddenAndTinyFrames) {
+  SimRequest main_resource("https://example.com/", "text/html");
+
+  SimRequest display_none_frame_resource(
+      "https://crossorigin.com/display_none.html", "text/html");
+  SimRequest visibility_hidden_frame_resource(
+      "https://crossorigin.com/visibility_hidden.html", "text/html");
+  SimRequest tiny_frame_resource("https://crossorigin.com/tiny.html",
+                                 "text/html");
+  SimRequest tiny_width_frame_resource(
+      "https://crossorigin.com/tiny_width.html", "text/html");
+  SimRequest tiny_height_frame_resource(
+      "https://crossorigin.com/tiny_height.html", "text/html");
+  SimRequest off_screen_left_frame_resource(
+      "https://crossorigin.com/off_screen_left.html", "text/html");
+  SimRequest off_screen_top_frame_resource(
+      "https://crossorigin.com/off_screen_top.html", "text/html");
+
+  LoadURL("https://example.com/");
+
+  main_resource.Complete(String::Format(
+      R"HTML(
+        <head><style>
+          /* Chrome by default sets borders for iframes, so explicitly specify
+           * no borders, padding, or margins here so that the dimensions of the
+           * tiny frames aren't artificially inflated past the dimensions that
+           * the lazy loading logic considers "tiny". */
+          iframe { border-style: none; padding: 0px; margin: 0px; }
+        </style></head>
+
+        <body onload='console.log("main body onload");'>
+        <div style='height: %dpx'></div>
+        <iframe src='https://crossorigin.com/display_none.html'
+             style='display: none;'
+             onload='console.log("display none element onload");'></iframe>
+        <iframe src='https://crossorigin.com/visibility_hidden.html'
+             style='visibility:hidden;width:100px;height:100px;'
+             onload='console.log("visibility hidden element onload");'></iframe>
+        <iframe src='https://crossorigin.com/tiny.html'
+             style='width: 4px; height: 4px;'
+             onload='console.log("tiny element onload");'></iframe>
+        <iframe src='https://crossorigin.com/tiny_width.html'
+             style='width: 0px; height: 50px;'
+             onload='console.log("tiny width element onload");'></iframe>
+        <iframe src='https://crossorigin.com/tiny_height.html'
+             style='width: 50px; height: 0px;'
+             onload='console.log("tiny height element onload");'></iframe>
+        <iframe src='https://crossorigin.com/off_screen_left.html'
+             style='position:relative;right:9000px;width:50px;height:50px;'
+             onload='console.log("off screen left element onload");'></iframe>
+        <iframe src='https://crossorigin.com/off_screen_top.html'
+             style='position:relative;bottom:9000px;width:50px;height:50px;'
+             onload='console.log("off screen top element onload");'></iframe>
+        </body>
+      )HTML",
+      kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+  Compositor().BeginFrame();
+  test::RunPendingTasks();
+
+  display_none_frame_resource.Complete("");
+  visibility_hidden_frame_resource.Complete("");
+  tiny_frame_resource.Complete("");
+  tiny_width_frame_resource.Complete("");
+  tiny_height_frame_resource.Complete("");
+  off_screen_left_frame_resource.Complete("");
+  off_screen_top_frame_resource.Complete("");
+
+  Compositor().BeginFrame();
+  test::RunPendingTasks();
+
+  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+  EXPECT_TRUE(ConsoleMessages().Contains("display none element onload"));
+  EXPECT_TRUE(ConsoleMessages().Contains("visibility hidden element onload"));
+  EXPECT_TRUE(ConsoleMessages().Contains("tiny element onload"));
+  EXPECT_TRUE(ConsoleMessages().Contains("tiny width element onload"));
+  EXPECT_TRUE(ConsoleMessages().Contains("tiny height element onload"));
+  EXPECT_TRUE(ConsoleMessages().Contains("off screen left element onload"));
+  EXPECT_TRUE(ConsoleMessages().Contains("off screen top element onload"));
+
+  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);
+
+  // Scroll down to where the hidden frames are.
+  GetDocument().View()->LayoutViewport()->SetScrollOffset(
+      ScrollOffset(0, kViewportHeight + GetLoadingDistanceThreshold()),
+      mojom::blink::ScrollType::kProgrammatic);
+
+  // All of the frames on the page are hidden or tiny, so no visible load time
+  // samples should have been recorded for them.
+  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);
+
+  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+      LazyLoadFrameObserver::FrameInitialDeferralAction::kLoadedHidden, 7);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
+}
+
+TEST_P(LazyEmbedsTest, LoadHiddenFrameFarFromViewportWithLoadingAttributeLazy) {
+  SimRequest main_resource("https://example.com/", "text/html");
+  SimRequest tiny_frame_resource("https://crossorigin.com/tiny.html",
+                                 "text/html");
+
+  LoadURL("https://example.com/");
+
+  main_resource.Complete(String::Format(
+      R"HTML(
+        <head><style>
+          /* Chrome by default sets borders for iframes, so explicitly specify
+           * no borders, padding, or margins here so that the dimensions of the
+           * tiny frames aren't artificially inflated past the dimensions that
+           * the lazy loading logic considers "tiny". */
+          iframe { border-style: none; padding: 0px; margin: 0px; }
+        </style></head>
+        <body onload='console.log("main body onload");'>
+        <div style='height: %dpx'></div>
+        <iframe src='https://crossorigin.com/tiny.html'
+             loading='lazy'
+             style='width: 4px; height: 4px;'
+             onload='console.log("tiny element onload");'></iframe>
+        </body>
+      )HTML",
+      kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+  Compositor().BeginFrame();
+  test::RunPendingTasks();
+
+  // The body's load event should have already fired.
+  // Child frame loading will not be triggered.
+  EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+  EXPECT_FALSE(ConsoleMessages().Contains("tiny element onload"));
+
+  ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
+
+  // Scroll down to where the hidden frames are.
+  GetDocument().View()->LayoutViewport()->SetScrollOffset(
+      ScrollOffset(0, kViewportHeight + GetLoadingDistanceThreshold()),
+      mojom::blink::ScrollType::kProgrammatic);
+  Compositor().BeginFrame();
+  test::RunPendingTasks();
+
+  tiny_frame_resource.Complete("");
+  Compositor().BeginFrame();
+  test::RunPendingTasks();
+
+  EXPECT_TRUE(ConsoleMessages().Contains("tiny element onload"));
+  ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+      LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 1);
+  histogram_tester()->ExpectTotalCount(
+      "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 1);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    LazyEmbeds,
+    LazyEmbedsTest,
+    ::testing::Combine(
+        ::testing::Values(LazyFrameLoadingFeatureStatus::kEnabled),
+        ::testing::Values(LazyFrameVisibleLoadTimeFeatureStatus::kEnabled),
+        ::testing::Values(WebEffectiveConnectionType::kType4G)));
+
 class LazyLoadFramesTest : public SimTest {
  public:
   static constexpr int kViewportWidth = 800;
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.cc
index 71a6c0a1..bbfdea09 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.cc
@@ -34,16 +34,35 @@
 #include "third_party/blink/renderer/core/html/track/vtt/vtt_cue.h"
 #include "third_party/blink/renderer/core/layout/layout_object_factory.h"
 #include "third_party/blink/renderer/core/layout/layout_vtt_cue.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 
 namespace blink {
 
+namespace {
+
+class VttCueBoxResizeDelegate final : public ResizeObserver::Delegate {
+ public:
+  void OnResize(
+      const HeapVector<Member<ResizeObserverEntry>>& entries) override {
+    DCHECK_EQ(entries.size(), 1u);
+    // TODO(crbug.com/1335309): Do adjustment here.
+  }
+};
+
+}  // anonymous namespace
+
 VTTCueBox::VTTCueBox(Document& document)
     : HTMLDivElement(document),
       snap_to_lines_position_(std::numeric_limits<float>::quiet_NaN()) {
   SetShadowPseudoId(AtomicString("-webkit-media-text-track-display"));
 }
 
+void VTTCueBox::Trace(Visitor* visitor) const {
+  visitor->Trace(box_size_observer_);
+  HTMLDivElement::Trace(visitor);
+}
+
 void VTTCueBox::ApplyCSSProperties(
     const VTTDisplayParameters& display_parameters) {
   // http://dev.w3.org/html5/webvtt/#applying-css-properties-to-webvtt-node-objects
@@ -133,4 +152,25 @@
   return MakeGarbageCollected<LayoutVTTCue>(this, snap_to_lines_position_);
 }
 
+Node::InsertionNotificationRequest VTTCueBox::InsertedInto(
+    ContainerNode& insertion_point) {
+  if (RuntimeEnabledFeatures::LayoutNGVTTCueEnabled() &&
+      insertion_point.isConnected()) {
+    DCHECK(!box_size_observer_);
+    box_size_observer_ =
+        ResizeObserver::Create(GetDocument().domWindow(),
+                               MakeGarbageCollected<VttCueBoxResizeDelegate>());
+    box_size_observer_->observe(this);
+  }
+  return HTMLDivElement::InsertedInto(insertion_point);
+}
+
+void VTTCueBox::RemovedFrom(ContainerNode& insertion_point) {
+  HTMLDivElement::RemovedFrom(insertion_point);
+  if (!box_size_observer_)
+    return;
+  box_size_observer_->disconnect();
+  box_size_observer_.Clear();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.h b/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.h
index e9eb6ac..f4a2c8a 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.h
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue_box.h
@@ -43,12 +43,17 @@
 class VTTCueBox final : public HTMLDivElement {
  public:
   explicit VTTCueBox(Document&);
+  void Trace(Visitor* visitor) const override;
 
   void ApplyCSSProperties(const VTTDisplayParameters&);
 
  private:
   LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
+  InsertionNotificationRequest InsertedInto(
+      ContainerNode& insertion_point) override;
+  void RemovedFrom(ContainerNode& insertion_point) override;
 
+  Member<ResizeObserver> box_size_observer_;
   // The computed line position for snap-to-lines layout, and NaN for
   // non-snap-to-lines layout where no adjustment should take place.
   // This is set in applyCSSProperties and propagated to LayoutVTTCue.
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index dd2f789..f6fd9250 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -838,11 +838,9 @@
     // exists (https://crbug.com/705550).
     if (!same_item_sequence_number) {
       scoped_refptr<SerializedScriptValue> state_object =
-          history_item ? history_item->StateObject() : nullptr;
-      DCHECK(!state_object || type == WebFrameLoadType::kBackForward);
-      frame_->DomWindow()->StatePopped(
-          state_object ? std::move(state_object)
-                       : SerializedScriptValue::NullValue());
+          history_item ? history_item->StateObject()
+                       : SerializedScriptValue::NullValue();
+      frame_->DomWindow()->DispatchPopstateEvent(std::move(state_object));
     }
   }
 }
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
index 0daf5a8..b67d604 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -288,7 +288,7 @@
   ASSERT_TRUE(child_frame);
   LocalFrameView* child_frame_view = child_frame->View();
   ASSERT_TRUE(child_frame_view);
-  EXPECT_TRUE(child_frame_view->CanThrottleRendering());
+  EXPECT_FALSE(child_frame_view->CanThrottleRendering());
 }
 
 TEST_P(CompositingReasonFinderTest, PromoteCrossOriginIframe) {
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
index 66f8ec1..83363f3 100644
--- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
+++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
@@ -317,52 +317,68 @@
       exception_state.ThrowTypeError("first pending read's buffer is detached");
       return;
     }
-    //     c. Set firstPendingPullInto's buffer to ! TransferArrayBuffer(
+    //     c. Perform !
+    //     ReadableByteStreamControllerInvalidateBYOBRequest(controller).
+    InvalidateBYOBRequest(controller);
+    //     d. Set firstPendingPullInto's buffer to ! TransferArrayBuffer(
     //     firstPendingPullInto's buffer).
     first_pending_pull_into->buffer = TransferArrayBuffer(
         script_state, first_pending_pull_into->buffer, exception_state);
+    //     e. If firstPendingPullInto’s reader type is "none", perform ?
+    //     ReadableByteStreamControllerEnqueueDetachedPullIntoToQueue(controller,
+    //     firstPendingPullInto).
+    if (first_pending_pull_into->reader_type == ReaderType::kNone) {
+      EnqueueDetachedPullIntoToQueue(controller, first_pending_pull_into);
+    }
   }
 
-  // 9. Perform ! ReadableByteStreamControllerInvalidateBYOBRequest(controller).
-  InvalidateBYOBRequest(controller);
-
-  // 10. If ! ReadableStreamHasDefaultReader(stream) is true
+  // 9. If ! ReadableStreamHasDefaultReader(stream) is true
   if (ReadableStream::HasDefaultReader(stream)) {
-    //   a. If ! ReadableStreamGetNumReadRequests(stream) is 0,
+    //   a. Perform !
+    //   ReadableByteStreamControllerProcessReadRequestsUsingQueue(controller).
+    ProcessReadRequestsUsingQueue(script_state, controller);
+    //   b. If ! ReadableStreamGetNumReadRequests(stream) is 0,
     if (ReadableStream::GetNumReadRequests(stream) == 0) {
+      //     i. Assert: controller.[[pendingPullIntos]] is empty.
       DCHECK(controller->pending_pull_intos_.IsEmpty());
 
-      //     i. Perform !
+      //     ii. Perform !
       //     ReadableByteStreamControllerEnqueueChunkToQueue(controller,
       //     transferredBuffer, byteOffset, byteLength).
       EnqueueChunkToQueue(controller, transferred_buffer, byte_offset,
                           byte_length);
     } else {
-      // b. Otherwise,
+      // c. Otherwise,
       //     i. Assert: controller.[[queue]] is empty.
       DCHECK(controller->queue_.IsEmpty());
 
+      //     ii. If controller.[[pendingPullIntos]] is not empty,
       if (!controller->pending_pull_intos_.IsEmpty()) {
+        //        1. Assert: controller.[[pendingPullIntos]][0]'s reader type is
+        //        "default".
         DCHECK_EQ(controller->pending_pull_intos_[0]->reader_type,
                   ReaderType::kDefault);
+
+        //        2. Perform !
+        //        ReadableByteStreamControllerShiftPendingPullInto(controller).
         ShiftPendingPullInto(controller);
       }
 
-      //     ii. Let transferredView be ! Construct(%Uint8Array%, «
+      //     iii. Let transferredView be ! Construct(%Uint8Array%, «
       //     transferredBuffer, byteOffset, byteLength »).
       v8::Local<v8::Value> const transferred_view = v8::Uint8Array::New(
           ToV8Traits<DOMArrayBuffer>::ToV8(script_state, transferred_buffer)
               .ToLocalChecked()
               .As<v8::ArrayBuffer>(),
           byte_offset, byte_length);
-      //     iii. Perform ! ReadableStreamFulfillReadRequest(stream,
+      //     iv. Perform ! ReadableStreamFulfillReadRequest(stream,
       //     transferredView, false).
       ReadableStream::FulfillReadRequest(script_state, stream, transferred_view,
                                          false);
     }
   }
 
-  // 11. Otherwise, if ! ReadableStreamHasBYOBReader(stream) is true,
+  // 10. Otherwise, if ! ReadableStreamHasBYOBReader(stream) is true,
   else if (ReadableStream::HasBYOBReader(stream)) {
     //   a. Perform !
     //   ReadableByteStreamControllerEnqueueChunkToQueue(controller,
@@ -376,7 +392,7 @@
                                          exception_state);
     DCHECK(!exception_state.HadException());
   } else {
-    // 12. Otherwise,
+    // 11. Otherwise,
     //   a. Assert: ! IsReadableStreamLocked(stream) is false.
     DCHECK(!ReadableStream::IsLocked(stream));
     //   b. Perform !
@@ -386,7 +402,7 @@
                         byte_length);
   }
 
-  // 13. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller).
+  // 12. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller).
   CallPullIfNeeded(script_state, controller);
 }
 
@@ -406,6 +422,49 @@
   controller->queue_total_size_ += byte_length;
 }
 
+void ReadableByteStreamController::EnqueueClonedChunkToQueue(
+    ReadableByteStreamController* controller,
+    DOMArrayBuffer* buffer,
+    size_t byte_offset,
+    size_t byte_length) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerenqueueclonedchunktoqueue
+  // 1. Let cloneResult be CloneArrayBuffer(buffer, byteOffset, byteLength,
+  // %ArrayBuffer%).
+  DOMArrayBuffer* const clone_result = DOMArrayBuffer::Create(
+      static_cast<char*>(buffer->Data()) + byte_offset, byte_length);
+  // 2. If cloneResult is an abrupt completion,
+  //   a. Perform ! ReadableByteStreamControllerError(controller,
+  //   cloneResult.[[Value]]). b. Return cloneResult.
+  // This is not needed as DOMArrayBuffer::Create() is designed to crash if it
+  // cannot allocate the memory.
+
+  // 3. Perform ! ReadableByteStreamControllerEnqueueChunkToQueue(controller,
+  // cloneResult.[[Value]], 0, byteLength).
+  EnqueueChunkToQueue(controller, clone_result, 0, byte_length);
+}
+
+void ReadableByteStreamController::EnqueueDetachedPullIntoToQueue(
+    ReadableByteStreamController* controller,
+    PullIntoDescriptor* pull_into_descriptor) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerenqueuedetachedpullintotoqueue
+  // Note: EnqueueDetachedPullIntoToQueue cannot throw in this implementation.
+  // 1. Assert: pullIntoDescriptor’s reader type is "none".
+  DCHECK_EQ(pull_into_descriptor->reader_type, ReaderType::kNone);
+
+  // 2. If pullIntoDescriptor’s bytes filled > 0, perform ?
+  // ReadableByteStreamControllerEnqueueClonedChunkToQueue(controller,
+  // pullIntoDescriptor’s buffer, pullIntoDescriptor’s byte offset,
+  // pullIntoDescriptor’s bytes filled).
+  if (pull_into_descriptor->bytes_filled > 0) {
+    EnqueueClonedChunkToQueue(controller, pull_into_descriptor->buffer,
+                              pull_into_descriptor->byte_offset,
+                              pull_into_descriptor->bytes_filled);
+  }
+
+  // 3. Perform ! ReadableByteStreamControllerShiftPendingPullInto(controller).
+  ShiftPendingPullInto(controller);
+}
+
 void ReadableByteStreamController::ProcessPullIntoDescriptorsUsingQueue(
     ScriptState* script_state,
     ReadableByteStreamController* controller,
@@ -438,6 +497,34 @@
   }
 }
 
+void ReadableByteStreamController::ProcessReadRequestsUsingQueue(
+    ScriptState* script_state,
+    ReadableByteStreamController* controller) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerprocessreadrequestsusingqueue
+  // 1. Let reader be controller.[[stream]].[[reader]].
+  ReadableStreamGenericReader* reader =
+      controller->controlled_readable_stream_->reader_;
+  // 2. Assert: reader implements ReadableStreamDefaultReader.
+  DCHECK(reader->IsDefaultReader());
+  ReadableStreamDefaultReader* default_reader =
+      To<ReadableStreamDefaultReader>(reader);
+  // 3. While reader.[[readRequests]] is not empty,
+  while (!default_reader->read_requests_.IsEmpty()) {
+    //   a. If controller.[[queueTotalSize]] is 0, return.
+    if (controller->queue_total_size_ == 0) {
+      return;
+    }
+    //   b. Let readRequest be reader.[[readRequests]][0].
+    StreamPromiseResolver* read_request = default_reader->read_requests_[0];
+    //   c. Remove readRequest from reader.[[readRequests]].
+    default_reader->read_requests_.pop_front();
+    //   d. Perform !
+    //   ReadableByteStreamControllerFillReadRequestFromQueue(controller,
+    //   readRequest).
+    FillReadRequestFromQueue(script_state, controller, read_request);
+  }
+}
+
 void ReadableByteStreamController::CallPullIfNeeded(
     ScriptState* script_state,
     ReadableByteStreamController* controller) {
@@ -587,21 +674,23 @@
   // https://streams.spec.whatwg.org/#readable-byte-stream-controller-commit-pull-into-descriptor
   // 1. Assert: stream.[[state]] is not "errored".
   DCHECK_NE(stream->state_, ReadableStream::kErrored);
-  // 2. Let done be false.
+  // 2. Assert: pullIntoDescriptor.reader type is not "none".
+  DCHECK_NE(pull_into_descriptor->reader_type, ReaderType::kNone);
+  // 3. Let done be false.
   bool done = false;
-  // 3. If stream.[[state]] is "closed",
+  // 4. If stream.[[state]] is "closed",
   if (stream->state_ == ReadableStream::kClosed) {
     //   a. Assert: pullIntoDescriptor’s bytes filled is 0.
     DCHECK_EQ(pull_into_descriptor->bytes_filled, 0u);
     //   b. Set done to true.
     done = true;
   }
-  // 4. Let filledView be !
+  // 5. Let filledView be !
   // ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor).
   auto* filled_view = ConvertPullIntoDescriptor(
       script_state, pull_into_descriptor, exception_state);
   DCHECK(!exception_state.HadException());
-  // 5. If pullIntoDescriptor’s reader type is "default",
+  // 6. If pullIntoDescriptor’s reader type is "default",
   if (pull_into_descriptor->reader_type == ReaderType::kDefault) {
     //   a. Perform ! ReadableStreamFulfillReadRequest(stream, filledView,
     //   done).
@@ -611,7 +700,7 @@
             .ToLocalChecked(),
         done);
   } else {
-    // 6. Otherwise,
+    // 7. Otherwise,
     //   a. Assert: pullIntoDescriptor’s reader type is "byob".
     DCHECK_EQ(pull_into_descriptor->reader_type, ReaderType::kBYOB);
     //   b. Perform ! ReadableStreamFulfillReadIntoRequest(stream, filledView,
@@ -1007,6 +1096,40 @@
   return ready;
 }
 
+void ReadableByteStreamController::FillReadRequestFromQueue(
+    ScriptState* script_state,
+    ReadableByteStreamController* controller,
+    StreamPromiseResolver* read_request) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerfillreadrequestfromqueue
+  // 1. Assert: controller.[[queueTotalSize]] > 0.
+  DCHECK_GT(controller->queue_total_size_, 0);
+  // 2. Let entry be controller.[[queue]][0].
+  QueueEntry* entry = controller->queue_[0];
+  // 3. Remove entry from controller.[[queue]].
+  controller->queue_.pop_front();
+  // 4. Set controller.[[queueTotalSize]] to controller.[[queueTotalSize]] −
+  // entry’s byte length.
+  controller->queue_total_size_ -= entry->byte_length;
+  // 5. Perform ! ReadableByteStreamControllerHandleQueueDrain(controller).
+  HandleQueueDrain(script_state, controller);
+  // 6. Let view be ! Construct(%Uint8Array%, « entry’s buffer, entry’s byte
+  // offset, entry’s byte length »).
+  DOMUint8Array* view = DOMUint8Array::Create(entry->buffer, entry->byte_offset,
+                                              entry->byte_length);
+  // 7. Perform readRequest’s chunk steps, given view.
+  // TODO(nidhijaju): Implement https://github.com/whatwg/streams/pull/1045 to
+  // remove forAuthorCode and update implementation for readRequest's chunk
+  // steps.
+  ReadableStreamGenericReader* reader =
+      controller->controlled_readable_stream_->reader_;
+  read_request->Resolve(
+      script_state,
+      ReadableStream::CreateReadResult(
+          script_state,
+          ToV8Traits<DOMUint8Array>::ToV8(script_state, view).ToLocalChecked(),
+          false, To<ReadableStreamDefaultReader>(reader)->for_author_code_));
+}
+
 void ReadableByteStreamController::PullInto(
     ScriptState* script_state,
     ReadableByteStreamController* controller,
@@ -1238,9 +1361,14 @@
   // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-in-closed-state
   // 1. Assert: firstDescriptor’s bytes filled is 0.
   DCHECK_EQ(first_descriptor->bytes_filled, 0u);
-  // 2. Let stream be controller.[[stream]].
+  // 2. If firstDescriptor’s reader type is "none", perform !
+  // ReadableByteStreamControllerShiftPendingPullInto(controller).
+  if (first_descriptor->reader_type == ReaderType::kNone) {
+    ShiftPendingPullInto(controller);
+  }
+  // 3. Let stream be controller.[[stream]].
   ReadableStream* const stream = controller->controlled_readable_stream_;
-  // 3. If ! ReadableStreamHasBYOBReader(stream) is true,
+  // 4. If ! ReadableStreamHasBYOBReader(stream) is true,
   if (ReadableStream::HasBYOBReader(stream)) {
     //   a. While ! ReadableStreamGetNumReadIntoRequests(stream) > 0,
     while (ReadableStream::GetNumReadIntoRequests(stream) > 0) {
@@ -1273,18 +1401,31 @@
   // ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller,
   // bytesWritten, pullIntoDescriptor).
   FillHeadPullIntoDescriptor(controller, bytes_written, pull_into_descriptor);
-  // 3. If pullIntoDescriptor’s bytes filled < pullIntoDescriptor’s element
+  // 3. If pullIntoDescriptor’s reader type is "none",
+  if (pull_into_descriptor->reader_type == ReaderType::kNone) {
+    //   a. Perform ?
+    //   ReadableByteStreamControllerEnqueueDetachedPullIntoToQueue(controller,
+    //   pullIntoDescriptor).
+    EnqueueDetachedPullIntoToQueue(controller, pull_into_descriptor);
+    //   b. Perform !
+    //   ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller).
+    ProcessPullIntoDescriptorsUsingQueue(script_state, controller,
+                                         exception_state);
+    //   c. Return.
+    return;
+  }
+  // 4. If pullIntoDescriptor’s bytes filled < pullIntoDescriptor’s element
   // size, return.
   if (pull_into_descriptor->bytes_filled < pull_into_descriptor->element_size) {
     return;
   }
-  // 4. Perform ! ReadableByteStreamControllerShiftPendingPullInto(controller).
+  // 5. Perform ! ReadableByteStreamControllerShiftPendingPullInto(controller).
   ShiftPendingPullInto(controller);
-  // 5. Let remainderSize be pullIntoDescriptor’s bytes filled mod
+  // 6. Let remainderSize be pullIntoDescriptor’s bytes filled mod
   // pullIntoDescriptor’s element size.
   const size_t remainder_size =
       pull_into_descriptor->bytes_filled % pull_into_descriptor->element_size;
-  // 6. If remainderSize > 0,
+  // 7. If remainderSize > 0,
   if (remainder_size > 0) {
     //   a. Let end be pullIntoDescriptor’s byte offset + pullIntoDescriptor’s
     //   bytes filled.
@@ -1293,29 +1434,24 @@
     //   size_t.
     size_t end =
         pull_into_descriptor->byte_offset + pull_into_descriptor->bytes_filled;
-    //   b. Let remainder be ? CloneArrayBuffer(pullIntoDescriptor’s
-    //   buffer, end − remainderSize, remainderSize, %ArrayBuffer%).
-    DOMArrayBuffer* const remainder = DOMArrayBuffer::Create(
-        static_cast<char*>(pull_into_descriptor->buffer->Data()) + end -
-            remainder_size,
-        remainder_size);
-    //   c. Perform !
-    //   ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder,
-    //   0, remainder.[[ByteLength]]).
-    EnqueueChunkToQueue(controller, remainder, 0, remainder->ByteLength());
+    //   b. Perform ?
+    //   ReadableByteStreamControllerEnqueueClonedChunkToQueue(controller,
+    //   pullIntoDescriptor’s buffer, end − remainderSize, remainderSize).
+    EnqueueClonedChunkToQueue(controller, pull_into_descriptor->buffer,
+                              end - remainder_size, remainder_size);
   }
-  // 7. Set pullIntoDescriptor’s bytes filled to pullIntoDescriptor’s bytes
+  // 8. Set pullIntoDescriptor’s bytes filled to pullIntoDescriptor’s bytes
   // filled − remainderSize.
   pull_into_descriptor->bytes_filled =
       pull_into_descriptor->bytes_filled - remainder_size;
-  // 8. Perform !
+  // 9. Perform !
   // ReadableByteStreamControllerCommitPullIntoDescriptor(controller.[[stream]],
   // pullIntoDescriptor).
   CommitPullIntoDescriptor(script_state,
                            controller->controlled_readable_stream_,
                            pull_into_descriptor, exception_state);
   DCHECK(!exception_state.HadException());
-  // 9. Perform !
+  // 10. Perform !
   // ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller).
   ProcessPullIntoDescriptorsUsingQueue(script_state, controller,
                                        exception_state);
@@ -1490,7 +1626,7 @@
   // it needs to be updated to the new version on
   // https://streams.spec.whatwg.org when the ReadableStreamDefaultReader
   // implementation is updated.
-  // 1. Let stream be this.[[controlledReadableByteStream]].
+  // 1. Let stream be this.[[stream]].
   ReadableStream* const stream = controlled_readable_stream_;
   // 2. Assert: ! ReadableStreamHasDefaultReader(stream) is true.
   DCHECK(ReadableStream::HasDefaultReader(stream));
@@ -1557,4 +1693,18 @@
   return promise;
 }
 
+void ReadableByteStreamController::ReleaseSteps() {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontroller-releasesteps
+  // 1. If this.[[pendingPullIntos]] is not empty,
+  if (!pending_pull_intos_.IsEmpty()) {
+    //   a. Let firstPendingPullInto be this.[[pendingPullIntos]][0].
+    PullIntoDescriptor* first_pending_pull_into = pending_pull_intos_[0];
+    //   b. Set firstPendingPullInto’s reader type to "none".
+    first_pending_pull_into->reader_type = ReaderType::kNone;
+    //   c. Set this.[[pendingPullIntos]] to the list « firstPendingPullInto ».
+    pending_pull_intos_.clear();
+    pending_pull_intos_.push_back(first_pending_pull_into);
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
index 45ba7444..e43cb87 100644
--- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
+++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
@@ -78,7 +78,7 @@
     void Trace(Visitor*) const;
   };
 
-  enum class ReaderType { kDefault, kBYOB };
+  enum class ReaderType { kDefault, kBYOB, kNone };
 
   // https://streams.spec.whatwg.org/#pull-into-descriptor
   struct PullIntoDescriptor final
@@ -106,7 +106,7 @@
     size_t bytes_filled;
     const size_t element_size;
     const ViewConstructorType view_constructor;
-    const ReaderType reader_type;
+    ReaderType reader_type;
 
     void Trace(Visitor*) const;
   };
@@ -131,12 +131,26 @@
                                   size_t byte_offset,
                                   size_t byte_length);
 
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerenqueueclonedchunktoqueue
+  static void EnqueueClonedChunkToQueue(ReadableByteStreamController*,
+                                        DOMArrayBuffer*,
+                                        size_t byte_offset,
+                                        size_t byte_length);
+
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerenqueuedetachedpullintotoqueue
+  static void EnqueueDetachedPullIntoToQueue(ReadableByteStreamController*,
+                                             PullIntoDescriptor*);
+
   // https://streams.spec.whatwg.org/#readable-byte-stream-controller-process-pull-into-descriptors-using-queue
   static void ProcessPullIntoDescriptorsUsingQueue(
       ScriptState*,
       ReadableByteStreamController*,
       ExceptionState&);
 
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerprocessreadrequestsusingqueue
+  static void ProcessReadRequestsUsingQueue(ScriptState*,
+                                            ReadableByteStreamController*);
+
   // https://streams.spec.whatwg.org/#readable-byte-stream-controller-call-pull-if-needed
   static void CallPullIfNeeded(ScriptState*, ReadableByteStreamController*);
 
@@ -196,6 +210,11 @@
   static bool FillPullIntoDescriptorFromQueue(ReadableByteStreamController*,
                                               PullIntoDescriptor*);
 
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerfillreadrequestfromqueue
+  static void FillReadRequestFromQueue(ScriptState*,
+                                       ReadableByteStreamController*,
+                                       StreamPromiseResolver* read_request);
+
   // https://streams.spec.whatwg.org/#readable-byte-stream-controller-pull-into
   static void PullInto(ScriptState*,
                        ReadableByteStreamController*,
@@ -255,6 +274,9 @@
   // https://streams.spec.whatwg.org/#rbs-controller-private-pull
   StreamPromiseResolver* PullSteps(ScriptState*) override;
 
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontroller-releasesteps
+  void ReleaseSteps() override;
+
   // autoAllocateChunkSize is encoded as 0 when it is undefined
   size_t auto_allocate_chunk_size_ = 0u;
   Member<ReadableStreamBYOBRequest> byob_request_;
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc
index 860cedcf..091f561 100644
--- a/third_party/blink/renderer/core/streams/readable_stream.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -701,18 +701,31 @@
     // a. Perform ! WritableStreamDefaultWriterRelease(writer).
     WritableStreamDefaultWriter::Release(script_state_, writer_);
 
-    // b. Perform ! ReadableStreamReaderGenericRelease(reader).
-    ReadableStreamGenericReader::GenericRelease(script_state_, reader_);
+    // b. If reader implements ReadableStreamBYOBReader, perform !
+    // ReadableStreamBYOBReaderRelease(reader).
+    if (reader_->IsBYOBReader()) {
+      ReadableStreamGenericReader* reader = reader_;
+      ReadableStreamBYOBReader* byob_reader =
+          To<ReadableStreamBYOBReader>(reader);
+      ReadableStreamBYOBReader::Release(script_state_, byob_reader);
+    } else {
+      // c. Otherwise, perform ! ReadableStreamDefaultReaderRelease(reader).
+      DCHECK(reader_->IsDefaultReader());
+      ReadableStreamGenericReader* reader = reader_;
+      ReadableStreamDefaultReader* default_reader =
+          To<ReadableStreamDefaultReader>(reader);
+      ReadableStreamDefaultReader::Release(script_state_, default_reader);
+    }
 
     // TODO(ricea): Implement signal.
-    // c. If signal is not undefined, remove abortAlgorithm from signal.
+    // d. If signal is not undefined, remove abortAlgorithm from signal.
 
     v8::Local<v8::Value> error;
     if (error_maybe.ToLocal(&error)) {
-      // d. If error was given, reject promise with error.
+      // e. If error was given, reject promise with error.
       promise_->Reject(script_state_, error);
     } else {
-      // e. Otherwise, resolve promise with undefined.
+      // f. Otherwise, resolve promise with undefined.
       promise_->ResolveWithUndefined(script_state_);
     }
   }
@@ -1907,20 +1920,26 @@
   // 6. If reader is not undefined and reader implements
   // ReadableStreamBYOBReader,
   if (reader && reader->IsBYOBReader()) {
-    //   a. For each readIntoRequest of reader.[[readIntoRequests]],
+    //   a. Let readIntoRequests be reader.[[readIntoRequests]].
     ReadableStreamBYOBReader* byob_reader =
         To<ReadableStreamBYOBReader>(reader);
+    HeapDeque<Member<ReadableStreamBYOBReader::ReadIntoRequest>>
+        read_into_requests;
+    read_into_requests.Swap(byob_reader->read_into_requests_);
+
+    //   b. Set reader.[[readIntoRequests]] to an empty list.
+    //      This is not required since we've already called Swap().
+
+    //   c. For each readIntoRequest of readIntoRequests,
     for (ReadableStreamBYOBReader::ReadIntoRequest* request :
-         byob_reader->read_into_requests_) {
+         read_into_requests) {
       //     i. Perform readIntoRequest's close steps, given undefined.
       request->CloseSteps(script_state, nullptr);
     }
-    //   b. Set reader.[[readIntoRequests]] to an empty list.
-    byob_reader->read_into_requests_.clear();
   }
 
-  // 7. Let sourceCancelPromise be ! stream.[[readableStreamController]].
-  //    [[CancelSteps]](reason).
+  // 7. Let sourceCancelPromise be !
+  // stream.[[controller]].[[CancelSteps]](reason).
   v8::Local<v8::Promise> source_cancel_promise =
       stream->readable_stream_controller_->CancelSteps(script_state, reason);
 
@@ -1934,8 +1953,8 @@
                        v8::Local<v8::Value>) override {}
   };
 
-  // 8. Return the result of transforming sourceCancelPromise with a
-  //    fulfillment handler that returns undefined.
+  // 8. Return the result of reacting to sourceCancelPromise with a
+  //    fulfillment step that returns undefined.
   return StreamThenPromise(
       script_state->GetContext(), source_cancel_promise,
       MakeGarbageCollected<ScriptFunction>(
@@ -1962,16 +1981,23 @@
   if (ExecutionContext::From(script_state)->IsContextDestroyed())
     return;
 
-  // 5. If ! IsReadableStreamDefaultReader(reader) is true,
+  // 5. Resolve reader.[[closedPromise]] with undefined.
+  reader->closed_promise_->ResolveWithUndefined(script_state);
+
+  // 6. If reader implements ReadableStreamDefaultReader,
   if (reader->IsDefaultReader()) {
-    //   a. Repeat for each readRequest that is an element of reader.
-    //      [[readRequests]],
+    //   a. Let readRequests be reader.[[readRequests]].
     HeapDeque<Member<StreamPromiseResolver>> requests;
     requests.Swap(To<ReadableStreamDefaultReader>(reader)->read_requests_);
     bool for_author_code =
         To<ReadableStreamDefaultReader>(reader)->for_author_code_;
+    //   b. Set reader.[[readRequests]] to an empty list.`
+    //      This is not required since we've already called Swap()
+
+    //   c. Repeat for each readRequest that is an element of reader.
+    //      [[readRequests]],
     for (StreamPromiseResolver* promise : requests) {
-      //   i. Resolve readRequest.[[promise]] with !
+      //      i. Resolve readRequest.[[promise]] with !
       //      ReadableStreamCreateReadResult(undefined, true, reader.
       //      [[forAuthorCode]]).
       promise->Resolve(
@@ -1980,12 +2006,7 @@
                            v8::Undefined(script_state->GetIsolate()), true,
                            for_author_code));
     }
-
-    //   b. Set reader.[[readRequests]] to an empty List.
-    //      This is not required since we've already called Swap().
   }
-  // 6. Resolve reader.[[closedPromise]] with undefined.
-  reader->closed_promise_->ResolveWithUndefined(script_state);
 }
 
 v8::Local<v8::Value> ReadableStream::CreateReadResult(
@@ -2056,42 +2077,29 @@
     return;
   }
 
-  // 6. If ! IsReadableStreamDefaultReader(reader) is true,
-  //   a. Repeat for each readRequest that is an element of reader.
-  //      [[readRequests]],
-  if (reader->IsDefaultReader()) {
-    ReadableStreamDefaultReader* default_reader =
-        To<ReadableStreamDefaultReader>(reader);
-    for (StreamPromiseResolver* promise : default_reader->read_requests_) {
-      //   i. Reject readRequest.[[promise]] with e.
-      promise->Reject(script_state, e);
-    }
-
-    //   b. Set reader.[[readRequests]] to a new empty List.
-    default_reader->read_requests_.clear();
-  }
-
-  // 7. Otherwise,
-  else {
-    // a. Assert: reader implements ReadableStreamBYOBReader.
-    DCHECK(reader->IsBYOBReader());
-    // b. For each readIntoRequest of reader.[[readIntoRequests]],
-    ReadableStreamBYOBReader* byob_reader =
-        To<ReadableStreamBYOBReader>(reader);
-    for (ReadableStreamBYOBReader::ReadIntoRequest* request :
-         byob_reader->read_into_requests_) {
-      // i. Perform readIntoRequests' error steps, given e.
-      request->ErrorSteps(script_state, e);
-    }
-    // c. Set reader.[[readIntoRequests]] to a new empty list.
-    byob_reader->read_into_requests_.clear();
-  }
-
-  // 8. Reject reader.[[closedPromise]] with e.
+  // 6. Reject reader.[[closedPromise]] with e.
   reader->closed_promise_->Reject(script_state, e);
 
-  // 9. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
+  // 7. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
   reader->closed_promise_->MarkAsHandled(isolate);
+
+  // 8. If reader implements ReadableStreamDefaultReader,
+  if (reader->IsDefaultReader()) {
+    //   a. Perform ! ReadableStreamDefaultReaderErrorReadRequests(reader, e).
+    ReadableStreamDefaultReader* default_reader =
+        To<ReadableStreamDefaultReader>(reader);
+    ReadableStreamDefaultReader::ErrorReadRequests(script_state, default_reader,
+                                                   e);
+  } else {
+    // 9. Otherwise,
+    // a. Assert: reader implements ReadableStreamBYOBReader.
+    DCHECK(reader->IsBYOBReader());
+    // b. Perform ! ReadableStreamBYOBReaderErrorReadIntoRequests(reader, e).
+    ReadableStreamBYOBReader* byob_reader =
+        To<ReadableStreamBYOBReader>(reader);
+    ReadableStreamBYOBReader::ErrorReadIntoRequests(script_state, byob_reader,
+                                                    e);
+  }
 }
 
 void ReadableStream::FulfillReadIntoRequest(ScriptState* script_state,
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc
index adb701b..692814c 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/bindings/to_v8.h"
 #include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 
 namespace blink {
 
@@ -166,6 +167,36 @@
   }
 }
 
+void ReadableStreamBYOBReader::ErrorReadIntoRequests(
+    ScriptState* script_state,
+    ReadableStreamBYOBReader* reader,
+    v8::Local<v8::Value> e) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreambyobreadererrorreadintorequests
+  // 1. Let readIntoRequests be reader.[[readIntoRequests]].
+  // 2. Set reader.[[readIntoRequests]] to a new empty list.
+  // 3. For each readIntoRequest of readIntoRequests,
+  for (ReadableStreamBYOBReader::ReadIntoRequest* request :
+       reader->read_into_requests_) {
+    //   a. Perform readIntoRequest’s error steps, given e.
+    request->ErrorSteps(script_state, e);
+  }
+  reader->read_into_requests_.clear();
+}
+
+void ReadableStreamBYOBReader::Release(ScriptState* script_state,
+                                       ReadableStreamBYOBReader* reader) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreambyobreaderrelease
+  // 1. Perform ! ReadableStreamReaderGenericRelease(reader).
+  ReadableStreamGenericReader::GenericRelease(script_state, reader);
+
+  // 2. Let e be a new TypeError exception.
+  v8::Local<v8::Value> e = V8ThrowException::CreateTypeError(
+      script_state->GetIsolate(), "Releasing BYOB reader");
+
+  // 3. Perform ! ReadableStreamBYOBReaderErrorReadIntoRequests(reader, e).
+  ErrorReadIntoRequests(script_state, reader, e);
+}
+
 void ReadableStreamBYOBReader::releaseLock(ScriptState* script_state,
                                            ExceptionState& exception_state) {
   // https://streams.spec.whatwg.org/#byob-reader-release-lock
@@ -174,16 +205,8 @@
     return;
   }
 
-  // 2. If this.[[readIntoRequests]] is not empty, throw a TypeError exception.
-  if (read_into_requests_.size() > 0) {
-    exception_state.ThrowTypeError(
-        "Cannot release a readable stream reader when it still has outstanding "
-        "read() calls that have not yet settled");
-    return;
-  }
-
-  // 3. Perform ! ReadableStreamReaderGenericRelease(this).
-  GenericRelease(script_state, this);
+  // 2. Perform ! ReadableStreamBYOBReaderRelease(this).
+  Release(script_state, this);
 }
 
 void ReadableStreamBYOBReader::SetUpBYOBReader(
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h
index 11a5b63..a8a1641e 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h
+++ b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h
@@ -77,6 +77,10 @@
     Member<StreamPromiseResolver> resolver_;
   };
 
+  //
+  // Readable stream reader abstract operations
+  //
+
   // https://streams.spec.whatwg.org/#readable-stream-byob-reader-read
   static void Read(ScriptState*,
                    ReadableStreamBYOBReader*,
@@ -84,6 +88,14 @@
                    ReadIntoRequest*,
                    ExceptionState&);
 
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreambyobreadererrorreadintorequests
+  static void ErrorReadIntoRequests(ScriptState*,
+                                    ReadableStreamBYOBReader*,
+                                    v8::Local<v8::Value> e);
+
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreambyobreaderrelease
+  static void Release(ScriptState*, ReadableStreamBYOBReader*);
+
   HeapDeque<Member<ReadIntoRequest>> read_into_requests_;
 };
 
diff --git a/third_party/blink/renderer/core/streams/readable_stream_controller.h b/third_party/blink/renderer/core/streams/readable_stream_controller.h
index 8ea66c0..1a2857d 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_controller.h
+++ b/third_party/blink/renderer/core/streams/readable_stream_controller.h
@@ -24,6 +24,9 @@
 
   // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamcontroller-pullsteps
   virtual StreamPromiseResolver* PullSteps(ScriptState*) = 0;
+
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamcontroller-releasesteps
+  virtual void ReleaseSteps() = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc b/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
index 2365ac4..478879d71 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller.cc
@@ -334,6 +334,12 @@
   return pendingPromise;
 }
 
+void ReadableStreamDefaultController::ReleaseSteps() {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultcontroller-releasesteps
+  // 1. Return.
+  return;
+}
+
 //
 // Readable Stream Default Controller Abstract Operations
 //
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller.h b/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
index 406121d..cd9356f 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
+++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
@@ -84,6 +84,9 @@
   // https://streams.spec.whatwg.org/#rs-default-controller-private-pull
   StreamPromiseResolver* PullSteps(ScriptState*) override;
 
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultcontroller-releasesteps
+  void ReleaseSteps() override;
+
  private:
   friend class ReadableStream;
   friend class ReadableStreamDefaultReader;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_reader.cc b/third_party/blink/renderer/core/streams/readable_stream_default_reader.cc
index 089b616..b91fe5b 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_default_reader.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream_default_reader.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/streams/stream_promise_resolver.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 
 namespace blink {
 
@@ -94,24 +95,45 @@
   }
 }
 
+void ReadableStreamDefaultReader::ErrorReadRequests(
+    ScriptState* script_state,
+    ReadableStreamDefaultReader* reader,
+    v8::Local<v8::Value> e) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultreadererrorreadrequests
+  // 1. Let readRequests be reader.[[readRequests]].
+  // 2. Set reader.[[readRequests]] to a new empty list.
+  // 3. For each readRequest of readRequests,
+  for (StreamPromiseResolver* promise : reader->read_requests_) {
+    //   a. Perform readRequest’s error steps, given e.
+    promise->Reject(script_state, e);
+  }
+  reader->read_requests_.clear();
+}
+
+void ReadableStreamDefaultReader::Release(ScriptState* script_state,
+                                          ReadableStreamDefaultReader* reader) {
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultreaderrelease
+  // 1. Perform ! ReadableStreamReaderGenericRelease(reader).
+  ReadableStreamGenericReader::GenericRelease(script_state, reader);
+
+  // 2. Let e be a new TypeError exception.
+  v8::Local<v8::Value> e = V8ThrowException::CreateTypeError(
+      script_state->GetIsolate(), "Releasing Default reader");
+
+  // 3. Perform ! ReadableStreamDefaultReaderErrorReadRequests(reader, e).
+  ErrorReadRequests(script_state, reader, e);
+}
+
 void ReadableStreamDefaultReader::releaseLock(ScriptState* script_state,
                                               ExceptionState& exception_state) {
   // https://streams.spec.whatwg.org/#default-reader-release-lock
-  // 2. If this.[[ownerReadableStream]] is undefined, return.
+  // 1. If this.[[stream]] is undefined, return.
   if (!owner_readable_stream_) {
     return;
   }
 
-  // 3. If this.[[readRequests]] is not empty, throw a TypeError exception.
-  if (read_requests_.size() > 0) {
-    exception_state.ThrowTypeError(
-        "Cannot release a readable stream reader when it still has outstanding "
-        "read() calls that have not yet settled");
-    return;
-  }
-
-  // 4. Perform ! ReadableStreamReaderGenericRelease(this).
-  GenericRelease(script_state, this);
+  // 2. Perform ! ReadableStreamDefaultReaderRelease(this).
+  Release(script_state, this);
 }
 
 void ReadableStreamDefaultReader::SetUpDefaultReader(
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_reader.h b/third_party/blink/renderer/core/streams/readable_stream_default_reader.h
index 5ab9f59..2ca4301 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_default_reader.h
+++ b/third_party/blink/renderer/core/streams/readable_stream_default_reader.h
@@ -60,6 +60,14 @@
   static StreamPromiseResolver* Read(ScriptState*,
                                      ReadableStreamDefaultReader* reader);
 
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultreadererrorreadrequests
+  static void ErrorReadRequests(ScriptState*,
+                                ReadableStreamDefaultReader* reader,
+                                v8::Local<v8::Value> e);
+
+  // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultreaderrelease
+  static void Release(ScriptState*, ReadableStreamDefaultReader* reader);
+
   void Trace(Visitor*) const override;
 
   bool HasPendingActivity() const final;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc
index 131320c22..20bed9d 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.cc
@@ -59,17 +59,20 @@
     ScriptState* script_state,
     ReadableStreamGenericReader* reader) {
   // https://streams.spec.whatwg.org/#readable-stream-reader-generic-release
-  // 1. Assert: reader.[[ownerReadableStream]] is not undefined.
-  DCHECK(reader->owner_readable_stream_);
+  // 1. Let stream be reader.[[stream]].
+  ReadableStream* stream = reader->owner_readable_stream_;
 
-  // 2. Assert: reader.[[ownerReadableStream]].[[reader]] is reader.
-  DCHECK_EQ(reader->owner_readable_stream_->reader_, reader);
+  // 2. Assert: stream is not undefined.
+  DCHECK(stream);
+
+  // 3. Assert: stream.[[reader]] is reader.
+  DCHECK_EQ(stream->reader_, reader);
 
   auto* isolate = script_state->GetIsolate();
 
-  // 3. If reader.[[ownerReadableStream]].[[state]] is "readable", reject
-  //    reader.[[closedPromise]] with a TypeError exception.
-  if (reader->owner_readable_stream_->state_ == ReadableStream::kReadable) {
+  // 4. If stream.[[state]] is "readable", reject reader.[[closedPromise]] with
+  // a TypeError exception.
+  if (stream->state_ == ReadableStream::kReadable) {
     reader->closed_promise_->MarkAsSilent(isolate);
     reader->closed_promise_->Reject(
         script_state,
@@ -78,8 +81,8 @@
             "This readable stream reader has been released and cannot be used "
             "to monitor the stream's state")));
   } else {
-    // 4. Otherwise, set reader.[[closedPromise]] to a promise rejected with a
-    //    TypeError exception.
+    // 5. Otherwise, set reader.[[closedPromise]] to a promise rejected with a
+    // TypeError exception.
     reader->closed_promise_ = StreamPromiseResolver::CreateRejectedAndSilent(
         script_state, v8::Exception::TypeError(V8String(
                           isolate,
@@ -87,13 +90,16 @@
                           "cannot be used to monitor the stream's state")));
   }
 
-  // 5. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
+  // 6. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
   reader->closed_promise_->MarkAsHandled(isolate);
 
-  // 6. Set reader.[[ownerReadableStream]].[[reader]] to undefined.
-  reader->owner_readable_stream_->reader_ = nullptr;
+  // 7. Perform ! stream.[[controller]].[[ReleaseSteps]]().
+  stream->readable_stream_controller_->ReleaseSteps();
 
-  // 7. Set reader.[[ownerReadableStream]] to undefined.
+  // 8. Set stream.[[reader]] to undefined.
+  stream->reader_ = nullptr;
+
+  // 9. Set reader.[[stream]] to undefined.
   reader->owner_readable_stream_ = nullptr;
 }
 
diff --git a/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.cc b/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.cc
index a5edd91..866e44c 100644
--- a/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.cc
+++ b/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_statics.h"
+#include "third_party/skia/include/core/SkColorSpace.h"
 #include "ui/display/screen_info.h"
 #include "ui/display/screen_infos.h"
 
@@ -47,6 +48,49 @@
   if (prev.label != current.label)
     return false;
 
+  if (RuntimeEnabledFeatures::CanvasHDREnabled()) {
+    // highDynamicRangeHeadroom()
+    if (prev.display_color_spaces.GetHDRMaxLuminanceRelative() !=
+        current.display_color_spaces.GetHDRMaxLuminanceRelative()) {
+      return false;
+    }
+
+    const auto prev_primaries = prev.display_color_spaces.GetPrimaries();
+    const auto curr_primaries = current.display_color_spaces.GetPrimaries();
+
+    // redPrimaryX()
+    if (prev_primaries.fRX != curr_primaries.fRX)
+      return false;
+
+    // redPrimaryY()
+    if (prev_primaries.fRY != curr_primaries.fRY)
+      return false;
+
+    // greenPrimaryX()
+    if (prev_primaries.fGX != curr_primaries.fGX)
+      return false;
+
+    // greenPrimaryY()
+    if (prev_primaries.fGY != curr_primaries.fGY)
+      return false;
+
+    // bluePrimaryX()
+    if (prev_primaries.fBX != curr_primaries.fBX)
+      return false;
+
+    // bluePrimaryY()
+    if (prev_primaries.fBY != curr_primaries.fBY)
+      return false;
+
+    // whitePointX()
+    if (prev_primaries.fWX != curr_primaries.fWX)
+      return false;
+
+    // whitePointY()
+    if (prev_primaries.fWY != curr_primaries.fWY)
+      return false;
+  }
+
   // Note: devicePixelRatio() covered by Screen base function
 
   return true;
@@ -109,4 +153,40 @@
   return String(prefix) + String::Number(label_idx_);
 }
 
+float ScreenDetailed::highDynamicRangeHeadroom() const {
+  return GetScreenInfo().display_color_spaces.GetHDRMaxLuminanceRelative();
+}
+
+float ScreenDetailed::redPrimaryX() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fRX;
+}
+
+float ScreenDetailed::redPrimaryY() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fRY;
+}
+
+float ScreenDetailed::greenPrimaryX() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fGX;
+}
+
+float ScreenDetailed::greenPrimaryY() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fGY;
+}
+
+float ScreenDetailed::bluePrimaryX() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fBX;
+}
+
+float ScreenDetailed::bluePrimaryY() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fBY;
+}
+
+float ScreenDetailed::whitePointX() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fWX;
+}
+
+float ScreenDetailed::whitePointY() const {
+  return GetScreenInfo().display_color_spaces.GetPrimaries().fWY;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.h b/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.h
index 25c0834..6330bdfe 100644
--- a/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.h
+++ b/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.h
@@ -36,6 +36,18 @@
   float devicePixelRatio() const;
   String label() const;
 
+  // Attributes exposed for HDR canvas.
+  // https://github.com/w3c/ColorWeb-CG/blob/master/hdr_html_canvas_element.md
+  float highDynamicRangeHeadroom() const;
+  float redPrimaryX() const;
+  float redPrimaryY() const;
+  float greenPrimaryX() const;
+  float greenPrimaryY() const;
+  float bluePrimaryX() const;
+  float bluePrimaryY() const;
+  float whitePointX() const;
+  float whitePointY() const;
+
   uint32_t label_idx() const { return label_idx_; }
   bool label_is_internal() const { return label_is_internal_; }
 
diff --git a/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.idl b/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.idl
index babd1cb..926f5a7 100644
--- a/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.idl
+++ b/third_party/blink/renderer/modules/screen_enumeration/screen_detailed.idl
@@ -30,4 +30,23 @@
 
   // A user-friendly label for the screen, determined by the user agent and OS.
   [HighEntropy=Direct, Measure] readonly attribute DOMString label;
+
+  // The maximum luminance that the screen is capable of displaying across
+  // the full area of the screen, as a multiple of the luminance of SDR white.
+  // This will have a value of 1.0 for screens that are not HDR capable.
+  // https://github.com/w3c/ColorWeb-CG/blob/master/hdr_html_canvas_element.md
+  [RuntimeEnabled=CanvasHDR] readonly attribute float highDynamicRangeHeadroom;
+
+  // The color primaries and white point of the screen, in CIE 1931 xy
+  // coordinates. These define the color gamut that the screen is capable of
+  // displaying.
+  // https://github.com/w3c/ColorWeb-CG/blob/master/hdr_html_canvas_element.md
+  [RuntimeEnabled=CanvasHDR] readonly attribute float redPrimaryX;
+  [RuntimeEnabled=CanvasHDR] readonly attribute float redPrimaryY;
+  [RuntimeEnabled=CanvasHDR] readonly attribute float greenPrimaryX;
+  [RuntimeEnabled=CanvasHDR] readonly attribute float greenPrimaryY;
+  [RuntimeEnabled=CanvasHDR] readonly attribute float bluePrimaryX;
+  [RuntimeEnabled=CanvasHDR] readonly attribute float bluePrimaryY;
+  [RuntimeEnabled=CanvasHDR] readonly attribute float whitePointX;
+  [RuntimeEnabled=CanvasHDR] readonly attribute float whitePointY;
 };
diff --git a/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc b/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc
index ceb6f0d..58e4ce1 100644
--- a/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc
+++ b/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc
@@ -55,7 +55,20 @@
 void OESVertexArrayObject::deleteVertexArrayOES(
     WebGLVertexArrayObjectOES* array_object) {
   WebGLExtensionScopedContext scoped(this);
-  if (!array_object || scoped.IsLost())
+  if (scoped.IsLost() || !array_object)
+    return;
+
+  // ValidateWebGLObject generates an error if the object has already been
+  // deleted, so we must replicate most of its checks here.
+  if (!array_object->Validate(scoped.Context()->ContextGroup(),
+                              scoped.Context())) {
+    scoped.Context()->SynthesizeGLError(
+        GL_INVALID_OPERATION, "deleteVertexArrayOES",
+        "object does not belong to this context");
+    return;
+  }
+
+  if (array_object->MarkedForDeletion())
     return;
 
   if (!array_object->IsDefaultObject() &&
@@ -68,7 +81,9 @@
 GLboolean OESVertexArrayObject::isVertexArrayOES(
     WebGLVertexArrayObjectOES* array_object) {
   WebGLExtensionScopedContext scoped(this);
-  if (!array_object || scoped.IsLost())
+  if (scoped.IsLost() || !array_object ||
+      !array_object->Validate(scoped.Context()->ContextGroup(),
+                              scoped.Context()))
     return 0;
 
   if (!array_object->HasEverBeenBound())
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index d085fa33..01c287df 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -1741,8 +1741,6 @@
 
     camera_image_size_ = absl::nullopt;
     if (frame_data->camera_image_size.has_value()) {
-      DCHECK(frame_data->camera_image_buffer_holder.has_value());
-
       // Let's store the camera image size. The texture ID will be filled out on
       // the XRWebGLLayer by the session once the frame starts
       // (in XRSession::OnFrame()).
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
index cb0e3fe3..a94d850 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -413,7 +413,10 @@
       // Always call submit, but notify if the contents were changed or not.
       session()->xr()->frameProvider()->SubmitWebGLLayer(this,
                                                          framebuffer_dirty);
-      if (camera_image_mailbox_holder_ && camera_image_texture_id_) {
+      if (camera_image_texture_id_) {
+        // We shouldn't ever have a camera texture if the holder wasn't present:
+        DCHECK(camera_image_mailbox_holder_);
+
         DVLOG(3) << __func__
                  << ": deleting camera image texture, camera_image_texture_id_="
                  << camera_image_texture_id_;
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 5dafe4f..30df459 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -2459,7 +2459,10 @@
     ":blink_fuzzer_test_support",
     ":platform",
   ]
-  seed_corpus = "//third_party/blink/web_tests/external/wpt/fonts/math"
+  seed_corpuses = [
+    "//third_party/blink/web_tests/external/wpt/fonts/math",
+    "//testing/libfuzzer/fuzzers/woff2_corpus",
+  ]
 }
 
 # Fuzzer for blink::StretchyOperatorShaper
@@ -2469,7 +2472,10 @@
     ":blink_fuzzer_test_support",
     ":platform",
   ]
-  seed_corpus = "//third_party/blink/web_tests/external/wpt/fonts/math"
+  seed_corpuses = [
+    "//third_party/blink/web_tests/external/wpt/fonts/math",
+    "//testing/libfuzzer/fuzzers/woff2_corpus",
+  ]
 }
 
 # Fuzzer for blink::MHTMLParser.
diff --git a/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc b/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
index 41f12d65..2e331f1 100644
--- a/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
+++ b/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
@@ -181,6 +181,25 @@
   }
 }
 
+bool CalculationExpressionOperationNode::ComputeHasAnchorQueries() const {
+  for (const auto& child : children_) {
+    if (child->HasAnchorQueries())
+      return true;
+  }
+  return false;
+}
+
+CalculationExpressionOperationNode::CalculationExpressionOperationNode(
+    Children&& children,
+    CalculationOperator op)
+    : children_(std::move(children)), operator_(op) {
+#if DCHECK_IS_ON()
+  result_type_ = ResolvedResultType();
+  DCHECK_NE(result_type_, ResultType::kInvalid);
+#endif
+  has_anchor_queries_ = ComputeHasAnchorQueries();
+}
+
 float CalculationExpressionOperationNode::Evaluate(
     float max_value,
     const Length::AnchorEvaluator* anchor_evaluator) const {
diff --git a/third_party/blink/renderer/platform/geometry/calculation_expression_node.h b/third_party/blink/renderer/platform/geometry/calculation_expression_node.h
index 85e697c..a53a3b63b 100644
--- a/third_party/blink/renderer/platform/geometry/calculation_expression_node.h
+++ b/third_party/blink/renderer/platform/geometry/calculation_expression_node.h
@@ -38,6 +38,8 @@
     return !operator==(other);
   }
 
+  bool HasAnchorQueries() const { return has_anchor_queries_; }
+
   virtual bool IsNumber() const { return false; }
   virtual bool IsPixelsAndPercent() const { return false; }
   virtual bool IsOperation() const { return false; }
@@ -56,6 +58,9 @@
  protected:
   ResultType result_type_;
 #endif
+
+ protected:
+  bool has_anchor_queries_ = false;
 };
 
 class PLATFORM_EXPORT CalculationExpressionNumberNode final
@@ -138,13 +143,8 @@
       Children&& children,
       CalculationOperator op);
 
-  CalculationExpressionOperationNode(Children&& children, CalculationOperator op)
-      : children_(std::move(children)), operator_(op) {
-#if DCHECK_IS_ON()
-    result_type_ = ResolvedResultType();
-    DCHECK_NE(result_type_, ResultType::kInvalid);
-#endif
-  }
+  CalculationExpressionOperationNode(Children&& children,
+                                     CalculationOperator op);
 
   const Children& GetChildren() const { return children_; }
   CalculationOperator GetOperator() const { return operator_; }
@@ -162,6 +162,8 @@
 #endif
 
  private:
+  bool ComputeHasAnchorQueries() const;
+
   Children children_;
   CalculationOperator operator_;
 };
@@ -234,7 +236,9 @@
         anchor_name_(anchor_name),
         value_(value),
         side_percentage_(side_percentage),
-        fallback_(fallback) {}
+        fallback_(fallback) {
+    has_anchor_queries_ = true;
+  }
 
  private:
   AnchorQueryType type_;
diff --git a/third_party/blink/renderer/platform/geometry/calculation_value.cc b/third_party/blink/renderer/platform/geometry/calculation_value.cc
index b6c96f3f..e32cfe8 100644
--- a/third_party/blink/renderer/platform/geometry/calculation_value.cc
+++ b/third_party/blink/renderer/platform/geometry/calculation_value.cc
@@ -125,4 +125,8 @@
   return CreateSimplified(data_.expression->Zoom(factor), GetValueRange());
 }
 
+bool CalculationValue::HasAnchorQueries() const {
+  return IsExpression() && data_.expression->HasAnchorQueries();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/geometry/calculation_value.h b/third_party/blink/renderer/platform/geometry/calculation_value.h
index 69e4201..2c10811e7 100644
--- a/third_party/blink/renderer/platform/geometry/calculation_value.h
+++ b/third_party/blink/renderer/platform/geometry/calculation_value.h
@@ -68,6 +68,7 @@
     return is_non_negative_ ? Length::ValueRange::kNonNegative
                             : Length::ValueRange::kAll;
   }
+  bool HasAnchorQueries() const;
 
   float Pixels() const {
     DCHECK(!IsExpression());
diff --git a/third_party/blink/renderer/platform/geometry/length.cc b/third_party/blink/renderer/platform/geometry/length.cc
index 07d614b..5682b89 100644
--- a/third_party/blink/renderer/platform/geometry/length.cc
+++ b/third_party/blink/renderer/platform/geometry/length.cc
@@ -205,6 +205,10 @@
   return absl::nullopt;
 }
 
+bool Length::HasAnchorQueries() const {
+  return IsCalculated() && GetCalculationValue().HasAnchorQueries();
+}
+
 String Length::ToString() const {
   StringBuilder builder;
   builder.Append("Length(");
diff --git a/third_party/blink/renderer/platform/geometry/length.h b/third_party/blink/renderer/platform/geometry/length.h
index 03fc5040..21064a6 100644
--- a/third_party/blink/renderer/platform/geometry/length.h
+++ b/third_party/blink/renderer/platform/geometry/length.h
@@ -274,6 +274,7 @@
   bool IsExtendToZoom() const { return GetType() == kExtendToZoom; }
   bool IsDeviceWidth() const { return GetType() == kDeviceWidth; }
   bool IsDeviceHeight() const { return GetType() == kDeviceHeight; }
+  bool HasAnchorQueries() const;
 
   Length Blend(const Length& from, double progress, ValueRange range) const {
     DCHECK(IsSpecified());
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index c1c6e22..36066d6 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1163,7 +1163,7 @@
     },
     {
       name: "FormRelAttribute",
-      status: "stable",
+      status: "experimental",
     },
     {
       name: "FractionalScrollOffsets",
diff --git a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
index 5d8ef2a..1de3152 100644
--- a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
+++ b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
@@ -421,7 +421,7 @@
 // static
 void Partitions::HandleOutOfMemory(size_t size) {
   volatile size_t total_usage = TotalSizeOfCommittedPages();
-  uint32_t alloc_page_error_code = base::GetAllocPageErrorCode();
+  uint32_t alloc_page_error_code = partition_alloc::GetAllocPageErrorCode();
   base::debug::Alias(&alloc_page_error_code);
 
   // Report the total mapped size from PageAllocator. This is intended to
@@ -434,7 +434,8 @@
   char value[24];
   // %d works for 64 bit types as well with SafeSPrintf(), see its unit tests
   // for an example.
-  base::strings::SafeSPrintf(value, "%d", base::GetTotalMappedSize());
+  base::strings::SafeSPrintf(value, "%d",
+                             partition_alloc::GetTotalMappedSize());
   static crash_reporter::CrashKeyString<24> g_page_allocator_mapped_size(
       "page-allocator-mapped-size");
   g_page_allocator_mapped_size.Set(value);
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 0fdb592..31955c55 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -6140,12 +6140,10 @@
 crbug.com/1228959 [ Linux ] virtual/scroll-unification/fast/scroll-snap/snaps-after-wheel-scrolling-single-tick.html [ Failure Pass ]
 
 # A number of http/tests/inspector-protocol/network tests are flaky.
-crbug.com/1228246 http/tests/inspector-protocol/network/disable-interception-midway.js [ Failure Pass Timeout ]
 crbug.com/1196027 http/tests/inspector-protocol/network/request-interception.js [ Failure Pass ]
 crbug.com/1228246 http/tests/inspector-protocol/network/request-interception-frame-id.js [ Failure Pass Timeout ]
 crbug.com/1228246 http/tests/inspector-protocol/network/request-interception-patterns.js [ Failure Pass Timeout ]
 crbug.com/1228246 http/tests/inspector-protocol/network/request-response-interception-disable-between.js [ Failure Pass Timeout ]
-crbug.com/1228246 http/tests/inspector-protocol/network/webbundle.js [ Failure Pass Timeout ]
 
 # linux_layout_tests_layout_ng_disabled needs its own baselines.
 crbug.com/1231699 [ Linux ] fast/borders/border-inner-bleed.html [ Failure Pass ]
@@ -7165,13 +7163,20 @@
 crbug.com/1342518 [ Win ] external/wpt/webmessaging/event.data.sub.htm [ Failure Pass ]
 
 # Sheriff 2022-07-08
-crbug.com/1180274 virtual/plz-dedicated-worker/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Failure Pass ]
-crbug.com/1180274 virtual/partitioned-cookies-first-party-sets/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Failure Pass ]
-crbug.com/1180274 virtual/first-party-sets/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Failure Pass ]
-crbug.com/1180274 virtual/partitioned-cookies/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Failure Pass ]
+crbug.com/1180274 virtual/plz-dedicated-worker/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Skip ]
+crbug.com/1180274 virtual/partitioned-cookies-first-party-sets/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Skip ]
+crbug.com/1180274 virtual/first-party-sets/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Skip ]
+crbug.com/1180274 virtual/partitioned-cookies/http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Skip ]
 
 # Sheriff 2022-07-11
 crbug.com/1343262 [ Win11 ] compositing/overlap-blending/reflection-opacity-huge.html [ Failure ]
 crbug.com/1343262 [ Win11 ] compositing/reflections/nested-reflection-opacity.html [ Failure ]
 crbug.com/1343262 [ Win11 ] fast/reflections/transparent-reflected-sublayers.html [ Failure ]
 crbug.com/1343270 [ Win11 ] media/controls/video-controls-with-cast-rendering.html [ Failure ]
+
+# Sheriff 2022-07-12
+crbug.com/1343674 [ Linux ] editing/deleting/460938.html [ Failure Pass ]
+crbug.com/1343664 external/wpt/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-document.html [ Failure Pass ]
+crbug.com/1343651 external/wpt/credential-management/fedcm-network-requests.sub.https.html [ Crash Pass ]
+crbug.com/1343698 [ Mac Release ] external/wpt/webmessaging/postMessage_asterisk_xorigin.sub.htm [ Failure Pass ]
+crbug.com/1343698 [ Win10.20h2 Release ] external/wpt/webmessaging/postMessage_asterisk_xorigin.sub.htm [ Failure Pass ]
diff --git a/third_party/blink/web_tests/W3CImportExpectations b/third_party/blink/web_tests/W3CImportExpectations
index 6260046..646fb51 100644
--- a/third_party/blink/web_tests/W3CImportExpectations
+++ b/third_party/blink/web_tests/W3CImportExpectations
@@ -417,6 +417,10 @@
 external/wpt/css/css-page/page-size-011.xht [ Skip ]
 external/wpt/css/css-page/page-size-012.xht [ Skip ]
 
+# This test caused presubmit check failure due to baselines path name exceeds 200 characters
+# Skip this test for now. Will rename the test at upstream then unskip
+external/wpt/editing/other/insertparagraph-or-insertlinebreak-in-inline-editing-host.tentative.html [ Skip ]
+
 # This test includes arbitrary html in unit test names (via parametrize) which
 # is currently not well handled in WebDriverExpectations, and causes Lint error
 # crbug.com/1167318
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/README.md b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/README.md
new file mode 100644
index 0000000..b3c24c3f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/README.md
@@ -0,0 +1,9 @@
+Because this test suite is run as a virtual suite and it's quite deep in the
+folders, we have to use abbreviations for the test names to not run over 200
+characters, which is problematic on Windows.
+
+* unspecified -> "u"
+* unsafe-none -> "un"
+* same-origin -> "so"
+* same-origin-allow-popups -> "soap"
+* restrict-properties -> omitted
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-so.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-so.https.html
new file mode 100644
index 0000000..e5313a6e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-so.https.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=timeout content=long>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="../../resources/common.js"></script>
+<script src="../../resources/popup-test.js"></script>
+<script>
+
+[
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "severed",
+    "origin": SAME_ORIGIN
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "severed",
+    "origin": SAME_SITE
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "severed",
+    "origin": CROSS_ORIGIN
+  }
+].forEach(variant => {
+  popup_test(`${variant.origin.name} ${variant.title}`, variant.origin,
+    { coop: variant.coop }, variant.opener);
+});
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-so.https.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-so.https.html.headers
new file mode 100644
index 0000000..46ad58d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-so.https.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy: same-origin
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https.html
new file mode 100644
index 0000000..595a10a8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=timeout content=long>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="../../resources/common.js"></script>
+<script src="../../resources/popup-test.js"></script>
+<script>
+
+[
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": SAME_ORIGIN
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": SAME_SITE
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": CROSS_ORIGIN
+  }
+].forEach(variant => {
+  popup_test(`${variant.origin.name} ${variant.title}`, variant.origin,
+    { coop: variant.coop }, variant.opener);
+});
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https.html.headers
new file mode 100644
index 0000000..d83ed86
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy: same-origin-allow-popups
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https.html
new file mode 100644
index 0000000..595a10a8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=timeout content=long>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="../../resources/common.js"></script>
+<script src="../../resources/popup-test.js"></script>
+<script>
+
+[
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": SAME_ORIGIN
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": SAME_SITE
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": CROSS_ORIGIN
+  }
+].forEach(variant => {
+  popup_test(`${variant.origin.name} ${variant.title}`, variant.origin,
+    { coop: variant.coop }, variant.opener);
+});
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https.html
new file mode 100644
index 0000000..595a10a8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=timeout content=long>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="../../resources/common.js"></script>
+<script src="../../resources/popup-test.js"></script>
+<script>
+
+[
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": SAME_ORIGIN
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": SAME_SITE
+  },
+  {
+    "title": "popup with coop restrict-properties",
+    "coop": "restrict-properties",
+    "opener": "restricted",
+    "origin": CROSS_ORIGIN
+  }
+].forEach(variant => {
+  popup_test(`${variant.origin.name} ${variant.title}`, variant.origin,
+    { coop: variant.coop }, variant.opener);
+});
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https.html.headers
new file mode 100644
index 0000000..073ce7a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy: unsafe-none
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-initially-empty-is-updated-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-initially-empty-is-updated-ref.html
new file mode 100644
index 0000000..0484c39
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-initially-empty-is-updated-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <iframe src="resources/hello-world.html"></iframe>
+  </body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-initially-empty-is-updated.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-initially-empty-is-updated.html
new file mode 100644
index 0000000..3ad5b0f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-initially-empty-is-updated.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>Iframe that doesn't load can be updated and rendered.</title>
+<meta charset="utf-8">
+<link rel="match" href="iframe-initially-empty-is-updated-ref.html"/>
+<html>
+  <head>
+    <script>
+      window.onload = () => {
+        requestAnimationFrame(() => {
+          requestAnimationFrame(() => {
+            document.documentElement.classList.remove("reftest-wait");
+          });
+        });
+      }
+    </script>
+  </head>
+  <body>
+    <iframe src="resources/empty.html"></iframe>
+    <script>
+      window[0].document.body.appendChild(document.createElement('div'))
+          .appendChild(document.createTextNode('Hello world!'));
+      window[0].document.body.firstChild.style = 'color: green';
+      window.stop();
+    </script>
+  </body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/resources/empty.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/resources/empty.html
new file mode 100644
index 0000000..763b073
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/resources/empty.html
@@ -0,0 +1 @@
+<!DOCTYPE html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/resources/hello-world.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/resources/hello-world.html
new file mode 100644
index 0000000..0d1111b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/resources/hello-world.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <head>
+  	<style>
+  	  * { color: 'green'; }
+  	</style>
+  </head>
+  <body>
+  	<div><span style="color: green">Hello world!</span></div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js b/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js
index c90e2726..452cdfa 100644
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js
+++ b/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js
@@ -59,6 +59,12 @@
   return {matrix: getMatrixFromTransform(fakeTransformInit)};
 }
 
+// Value equality for camera image init objects - they must contain `width` &
+// `height` properties and may contain `pixels` property.
+function isSameCameraImageInit(rhs, lhs) {
+  return lhs.width === rhs.width && lhs.height === rhs.height && lhs.pixels === rhs.pixels;
+}
+
 class ChromeXRTest {
   constructor() {
     this.mockVRService_ = new MockVRService();
@@ -327,6 +333,7 @@
     'anchors': vrMojom.XRSessionFeature.ANCHORS,
     'depth-sensing': vrMojom.XRSessionFeature.DEPTH,
     'secondary-views': vrMojom.XRSessionFeature.SECONDARY_VIEWS,
+    'camera-access': vrMojom.XRSessionFeature.CAMERA_ACCESS,
   };
 
   static _sessionModeToMojoMap = {
@@ -436,17 +443,33 @@
 
   // WebXR Test API
   setViews(primaryViews, secondaryViews) {
+    this.cameraImage_ = null;
     this.primaryViews_ = [];
     this.secondaryViews_ = [];
     let xOffset = 0;
     if (primaryViews) {
       this.primaryViews_ = [];
       xOffset = this._setViews(primaryViews, xOffset, this.primaryViews_);
+      const cameraImage = this._findCameraImage(primaryViews);
+
+      if (cameraImage) {
+        this.cameraImage_ = cameraImage;
+      }
     }
 
     if (secondaryViews) {
       this.secondaryViews_ = [];
       this._setViews(secondaryViews, xOffset, this.secondaryViews_);
+      const cameraImage = this._findCameraImage(secondaryViews);
+
+      if (cameraImage) {
+        if (!isSameCameraImageInit(this.cameraImage_, cameraImage)) {
+          throw new Error("If present, camera resolutions on each view must match each other!"
+                          + " Secondary views' camera doesn't match primary views.");
+        }
+
+        this.cameraImage_ = cameraImage;
+      }
     }
   }
 
@@ -702,6 +725,23 @@
     return xOffset;
   }
 
+  _findCameraImage(views) {
+    const viewWithCamera = views.find(view => view.cameraImageInit);
+    if (viewWithCamera) {
+      //If we have one view with a camera resolution, all views should have the same camera resolution.
+      const allViewsHaveSameCamera = views.every(
+        view => isSameCameraImageInit(view.cameraImageInit, viewWithCamera.cameraImageInit));
+
+      if (!allViewsHaveSameCamera) {
+        throw new Error("If present, camera resolutions on each view must match each other!");
+      }
+
+      return viewWithCamera.cameraImageInit;
+    }
+
+    return null;
+  }
+
   _onStageParametersUpdated() {
     // Indicate for the frame loop that the stage parameters have been updated.
     this.stageParametersId_++;
@@ -896,7 +936,10 @@
           },
           frameId: this.next_frame_id_,
           bufferHolder: null,
-          bufferSize: {},
+          cameraImageSize: this.cameraImage_ ? {
+            width: this.cameraImage_.width,
+            height: this.cameraImage_.height
+          } : null,
           renderingTimeRatio: 0,
           stageParameters: this.stageParameters_,
           stageParametersId: this.stageParametersId_,
diff --git a/third_party/blink/web_tests/external/wpt/webxr/camera-access/xrCamera_resolution.https.html b/third_party/blink/web_tests/external/wpt/webxr/camera-access/xrCamera_resolution.https.html
new file mode 100644
index 0000000..d6d8690
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webxr/camera-access/xrCamera_resolution.https.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/webxr_util.js"></script>
+<script src="../resources/webxr_test_asserts.js"></script>
+<script src="../resources/webxr_test_constants.js"></script>
+<script src="../resources/webxr_test_constants_fake_world.js"></script>
+
+<script>
+
+const fakeDeviceInitParams = {
+  supportedModes: ["immersive-ar"],
+  views: VALID_VIEWS,
+  supportedFeatures: ALL_FEATURES,
+};
+
+const test_camera_present = (session, fakeDeviceController, t) => {
+  return session.requestReferenceSpace('viewer').then(viewerRefSpace => {
+    return new Promise((resolve, reject) => {
+      const requestAnimationFrameCallbackWithCamera = (time, frame) => {
+        const viewerPose = frame.getViewerPose(viewerRefSpace);
+
+        t.step(() => {
+          let foundCamera = false;
+
+          assert_not_equals(viewerPose, null, "Viewer pose should not be null!");
+          assert_equals(viewerPose.views.length, VALID_VIEWS.length, "View lengths should match!");
+
+          for (const view of viewerPose.views) {
+            if (view.camera) {
+              assert_equals(view.camera.width, 333, "Width doesn't match expectations!");
+              assert_equals(view.camera.height, 444, "Height doesn't match expectations!");
+
+              foundCamera = true;
+            }
+          }
+
+          assert_true(foundCamera, "There should be at least one camera! Didn't find any.")
+        });
+
+        resolve();
+      };
+
+      const requestAnimationFrameCallbackNoCamera = (time, frame) => {
+
+        const viewerPose = frame.getViewerPose(viewerRefSpace);
+        t.step(() => {
+          assert_not_equals(viewerPose, null, "Viewer pose should not be null!");
+          assert_equals(viewerPose.views.length, VALID_VIEWS.length, "View lengths should match!");
+
+          for (const view of viewerPose.views) {
+            assert_equals(view.camera, null, "Camera should be null!");
+          }
+        });
+
+        const views_with_camera = VALID_VIEWS.map((element, index) => {
+          return {
+            ...element,
+            resolution: { width: 111 * (index+1),  height: 222 * (index+1)},
+            cameraImageInit: { width: 333, height: 444 },
+          };
+        });
+        fakeDeviceController.setViews(views_with_camera);
+
+        // After this rAFcb, the test is supposed to continue w/ a callback that
+        // expects XRCamera to be present:
+        session.requestAnimationFrame(requestAnimationFrameCallbackWithCamera);
+      };
+
+      // Kick off the test - start with rAFcb w/o an XRCamera:
+      session.requestAnimationFrame(requestAnimationFrameCallbackNoCamera);
+    });
+  });
+};
+
+xr_session_promise_test("XRCamera object is present and carries expected dimensions",
+  test_camera_present,
+  fakeDeviceInitParams, 'immersive-ar', {'requiredFeatures': ['camera-access']});
+
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/webxr/resources/webxr_test_constants.js b/third_party/blink/web_tests/external/wpt/webxr/resources/webxr_test_constants.js
index 042480da..cabc4b4 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/resources/webxr_test_constants.js
+++ b/third_party/blink/web_tests/external/wpt/webxr/resources/webxr_test_constants.js
@@ -141,6 +141,7 @@
   'anchors',
   'depth-sensing',
   'secondary-views',
+  'camera-access',
 ];
 
 const TRACKED_IMMERSIVE_DEVICE = {
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/touch-emulation-fenced-frame.https.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/touch-emulation-fenced-frame.https.js
new file mode 100644
index 0000000..4a78da2
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/touch-emulation-fenced-frame.https.js
@@ -0,0 +1,17 @@
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startURL(
+      'resources/page-with-fenced-frame.php',
+      'Tests that fenced frame target does not support ' +
+      'Emulation.setEmitTouchEventsForMouse');
+
+  dp.Target.setAutoAttach(
+      {autoAttach: true, waitForDebuggerOnStart: false, flatten: true});
+
+  const {sessionId} = (await dp.Target.onceAttachedToTarget()).params;
+  const ffdp = session.createChild(sessionId).protocol;
+
+  const result = await ffdp.Emulation.setEmitTouchEventsForMouse({enabled: true});
+
+  testRunner.log(result.error ? 'FAIL: ' + result.error.message : 'PASS');
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/disable-interception-midway.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/disable-interception-midway.js
index 0b01760b..c2a8dc5 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/disable-interception-midway.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/disable-interception-midway.js
@@ -11,6 +11,9 @@
       'post-echo.pl': event => helper.allowRequest(event),
   };
 
+  // The XHR triggered in the onload handler of the iframe races with the frameStoppedLoading event
+  // for the frame, so don't record it in the trace.
+  helper.setSilentFrameStoppedLoading(true);
   await helper.startInterceptionTest(requestInterceptedDict, 1);
   session.evaluate(`
     var iframe = document.createElement('iframe');
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/webbundle.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/webbundle.js
index 2f428a9..d632d0b 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/webbundle.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/webbundle.js
@@ -4,24 +4,21 @@
 
   await dp.Network.enable();
 
-  let requestWillBeSent = [];
-  let webBundleMetadataReceived = [];
-  let webBundleInnerResponse = [];
-
-  const recordEvent = (dest, event) => dest.push(event.params);
-
-  dp.Network.onRequestWillBeSent(recordEvent.bind(null, requestWillBeSent));
-  dp.Network.onSubresourceWebBundleMetadataReceived(
-      recordEvent.bind(null, webBundleMetadataReceived));
-  dp.Network.onSubresourceWebBundleInnerResponseParsed(
-      recordEvent.bind(null, webBundleInnerResponse));
-
   const reportError = event => testRunner.log(event, 'Error: ');
-
   dp.Network.onSubresourceWebBundleMetadataError(reportError);
   dp.Network.onSubresourceWebBundleInnerResponseError(reportError);
   session.navigate(testRunner.url('./resources/page-with-webbundle.html'));
-  await dp.Network.onceSubresourceWebBundleInnerResponseParsed();
+
+  const requestWillBeSent = [];
+  const [, webBundleMetadataReceived, webBundleInnerResponse] =
+      (await Promise.all([
+        dp.Network.onceRequestWillBeSent((event) => {
+          requestWillBeSent.push(event.params);
+          return requestWillBeSent.length == 3;
+        }),
+        dp.Network.onceSubresourceWebBundleMetadataReceived(),
+        dp.Network.onceSubresourceWebBundleInnerResponseParsed()
+      ])).map(event => event.params);
 
   testRunner.log(requestWillBeSent, 'requestWillBeSent', [
     'timestamp', 'wallTime', 'loaderId', 'frameId', 'requestId', 'User-Agent'
@@ -31,24 +28,23 @@
       webBundleInnerResponse, 'webBundleInnerResponse',
       ['bundleRequestId', 'innerRequestId']);
 
-  testRunner.log(`webBundleMetadataReceived[0].urls: ${
-      webBundleMetadataReceived[0].urls}`);
-  testRunner.log(`webBundleInnerResponse[0].innerRequestURL: ${
-      webBundleInnerResponse[0].innerRequestURL}`);
-  if (requestWillBeSent[1].requestId ===
-      webBundleMetadataReceived[0].requestId) {
+  testRunner.log(
+      `webBundleMetadataReceived.urls: ${webBundleMetadataReceived.urls}`);
+  testRunner.log(`webBundleInnerResponse.innerRequestURL: ${
+      webBundleInnerResponse.innerRequestURL}`);
+  if (requestWillBeSent[1].requestId === webBundleMetadataReceived.requestId) {
     testRunner.log(
         'bundle request ID from webBundleMetadataReceived ' +
         'matches ID from requestWillBeSent');
   }
   if (requestWillBeSent[2].requestId ===
-      webBundleInnerResponse[0].innerRequestId) {
+      webBundleInnerResponse.innerRequestId) {
     testRunner.log(
         'inner request ID from webBundleInnerResponse ' +
         'matches ID from requestWillBeSent');
   }
-  if (webBundleInnerResponse[0].bundleRequestId ===
-      webBundleMetadataReceived[0].requestId) {
+  if (webBundleInnerResponse.bundleRequestId ===
+      webBundleMetadataReceived.requestId) {
     testRunner.log(
         'inner request ID from webBundleInnerResponse ' +
         'matches ID from webBundleMetadataReceived');
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https-expected.txt
new file mode 100644
index 0000000..8c40e7b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL SAME_ORIGIN popup with coop restrict-properties assert_false: Main page has dom access to the popup? expected false got true
+FAIL SAME_SITE popup with coop restrict-properties assert_false: Main page has cross origin access to the popup? expected false got true
+FAIL CROSS_ORIGIN popup with coop restrict-properties assert_false: Main page has cross origin access to the popup? expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https-expected.txt
new file mode 100644
index 0000000..8c40e7b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL SAME_ORIGIN popup with coop restrict-properties assert_false: Main page has dom access to the popup? expected false got true
+FAIL SAME_SITE popup with coop restrict-properties assert_false: Main page has cross origin access to the popup? expected false got true
+FAIL CROSS_ORIGIN popup with coop restrict-properties assert_false: Main page has cross origin access to the popup? expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https-expected.txt
new file mode 100644
index 0000000..8c40e7b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL SAME_ORIGIN popup with coop restrict-properties assert_false: Main page has dom access to the popup? expected false got true
+FAIL SAME_SITE popup with coop restrict-properties assert_false: Main page has cross origin access to the popup? expected false got true
+FAIL CROSS_ORIGIN popup with coop restrict-properties assert_false: Main page has cross origin access to the popup? expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any-expected.txt
deleted file mode 100644
index bc0a2aa0..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any-expected.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-This is a testharness.js-based test.
-Found 99 tests; 84 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS getReader({mode: "byob"}) throws on non-bytes streams
-PASS ReadableStream with byte source can be constructed with no errors
-PASS getReader({mode}) must perform ToString()
-PASS ReadableStream with byte source: Construct and expect start and pull being called
-PASS ReadableStream with byte source: No automatic pull call if start doesn't finish
-PASS ReadableStream with byte source: start() throws an exception
-PASS ReadableStream with byte source: Construct with highWaterMark of 0
-PASS ReadableStream with byte source: desiredSize when closed
-PASS ReadableStream with byte source: desiredSize when errored
-PASS ReadableStream with byte source: getReader(), then releaseLock()
-PASS ReadableStream with byte source: getReader() with mode set to byob, then releaseLock()
-PASS ReadableStream with byte source: Test that closing a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: Automatic pull() after start()
-PASS ReadableStream with byte source: Automatic pull() after start() and read()
-PASS ReadableStream with byte source: autoAllocateChunkSize
-PASS ReadableStream with byte source: Mix of auto allocate and BYOB
-PASS ReadableStream with byte source: Automatic pull() after start() and read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read()
-PASS ReadableStream with byte source: Push source that doesn't understand pull signal
-PASS ReadableStream with byte source: pull() function is not callable
-PASS ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read()
-PASS ReadableStream with byte source: enqueue(), read(view) partially, then read()
-PASS ReadableStream with byte source: getReader(), enqueue(), close(), then read()
-PASS ReadableStream with byte source: enqueue(), close(), getReader(), then read()
-PASS ReadableStream with byte source: Respond to pull() by enqueue()
-PASS ReadableStream with byte source: Respond to pull() by enqueue() asynchronously
-PASS ReadableStream with byte source: Respond to multiple pull() by separate enqueue()
-PASS ReadableStream with byte source: read(view), then respond()
-PASS ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer
-PASS ReadableStream with byte source: read(view), then respond() with too big value
-PASS ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB)
-PASS ReadableStream with byte source: getReader(), read(view), then cancel()
-PASS ReadableStream with byte source: cancel() with partially filled pending pull() request
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view
-PASS ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views
-PASS ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array
-PASS ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array
-PASS ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail
-PASS ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array
-PASS ReadableStream with byte source: Throw if close()-ed more than once
-PASS ReadableStream with byte source: Throw on enqueue() after close()
-PASS ReadableStream with byte source: read(view), then respond() and close() in pull()
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls
-PASS ReadableStream with byte source: read() twice, then enqueue() twice
-PASS ReadableStream with byte source: Multiple read(view), close() and respond()
-PASS ReadableStream with byte source: Multiple read(view), big enqueue()
-PASS ReadableStream with byte source: Multiple read(view) and multiple enqueue()
-PASS ReadableStream with byte source: read(view) with passing undefined as view must fail
-PASS ReadableStream with byte source: read(view) with passing an empty object as view must fail
-PASS ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail
-PASS ReadableStream with byte source: read() on an errored stream
-PASS ReadableStream with byte source: read(), then error()
-PASS ReadableStream with byte source: read(view) on an errored stream
-PASS ReadableStream with byte source: read(view), then error()
-PASS ReadableStream with byte source: Throwing in pull function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it
-PASS calling respond() twice on the same byobRequest should throw
-PASS calling respondWithNewView() twice on the same byobRequest should throw
-PASS calling respond(0) twice on the same byobRequest should throw even when closed
-PASS calling respond() should throw when canceled
-FAIL pull() resolving should not resolve read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction
-PASS ReadableStream with byte source: autoAllocateChunkSize cannot be 0
-PASS ReadableStreamBYOBReader can be constructed directly
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream argument
-PASS ReadableStreamBYOBReader constructor requires an unlocked ReadableStream
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"
-PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"
-PASS ReadableStream with byte source: respondWithNewView() with a smaller view
-PASS ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)
-PASS ReadableStream with byte source: enqueue() discards auto-allocated BYOB request
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 2 element Uint8Array, respond(3) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, close(), respond(0) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: autoAllocateChunkSize, read(), respondWithNewView()
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.serviceworker-expected.txt
deleted file mode 100644
index bc0a2aa0..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.serviceworker-expected.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-This is a testharness.js-based test.
-Found 99 tests; 84 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS getReader({mode: "byob"}) throws on non-bytes streams
-PASS ReadableStream with byte source can be constructed with no errors
-PASS getReader({mode}) must perform ToString()
-PASS ReadableStream with byte source: Construct and expect start and pull being called
-PASS ReadableStream with byte source: No automatic pull call if start doesn't finish
-PASS ReadableStream with byte source: start() throws an exception
-PASS ReadableStream with byte source: Construct with highWaterMark of 0
-PASS ReadableStream with byte source: desiredSize when closed
-PASS ReadableStream with byte source: desiredSize when errored
-PASS ReadableStream with byte source: getReader(), then releaseLock()
-PASS ReadableStream with byte source: getReader() with mode set to byob, then releaseLock()
-PASS ReadableStream with byte source: Test that closing a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: Automatic pull() after start()
-PASS ReadableStream with byte source: Automatic pull() after start() and read()
-PASS ReadableStream with byte source: autoAllocateChunkSize
-PASS ReadableStream with byte source: Mix of auto allocate and BYOB
-PASS ReadableStream with byte source: Automatic pull() after start() and read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read()
-PASS ReadableStream with byte source: Push source that doesn't understand pull signal
-PASS ReadableStream with byte source: pull() function is not callable
-PASS ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read()
-PASS ReadableStream with byte source: enqueue(), read(view) partially, then read()
-PASS ReadableStream with byte source: getReader(), enqueue(), close(), then read()
-PASS ReadableStream with byte source: enqueue(), close(), getReader(), then read()
-PASS ReadableStream with byte source: Respond to pull() by enqueue()
-PASS ReadableStream with byte source: Respond to pull() by enqueue() asynchronously
-PASS ReadableStream with byte source: Respond to multiple pull() by separate enqueue()
-PASS ReadableStream with byte source: read(view), then respond()
-PASS ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer
-PASS ReadableStream with byte source: read(view), then respond() with too big value
-PASS ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB)
-PASS ReadableStream with byte source: getReader(), read(view), then cancel()
-PASS ReadableStream with byte source: cancel() with partially filled pending pull() request
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view
-PASS ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views
-PASS ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array
-PASS ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array
-PASS ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail
-PASS ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array
-PASS ReadableStream with byte source: Throw if close()-ed more than once
-PASS ReadableStream with byte source: Throw on enqueue() after close()
-PASS ReadableStream with byte source: read(view), then respond() and close() in pull()
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls
-PASS ReadableStream with byte source: read() twice, then enqueue() twice
-PASS ReadableStream with byte source: Multiple read(view), close() and respond()
-PASS ReadableStream with byte source: Multiple read(view), big enqueue()
-PASS ReadableStream with byte source: Multiple read(view) and multiple enqueue()
-PASS ReadableStream with byte source: read(view) with passing undefined as view must fail
-PASS ReadableStream with byte source: read(view) with passing an empty object as view must fail
-PASS ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail
-PASS ReadableStream with byte source: read() on an errored stream
-PASS ReadableStream with byte source: read(), then error()
-PASS ReadableStream with byte source: read(view) on an errored stream
-PASS ReadableStream with byte source: read(view), then error()
-PASS ReadableStream with byte source: Throwing in pull function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it
-PASS calling respond() twice on the same byobRequest should throw
-PASS calling respondWithNewView() twice on the same byobRequest should throw
-PASS calling respond(0) twice on the same byobRequest should throw even when closed
-PASS calling respond() should throw when canceled
-FAIL pull() resolving should not resolve read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction
-PASS ReadableStream with byte source: autoAllocateChunkSize cannot be 0
-PASS ReadableStreamBYOBReader can be constructed directly
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream argument
-PASS ReadableStreamBYOBReader constructor requires an unlocked ReadableStream
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"
-PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"
-PASS ReadableStream with byte source: respondWithNewView() with a smaller view
-PASS ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)
-PASS ReadableStream with byte source: enqueue() discards auto-allocated BYOB request
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 2 element Uint8Array, respond(3) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, close(), respond(0) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: autoAllocateChunkSize, read(), respondWithNewView()
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.sharedworker-expected.txt
deleted file mode 100644
index bc0a2aa0..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-This is a testharness.js-based test.
-Found 99 tests; 84 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS getReader({mode: "byob"}) throws on non-bytes streams
-PASS ReadableStream with byte source can be constructed with no errors
-PASS getReader({mode}) must perform ToString()
-PASS ReadableStream with byte source: Construct and expect start and pull being called
-PASS ReadableStream with byte source: No automatic pull call if start doesn't finish
-PASS ReadableStream with byte source: start() throws an exception
-PASS ReadableStream with byte source: Construct with highWaterMark of 0
-PASS ReadableStream with byte source: desiredSize when closed
-PASS ReadableStream with byte source: desiredSize when errored
-PASS ReadableStream with byte source: getReader(), then releaseLock()
-PASS ReadableStream with byte source: getReader() with mode set to byob, then releaseLock()
-PASS ReadableStream with byte source: Test that closing a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: Automatic pull() after start()
-PASS ReadableStream with byte source: Automatic pull() after start() and read()
-PASS ReadableStream with byte source: autoAllocateChunkSize
-PASS ReadableStream with byte source: Mix of auto allocate and BYOB
-PASS ReadableStream with byte source: Automatic pull() after start() and read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read()
-PASS ReadableStream with byte source: Push source that doesn't understand pull signal
-PASS ReadableStream with byte source: pull() function is not callable
-PASS ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read()
-PASS ReadableStream with byte source: enqueue(), read(view) partially, then read()
-PASS ReadableStream with byte source: getReader(), enqueue(), close(), then read()
-PASS ReadableStream with byte source: enqueue(), close(), getReader(), then read()
-PASS ReadableStream with byte source: Respond to pull() by enqueue()
-PASS ReadableStream with byte source: Respond to pull() by enqueue() asynchronously
-PASS ReadableStream with byte source: Respond to multiple pull() by separate enqueue()
-PASS ReadableStream with byte source: read(view), then respond()
-PASS ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer
-PASS ReadableStream with byte source: read(view), then respond() with too big value
-PASS ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB)
-PASS ReadableStream with byte source: getReader(), read(view), then cancel()
-PASS ReadableStream with byte source: cancel() with partially filled pending pull() request
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view
-PASS ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views
-PASS ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array
-PASS ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array
-PASS ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail
-PASS ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array
-PASS ReadableStream with byte source: Throw if close()-ed more than once
-PASS ReadableStream with byte source: Throw on enqueue() after close()
-PASS ReadableStream with byte source: read(view), then respond() and close() in pull()
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls
-PASS ReadableStream with byte source: read() twice, then enqueue() twice
-PASS ReadableStream with byte source: Multiple read(view), close() and respond()
-PASS ReadableStream with byte source: Multiple read(view), big enqueue()
-PASS ReadableStream with byte source: Multiple read(view) and multiple enqueue()
-PASS ReadableStream with byte source: read(view) with passing undefined as view must fail
-PASS ReadableStream with byte source: read(view) with passing an empty object as view must fail
-PASS ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail
-PASS ReadableStream with byte source: read() on an errored stream
-PASS ReadableStream with byte source: read(), then error()
-PASS ReadableStream with byte source: read(view) on an errored stream
-PASS ReadableStream with byte source: read(view), then error()
-PASS ReadableStream with byte source: Throwing in pull function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it
-PASS calling respond() twice on the same byobRequest should throw
-PASS calling respondWithNewView() twice on the same byobRequest should throw
-PASS calling respond(0) twice on the same byobRequest should throw even when closed
-PASS calling respond() should throw when canceled
-FAIL pull() resolving should not resolve read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction
-PASS ReadableStream with byte source: autoAllocateChunkSize cannot be 0
-PASS ReadableStreamBYOBReader can be constructed directly
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream argument
-PASS ReadableStreamBYOBReader constructor requires an unlocked ReadableStream
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"
-PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"
-PASS ReadableStream with byte source: respondWithNewView() with a smaller view
-PASS ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)
-PASS ReadableStream with byte source: enqueue() discards auto-allocated BYOB request
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 2 element Uint8Array, respond(3) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, close(), respond(0) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: autoAllocateChunkSize, read(), respondWithNewView()
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.worker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.worker-expected.txt
deleted file mode 100644
index bc0a2aa0..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-byte-streams/general.any.worker-expected.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-This is a testharness.js-based test.
-Found 99 tests; 84 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS getReader({mode: "byob"}) throws on non-bytes streams
-PASS ReadableStream with byte source can be constructed with no errors
-PASS getReader({mode}) must perform ToString()
-PASS ReadableStream with byte source: Construct and expect start and pull being called
-PASS ReadableStream with byte source: No automatic pull call if start doesn't finish
-PASS ReadableStream with byte source: start() throws an exception
-PASS ReadableStream with byte source: Construct with highWaterMark of 0
-PASS ReadableStream with byte source: desiredSize when closed
-PASS ReadableStream with byte source: desiredSize when errored
-PASS ReadableStream with byte source: getReader(), then releaseLock()
-PASS ReadableStream with byte source: getReader() with mode set to byob, then releaseLock()
-PASS ReadableStream with byte source: Test that closing a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a reader automatically
-PASS ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: Automatic pull() after start()
-PASS ReadableStream with byte source: Automatic pull() after start() and read()
-PASS ReadableStream with byte source: autoAllocateChunkSize
-PASS ReadableStream with byte source: Mix of auto allocate and BYOB
-PASS ReadableStream with byte source: Automatic pull() after start() and read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read()
-PASS ReadableStream with byte source: Push source that doesn't understand pull signal
-PASS ReadableStream with byte source: pull() function is not callable
-PASS ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read()
-PASS ReadableStream with byte source: enqueue(), read(view) partially, then read()
-PASS ReadableStream with byte source: getReader(), enqueue(), close(), then read()
-PASS ReadableStream with byte source: enqueue(), close(), getReader(), then read()
-PASS ReadableStream with byte source: Respond to pull() by enqueue()
-PASS ReadableStream with byte source: Respond to pull() by enqueue() asynchronously
-PASS ReadableStream with byte source: Respond to multiple pull() by separate enqueue()
-PASS ReadableStream with byte source: read(view), then respond()
-PASS ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer
-PASS ReadableStream with byte source: read(view), then respond() with too big value
-PASS ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB)
-PASS ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB)
-PASS ReadableStream with byte source: getReader(), read(view), then cancel()
-PASS ReadableStream with byte source: cancel() with partially filled pending pull() request
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view
-PASS ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view)
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view
-PASS ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views
-PASS ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array
-PASS ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array
-PASS ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail
-PASS ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array
-PASS ReadableStream with byte source: Throw if close()-ed more than once
-PASS ReadableStream with byte source: Throw on enqueue() after close()
-PASS ReadableStream with byte source: read(view), then respond() and close() in pull()
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls
-PASS ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls
-PASS ReadableStream with byte source: read() twice, then enqueue() twice
-PASS ReadableStream with byte source: Multiple read(view), close() and respond()
-PASS ReadableStream with byte source: Multiple read(view), big enqueue()
-PASS ReadableStream with byte source: Multiple read(view) and multiple enqueue()
-PASS ReadableStream with byte source: read(view) with passing undefined as view must fail
-PASS ReadableStream with byte source: read(view) with passing an empty object as view must fail
-PASS ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail
-PASS ReadableStream with byte source: read() on an errored stream
-PASS ReadableStream with byte source: read(), then error()
-PASS ReadableStream with byte source: read(view) on an errored stream
-PASS ReadableStream with byte source: read(view), then error()
-PASS ReadableStream with byte source: Throwing in pull function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream
-PASS ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it
-PASS calling respond() twice on the same byobRequest should throw
-PASS calling respondWithNewView() twice on the same byobRequest should throw
-PASS calling respond(0) twice on the same byobRequest should throw even when closed
-PASS calling respond() should throw when canceled
-FAIL pull() resolving should not resolve read() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction
-PASS ReadableStream with byte source: autoAllocateChunkSize cannot be 0
-PASS ReadableStreamBYOBReader can be constructed directly
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream argument
-PASS ReadableStreamBYOBReader constructor requires an unlocked ReadableStream
-PASS ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"
-PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"
-PASS ReadableStream with byte source: respondWithNewView() with a smaller view
-PASS ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)
-PASS ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)
-PASS ReadableStream with byte source: enqueue() discards auto-allocated BYOB request
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 2 element Uint8Array, respond(3) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, close(), respond(0) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on second reader with 1 element Uint16Array, respond(1) promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-FAIL ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on second reader, enqueue() promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamBYOBReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream with byte source: autoAllocateChunkSize, read(), respondWithNewView()
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any-expected.txt
deleted file mode 100644
index e1c6daa..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a testharness.js-based test.
-PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument
-PASS ReadableStreamDefaultReader closed should always return the same promise object
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction)
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader)
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored
-PASS Reading from a reader for an empty stream will wait until a chunk is available
-PASS cancel() on a reader does not release the reader
-PASS closed should be fulfilled after stream is closed (.closed access before acquiring)
-PASS closed should be rejected after reader releases its lock (multiple stream locks)
-PASS closed is replaced when stream closes and reader releases its lock
-PASS closed is replaced when stream errors and reader releases its lock
-PASS Multiple readers can access the stream in sequence
-PASS Cannot use an already-released reader to unlock a stream again
-PASS cancel() on a released reader is a no-op and does not pass through
-PASS Getting a second reader after erroring the stream and releasing the reader should succeed
-PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error
-PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error
-PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Reading twice on a stream that gets closed
-PASS Reading twice on a closed stream
-PASS Reading twice on an errored stream
-PASS Reading twice on a stream that gets errored
-PASS getReader() should call ToString() on mode
-PASS controller.close() should clear the list of pending read requests
-FAIL Second reader can read chunks after first reader was released with pending read requests Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.serviceworker-expected.txt
deleted file mode 100644
index e1c6daa..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.serviceworker-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a testharness.js-based test.
-PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument
-PASS ReadableStreamDefaultReader closed should always return the same promise object
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction)
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader)
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored
-PASS Reading from a reader for an empty stream will wait until a chunk is available
-PASS cancel() on a reader does not release the reader
-PASS closed should be fulfilled after stream is closed (.closed access before acquiring)
-PASS closed should be rejected after reader releases its lock (multiple stream locks)
-PASS closed is replaced when stream closes and reader releases its lock
-PASS closed is replaced when stream errors and reader releases its lock
-PASS Multiple readers can access the stream in sequence
-PASS Cannot use an already-released reader to unlock a stream again
-PASS cancel() on a released reader is a no-op and does not pass through
-PASS Getting a second reader after erroring the stream and releasing the reader should succeed
-PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error
-PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error
-PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Reading twice on a stream that gets closed
-PASS Reading twice on a closed stream
-PASS Reading twice on an errored stream
-PASS Reading twice on a stream that gets errored
-PASS getReader() should call ToString() on mode
-PASS controller.close() should clear the list of pending read requests
-FAIL Second reader can read chunks after first reader was released with pending read requests Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.sharedworker-expected.txt
deleted file mode 100644
index e1c6daa..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a testharness.js-based test.
-PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument
-PASS ReadableStreamDefaultReader closed should always return the same promise object
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction)
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader)
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored
-PASS Reading from a reader for an empty stream will wait until a chunk is available
-PASS cancel() on a reader does not release the reader
-PASS closed should be fulfilled after stream is closed (.closed access before acquiring)
-PASS closed should be rejected after reader releases its lock (multiple stream locks)
-PASS closed is replaced when stream closes and reader releases its lock
-PASS closed is replaced when stream errors and reader releases its lock
-PASS Multiple readers can access the stream in sequence
-PASS Cannot use an already-released reader to unlock a stream again
-PASS cancel() on a released reader is a no-op and does not pass through
-PASS Getting a second reader after erroring the stream and releasing the reader should succeed
-PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error
-PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error
-PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Reading twice on a stream that gets closed
-PASS Reading twice on a closed stream
-PASS Reading twice on an errored stream
-PASS Reading twice on a stream that gets errored
-PASS getReader() should call ToString() on mode
-PASS controller.close() should clear the list of pending read requests
-FAIL Second reader can read chunks after first reader was released with pending read requests Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.worker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.worker-expected.txt
deleted file mode 100644
index e1c6daa..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/default-reader.any.worker-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a testharness.js-based test.
-PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument
-PASS ReadableStreamDefaultReader closed should always return the same promise object
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction)
-PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader)
-PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader)
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed
-PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored
-PASS Reading from a reader for an empty stream will wait until a chunk is available
-PASS cancel() on a reader does not release the reader
-PASS closed should be fulfilled after stream is closed (.closed access before acquiring)
-PASS closed should be rejected after reader releases its lock (multiple stream locks)
-PASS closed is replaced when stream closes and reader releases its lock
-PASS closed is replaced when stream errors and reader releases its lock
-PASS Multiple readers can access the stream in sequence
-PASS Cannot use an already-released reader to unlock a stream again
-PASS cancel() on a released reader is a no-op and does not pass through
-PASS Getting a second reader after erroring the stream and releasing the reader should succeed
-PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error
-PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error
-PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise
-PASS Reading twice on a stream that gets closed
-PASS Reading twice on a closed stream
-PASS Reading twice on an errored stream
-PASS Reading twice on a stream that gets errored
-PASS getReader() should call ToString() on mode
-PASS controller.close() should clear the list of pending read requests
-FAIL Second reader can read chunks after first reader was released with pending read requests Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any-expected.txt
index 77dca75..f0732e1 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any-expected.txt
@@ -12,7 +12,7 @@
 PASS ReadableStream start should be able to return a promise
 PASS ReadableStream start should be able to return a promise and reject it
 PASS ReadableStream should be able to enqueue different objects.
-FAIL ReadableStream: if pull rejects, it should error the stream assert_true: expected true got false
+PASS ReadableStream: if pull rejects, it should error the stream
 PASS ReadableStream: should only call pull once upon starting the stream
 PASS ReadableStream: should call pull when trying to read from a started, empty stream
 PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.serviceworker-expected.txt
index 77dca75..f0732e1 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.serviceworker-expected.txt
@@ -12,7 +12,7 @@
 PASS ReadableStream start should be able to return a promise
 PASS ReadableStream start should be able to return a promise and reject it
 PASS ReadableStream should be able to enqueue different objects.
-FAIL ReadableStream: if pull rejects, it should error the stream assert_true: expected true got false
+PASS ReadableStream: if pull rejects, it should error the stream
 PASS ReadableStream: should only call pull once upon starting the stream
 PASS ReadableStream: should call pull when trying to read from a started, empty stream
 PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.sharedworker-expected.txt
index 77dca75..f0732e1 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.sharedworker-expected.txt
@@ -12,7 +12,7 @@
 PASS ReadableStream start should be able to return a promise
 PASS ReadableStream start should be able to return a promise and reject it
 PASS ReadableStream should be able to enqueue different objects.
-FAIL ReadableStream: if pull rejects, it should error the stream assert_true: expected true got false
+PASS ReadableStream: if pull rejects, it should error the stream
 PASS ReadableStream: should only call pull once upon starting the stream
 PASS ReadableStream: should call pull when trying to read from a started, empty stream
 PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.worker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.worker-expected.txt
index 77dca75..f0732e1 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/general.any.worker-expected.txt
@@ -12,7 +12,7 @@
 PASS ReadableStream start should be able to return a promise
 PASS ReadableStream start should be able to return a promise and reject it
 PASS ReadableStream should be able to enqueue different objects.
-FAIL ReadableStream: if pull rejects, it should error the stream assert_true: expected true got false
+PASS ReadableStream: if pull rejects, it should error the stream
 PASS ReadableStream: should only call pull once upon starting the stream
 PASS ReadableStream: should call pull when trying to read from a started, empty stream
 PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any-expected.txt
deleted file mode 100644
index c157af32..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any-expected.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-This is a testharness.js-based test.
-Found 86 tests; 85 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Running templatedRSEmpty with ReadableStream (empty)
-PASS ReadableStream (empty): instances have the correct methods and properties
-PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors
-PASS Running templatedRSEmptyReader with ReadableStream (empty) reader
-PASS ReadableStream (empty) reader: instances have the correct methods and properties
-PASS ReadableStream (empty) reader: locked should be true
-PASS ReadableStream (empty) reader: read() should never settle
-PASS ReadableStream (empty) reader: two read()s should both never settle
-PASS ReadableStream (empty) reader: read() should return distinct promises each time
-PASS ReadableStream (empty) reader: getReader() again on the stream should fail
-FAIL ReadableStream (empty) reader: releasing the lock should reject all pending read requests promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false
-PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed
-PASS ReadableStream (empty) reader: canceling via the stream should fail
-PASS Running templatedRSClosed with ReadableStream (closed via call in start)
-PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via call in start): locked should be false
-PASS ReadableStream (closed via call in start): getReader() should be OK
-PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader)
-PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader)
-PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosed with ReadableStream (closed via cancel)
-PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via cancel): locked should be false
-PASS ReadableStream (closed via cancel): getReader() should be OK
-PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader)
-PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via call in start): read() twice should give the error each time
-PASS ReadableStream (errored via call in start): locked should be false
-PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise
-PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock
-PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time
-PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start)
-PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time
-PASS ReadableStream (errored via returning a rejected promise in start): locked should be false
-PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader
-PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error
-PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity
-PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader)
-PASS ReadableStream reader (errored before getting reader): closed should reject with the error
-PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored before getting reader): read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader)
-PASS ReadableStream reader (errored after getting reader): closed should reject with the error
-PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored after getting reader): read() should reject with the error
-PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential)
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested)
-PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time
-PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result
-PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential)
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested)
-PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.serviceworker-expected.txt
deleted file mode 100644
index c157af32..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.serviceworker-expected.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-This is a testharness.js-based test.
-Found 86 tests; 85 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Running templatedRSEmpty with ReadableStream (empty)
-PASS ReadableStream (empty): instances have the correct methods and properties
-PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors
-PASS Running templatedRSEmptyReader with ReadableStream (empty) reader
-PASS ReadableStream (empty) reader: instances have the correct methods and properties
-PASS ReadableStream (empty) reader: locked should be true
-PASS ReadableStream (empty) reader: read() should never settle
-PASS ReadableStream (empty) reader: two read()s should both never settle
-PASS ReadableStream (empty) reader: read() should return distinct promises each time
-PASS ReadableStream (empty) reader: getReader() again on the stream should fail
-FAIL ReadableStream (empty) reader: releasing the lock should reject all pending read requests promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false
-PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed
-PASS ReadableStream (empty) reader: canceling via the stream should fail
-PASS Running templatedRSClosed with ReadableStream (closed via call in start)
-PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via call in start): locked should be false
-PASS ReadableStream (closed via call in start): getReader() should be OK
-PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader)
-PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader)
-PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosed with ReadableStream (closed via cancel)
-PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via cancel): locked should be false
-PASS ReadableStream (closed via cancel): getReader() should be OK
-PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader)
-PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via call in start): read() twice should give the error each time
-PASS ReadableStream (errored via call in start): locked should be false
-PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise
-PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock
-PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time
-PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start)
-PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time
-PASS ReadableStream (errored via returning a rejected promise in start): locked should be false
-PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader
-PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error
-PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity
-PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader)
-PASS ReadableStream reader (errored before getting reader): closed should reject with the error
-PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored before getting reader): read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader)
-PASS ReadableStream reader (errored after getting reader): closed should reject with the error
-PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored after getting reader): read() should reject with the error
-PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential)
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested)
-PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time
-PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result
-PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential)
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested)
-PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.sharedworker-expected.txt
deleted file mode 100644
index c157af32..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-This is a testharness.js-based test.
-Found 86 tests; 85 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Running templatedRSEmpty with ReadableStream (empty)
-PASS ReadableStream (empty): instances have the correct methods and properties
-PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors
-PASS Running templatedRSEmptyReader with ReadableStream (empty) reader
-PASS ReadableStream (empty) reader: instances have the correct methods and properties
-PASS ReadableStream (empty) reader: locked should be true
-PASS ReadableStream (empty) reader: read() should never settle
-PASS ReadableStream (empty) reader: two read()s should both never settle
-PASS ReadableStream (empty) reader: read() should return distinct promises each time
-PASS ReadableStream (empty) reader: getReader() again on the stream should fail
-FAIL ReadableStream (empty) reader: releasing the lock should reject all pending read requests promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false
-PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed
-PASS ReadableStream (empty) reader: canceling via the stream should fail
-PASS Running templatedRSClosed with ReadableStream (closed via call in start)
-PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via call in start): locked should be false
-PASS ReadableStream (closed via call in start): getReader() should be OK
-PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader)
-PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader)
-PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosed with ReadableStream (closed via cancel)
-PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via cancel): locked should be false
-PASS ReadableStream (closed via cancel): getReader() should be OK
-PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader)
-PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via call in start): read() twice should give the error each time
-PASS ReadableStream (errored via call in start): locked should be false
-PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise
-PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock
-PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time
-PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start)
-PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time
-PASS ReadableStream (errored via returning a rejected promise in start): locked should be false
-PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader
-PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error
-PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity
-PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader)
-PASS ReadableStream reader (errored before getting reader): closed should reject with the error
-PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored before getting reader): read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader)
-PASS ReadableStream reader (errored after getting reader): closed should reject with the error
-PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored after getting reader): read() should reject with the error
-PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential)
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested)
-PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time
-PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result
-PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential)
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested)
-PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.worker-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.worker-expected.txt
deleted file mode 100644
index c157af32..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/streams/readable-streams/templated.any.worker-expected.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-This is a testharness.js-based test.
-Found 86 tests; 85 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Running templatedRSEmpty with ReadableStream (empty)
-PASS ReadableStream (empty): instances have the correct methods and properties
-PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors
-PASS Running templatedRSEmptyReader with ReadableStream (empty) reader
-PASS ReadableStream (empty) reader: instances have the correct methods and properties
-PASS ReadableStream (empty) reader: locked should be true
-PASS ReadableStream (empty) reader: read() should never settle
-PASS ReadableStream (empty) reader: two read()s should both never settle
-PASS ReadableStream (empty) reader: read() should return distinct promises each time
-PASS ReadableStream (empty) reader: getReader() again on the stream should fail
-FAIL ReadableStream (empty) reader: releasing the lock should reject all pending read requests promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'releaseLock' on 'ReadableStreamDefaultReader': Cannot release a readable stream reader when it still has outstanding read() calls that have not yet settled"
-PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError
-PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false
-PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed
-PASS ReadableStream (empty) reader: canceling via the stream should fail
-PASS Running templatedRSClosed with ReadableStream (closed via call in start)
-PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via call in start): locked should be false
-PASS ReadableStream (closed via call in start): getReader() should be OK
-PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader)
-PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader)
-PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSClosed with ReadableStream (closed via cancel)
-PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time
-PASS ReadableStream (closed via cancel): locked should be false
-PASS ReadableStream (closed via cancel): getReader() should be OK
-PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession
-PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one
-PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader)
-PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
-PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback
-PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined
-PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via call in start): read() twice should give the error each time
-PASS ReadableStream (errored via call in start): locked should be false
-PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start)
-PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise
-PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock
-PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time
-PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time
-PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start)
-PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored
-PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time
-PASS ReadableStream (errored via returning a rejected promise in start): locked should be false
-PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader
-PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error
-PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity
-PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader)
-PASS ReadableStream reader (errored before getting reader): closed should reject with the error
-PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored before getting reader): read() should reject with the error
-PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader)
-PASS ReadableStream reader (errored after getting reader): closed should reject with the error
-PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity
-PASS ReadableStream reader (errored after getting reader): read() should reject with the error
-PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential)
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested)
-PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time
-PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result
-PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential)
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested)
-PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError
-PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/touch-emulation-fenced-frame.https-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/touch-emulation-fenced-frame.https-expected.txt
new file mode 100644
index 0000000..effa22d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/touch-emulation-fenced-frame.https-expected.txt
@@ -0,0 +1,3 @@
+Tests that fenced frame target does not support Emulation.setEmitTouchEventsForMouse
+FAIL: Command can only be executed on top-level targets
+
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt
index ef2b67d6..82ea46b 100644
--- a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt
@@ -11,7 +11,6 @@
 ----- disableRequestInterception -----
 Network.responseReceived i-dont-exist.css 404 text/html
 Network.loadingFailed i-dont-exist.css net::ERR_ABORTED
-Page.frameStoppedLoading
 Network.responseReceived post-echo.pl 200 text/plain
 Post - ECHO SUCCESS!
 
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/webbundle-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/webbundle-expected.txt
index 1941d13..daf1246 100644
--- a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/webbundle-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/network/webbundle-expected.txt
@@ -91,24 +91,20 @@
         wallTime : <number>
     }
 ]
-webBundleMetadataReceived[
-    [0] : {
-        requestId : <string>
-        urls : [
-            [0] : uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
-            [1] : uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae
-        ]
-    }
-]
-webBundleInnerResponse[
-    [0] : {
-        bundleRequestId : <string>
-        innerRequestId : <string>
-        innerRequestURL : uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
-    }
-]
-webBundleMetadataReceived[0].urls: uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720,uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae
-webBundleInnerResponse[0].innerRequestURL: uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
+webBundleMetadataReceived{
+    requestId : <string>
+    urls : [
+        [0] : uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
+        [1] : uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae
+    ]
+}
+webBundleInnerResponse{
+    bundleRequestId : <string>
+    innerRequestId : <string>
+    innerRequestURL : uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
+}
+webBundleMetadataReceived.urls: uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720,uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae
+webBundleInnerResponse.innerRequestURL: uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
 bundle request ID from webBundleMetadataReceived matches ID from requestWillBeSent
 inner request ID from webBundleInnerResponse matches ID from requestWillBeSent
 inner request ID from webBundleInnerResponse matches ID from webBundleMetadataReceived
diff --git a/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https-expected.txt
new file mode 100644
index 0000000..6d7b0ed9
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-soap.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL SAME_ORIGIN popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+FAIL SAME_SITE popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+FAIL CROSS_ORIGIN popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https-expected.txt
new file mode 100644
index 0000000..6d7b0ed9
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-u.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL SAME_ORIGIN popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+FAIL SAME_SITE popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+FAIL CROSS_ORIGIN popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https-expected.txt
new file mode 100644
index 0000000..6d7b0ed9
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/coop-restrict-properties/external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/popup-un.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL SAME_ORIGIN popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+FAIL SAME_SITE popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+FAIL CROSS_ORIGIN popup with coop restrict-properties assert_false: Popup is closed from opener? expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/element-instance-property-listing-expected.txt
index 845d9ab8..7bbbdaa 100644
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -568,8 +568,6 @@
     property method
     property name
     property noValidate
-    property rel
-    property relList
     property reportValidity
     property requestSubmit
     property reset
diff --git a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
index 3b386e9c..4443e25 100644
--- a/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -2995,8 +2995,6 @@
     getter method
     getter name
     getter noValidate
-    getter rel
-    getter relList
     getter target
     method @@iterator
     method checkValidity
@@ -3013,8 +3011,6 @@
     setter method
     setter name
     setter noValidate
-    setter rel
-    setter relList
     setter target
 interface HTMLFrameElement : HTMLElement
     attribute @@toStringTag
diff --git a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
index f43a291c..8731c50 100644
--- a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
@@ -8361,12 +8361,21 @@
     setter onchange
 interface ScreenDetailed : Screen
     attribute @@toStringTag
+    getter bluePrimaryX
+    getter bluePrimaryY
     getter devicePixelRatio
+    getter greenPrimaryX
+    getter greenPrimaryY
+    getter highDynamicRangeHeadroom
     getter isInternal
     getter isPrimary
     getter label
     getter left
+    getter redPrimaryX
+    getter redPrimaryY
     getter top
+    getter whitePointX
+    getter whitePointY
     method constructor
 interface ScreenDetails : EventTarget
     attribute @@toStringTag
diff --git a/third_party/blink/web_tests/platform/win7/css1/font_properties/font-expected.png b/third_party/blink/web_tests/platform/win7/css1/font_properties/font-expected.png
deleted file mode 100644
index 7bbd214..0000000
--- a/third_party/blink/web_tests/platform/win7/css1/font_properties/font-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css1/font_properties/font_variant-expected.png b/third_party/blink/web_tests/platform/win7/css1/font_properties/font_variant-expected.png
deleted file mode 100644
index 484e96ca..0000000
--- a/third_party/blink/web_tests/platform/win7/css1/font_properties/font_variant-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css1/pseudo/firstline-expected.png b/third_party/blink/web_tests/platform/win7/css1/pseudo/firstline-expected.png
deleted file mode 100644
index fc4fd055..0000000
--- a/third_party/blink/web_tests/platform/win7/css1/pseudo/firstline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/blink/web_tests/platform/win7/css1/pseudo/multiple_pseudo_elements-expected.png
deleted file mode 100644
index 1cc8b8ef..0000000
--- a/third_party/blink/web_tests/platform/win7/css1/pseudo/multiple_pseudo_elements-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t051201-c23-first-line-00-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t051201-c23-first-line-00-b-expected.png
deleted file mode 100644
index 73a6eac7..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t051201-c23-first-line-00-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t051202-c26-psudo-nest-00-c-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t051202-c26-psudo-nest-00-c-expected.png
deleted file mode 100644
index 64811097..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t051202-c26-psudo-nest-00-c-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t0905-c5525-fltwidth-00-c-g-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t0905-c5525-fltwidth-00-c-g-expected.png
deleted file mode 100644
index b677ee4..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t0905-c5525-fltwidth-00-c-g-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1202-counter-04-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1202-counter-04-b-expected.png
deleted file mode 100644
index a51f9ac..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1202-counter-04-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1202-counters-04-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1202-counters-04-b-expected.png
deleted file mode 100644
index 6074803..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1202-counters-04-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1505-c524-font-var-00-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1505-c524-font-var-00-b-expected.png
deleted file mode 100644
index bbc5ec3b..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1505-c524-font-var-00-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-00-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-00-b-expected.png
deleted file mode 100644
index d175880..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-00-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-04-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-04-b-expected.png
deleted file mode 100644
index 4f5ec8e6..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-04-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-05-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-05-b-expected.png
deleted file mode 100644
index 9e69e716..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-05-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-07-b-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-07-b-expected.png
deleted file mode 100644
index e2dd662..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-07-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-10-c-expected.png b/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-10-c-expected.png
deleted file mode 100644
index 14529e64..0000000
--- a/third_party/blink/web_tests/platform/win7/css2.1/t1508-c527-font-10-c-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/win7/custom-elements/form-validation-bubble-appearance-expected.png
deleted file mode 100644
index 2cb858f..0000000
--- a/third_party/blink/web_tests/platform/win7/custom-elements/form-validation-bubble-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.https-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.https-expected.txt
deleted file mode 100644
index cc6f1a4..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.https-expected.txt
+++ /dev/null
@@ -1,241 +0,0 @@
-This is a testharness.js-based test.
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using spki and RSA-OAEP
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap RSA-PSS public key keys using spki and RSA-OAEP
-PASS Can wrap and unwrap RSA-PSS public key keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap RSA-OAEP public key keys using spki and RSA-OAEP
-PASS Can wrap and unwrap RSA-OAEP public key keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap ECDSA public key keys using spki and RSA-OAEP
-PASS Can wrap and unwrap ECDSA public key keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap ECDSA private key keys using pkcs8 and RSA-OAEP
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using pkcs8 and RSA-OAEP
-PASS Can wrap and unwrap ECDSA private key keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using jwk and RSA-OAEP
-PASS Can unwrap ECDSA private key non-extractable keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap ECDH public key keys using spki and RSA-OAEP
-PASS Can wrap and unwrap ECDH public key keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap ECDH private key keys using pkcs8 and RSA-OAEP
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using pkcs8 and RSA-OAEP
-PASS Can wrap and unwrap ECDH private key keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using jwk and RSA-OAEP
-PASS Can unwrap ECDH private key non-extractable keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-CTR keys using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-CTR keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using jwk and RSA-OAEP
-PASS Can unwrap AES-CTR non-extractable keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-CBC keys using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-CBC keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using jwk and RSA-OAEP
-PASS Can unwrap AES-CBC non-extractable keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-GCM keys using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-GCM keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using jwk and RSA-OAEP
-PASS Can unwrap AES-GCM non-extractable keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-KW keys using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-KW keys as non-extractable using raw and RSA-OAEP
-PASS Can wrap and unwrap AES-KW keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap AES-KW keys as non-extractable using jwk and RSA-OAEP
-PASS Can unwrap AES-KW non-extractable keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap HMAC keys using raw and RSA-OAEP
-PASS Can wrap and unwrap HMAC keys as non-extractable using raw and RSA-OAEP
-PASS Can wrap and unwrap HMAC keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap HMAC keys as non-extractable using jwk and RSA-OAEP
-PASS Can unwrap HMAC non-extractable keys using jwk and RSA-OAEP
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using spki and AES-CTR
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys using pkcs8 and AES-CTR
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys as non-extractable using pkcs8 and AES-CTR
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap RSASSA-PKCS1-v1_5 private key non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSA-PSS public key keys using spki and AES-CTR
-PASS Can wrap and unwrap RSA-PSS public key keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSA-PSS private key keys using pkcs8 and AES-CTR
-PASS Can wrap and unwrap RSA-PSS private key keys as non-extractable using pkcs8 and AES-CTR
-PASS Can wrap and unwrap RSA-PSS private key keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSA-PSS private key keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap RSA-PSS private key non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSA-OAEP public key keys using spki and AES-CTR
-PASS Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSA-OAEP private key keys using pkcs8 and AES-CTR
-PASS Can wrap and unwrap RSA-OAEP private key keys as non-extractable using pkcs8 and AES-CTR
-PASS Can wrap and unwrap RSA-OAEP private key keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSA-OAEP private key keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap RSA-OAEP private key non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap ECDSA public key keys using spki and AES-CTR
-PASS Can wrap and unwrap ECDSA public key keys using jwk and AES-CTR
-PASS Can wrap and unwrap ECDSA private key keys using pkcs8 and AES-CTR
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using pkcs8 and AES-CTR
-PASS Can wrap and unwrap ECDSA private key keys using jwk and AES-CTR
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap ECDSA private key non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap ECDH public key keys using spki and AES-CTR
-PASS Can wrap and unwrap ECDH public key keys using jwk and AES-CTR
-PASS Can wrap and unwrap ECDH private key keys using pkcs8 and AES-CTR
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using pkcs8 and AES-CTR
-PASS Can wrap and unwrap ECDH private key keys using jwk and AES-CTR
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap ECDH private key non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-CTR keys using raw and AES-CTR
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using raw and AES-CTR
-PASS Can wrap and unwrap AES-CTR keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap AES-CTR non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-CBC keys using raw and AES-CTR
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using raw and AES-CTR
-PASS Can wrap and unwrap AES-CBC keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap AES-CBC non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-GCM keys using raw and AES-CTR
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using raw and AES-CTR
-PASS Can wrap and unwrap AES-GCM keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap AES-GCM non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-KW keys using raw and AES-CTR
-PASS Can wrap and unwrap AES-KW keys as non-extractable using raw and AES-CTR
-PASS Can wrap and unwrap AES-KW keys using jwk and AES-CTR
-PASS Can wrap and unwrap AES-KW keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap AES-KW non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap HMAC keys using raw and AES-CTR
-PASS Can wrap and unwrap HMAC keys as non-extractable using raw and AES-CTR
-PASS Can wrap and unwrap HMAC keys using jwk and AES-CTR
-PASS Can wrap and unwrap HMAC keys as non-extractable using jwk and AES-CTR
-PASS Can unwrap HMAC non-extractable keys using jwk and AES-CTR
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using spki and AES-CBC
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys using pkcs8 and AES-CBC
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys as non-extractable using pkcs8 and AES-CBC
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap RSASSA-PKCS1-v1_5 private key non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSA-PSS public key keys using spki and AES-CBC
-PASS Can wrap and unwrap RSA-PSS public key keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSA-PSS private key keys using pkcs8 and AES-CBC
-PASS Can wrap and unwrap RSA-PSS private key keys as non-extractable using pkcs8 and AES-CBC
-PASS Can wrap and unwrap RSA-PSS private key keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSA-PSS private key keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap RSA-PSS private key non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSA-OAEP public key keys using spki and AES-CBC
-PASS Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSA-OAEP private key keys using pkcs8 and AES-CBC
-PASS Can wrap and unwrap RSA-OAEP private key keys as non-extractable using pkcs8 and AES-CBC
-PASS Can wrap and unwrap RSA-OAEP private key keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSA-OAEP private key keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap RSA-OAEP private key non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap ECDSA public key keys using spki and AES-CBC
-PASS Can wrap and unwrap ECDSA public key keys using jwk and AES-CBC
-PASS Can wrap and unwrap ECDSA private key keys using pkcs8 and AES-CBC
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using pkcs8 and AES-CBC
-PASS Can wrap and unwrap ECDSA private key keys using jwk and AES-CBC
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap ECDSA private key non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap ECDH public key keys using spki and AES-CBC
-PASS Can wrap and unwrap ECDH public key keys using jwk and AES-CBC
-PASS Can wrap and unwrap ECDH private key keys using pkcs8 and AES-CBC
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using pkcs8 and AES-CBC
-PASS Can wrap and unwrap ECDH private key keys using jwk and AES-CBC
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap ECDH private key non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-CTR keys using raw and AES-CBC
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using raw and AES-CBC
-PASS Can wrap and unwrap AES-CTR keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap AES-CTR non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-CBC keys using raw and AES-CBC
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using raw and AES-CBC
-PASS Can wrap and unwrap AES-CBC keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap AES-CBC non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-GCM keys using raw and AES-CBC
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using raw and AES-CBC
-PASS Can wrap and unwrap AES-GCM keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap AES-GCM non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-KW keys using raw and AES-CBC
-PASS Can wrap and unwrap AES-KW keys as non-extractable using raw and AES-CBC
-PASS Can wrap and unwrap AES-KW keys using jwk and AES-CBC
-PASS Can wrap and unwrap AES-KW keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap AES-KW non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap HMAC keys using raw and AES-CBC
-PASS Can wrap and unwrap HMAC keys as non-extractable using raw and AES-CBC
-PASS Can wrap and unwrap HMAC keys using jwk and AES-CBC
-PASS Can wrap and unwrap HMAC keys as non-extractable using jwk and AES-CBC
-PASS Can unwrap HMAC non-extractable keys using jwk and AES-CBC
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using spki and AES-GCM
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys using pkcs8 and AES-GCM
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys as non-extractable using pkcs8 and AES-GCM
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 private key keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap RSASSA-PKCS1-v1_5 private key non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSA-PSS public key keys using spki and AES-GCM
-PASS Can wrap and unwrap RSA-PSS public key keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSA-PSS private key keys using pkcs8 and AES-GCM
-PASS Can wrap and unwrap RSA-PSS private key keys as non-extractable using pkcs8 and AES-GCM
-PASS Can wrap and unwrap RSA-PSS private key keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSA-PSS private key keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap RSA-PSS private key non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSA-OAEP public key keys using spki and AES-GCM
-PASS Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSA-OAEP private key keys using pkcs8 and AES-GCM
-PASS Can wrap and unwrap RSA-OAEP private key keys as non-extractable using pkcs8 and AES-GCM
-PASS Can wrap and unwrap RSA-OAEP private key keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSA-OAEP private key keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap RSA-OAEP private key non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap ECDSA public key keys using spki and AES-GCM
-PASS Can wrap and unwrap ECDSA public key keys using jwk and AES-GCM
-PASS Can wrap and unwrap ECDSA private key keys using pkcs8 and AES-GCM
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using pkcs8 and AES-GCM
-PASS Can wrap and unwrap ECDSA private key keys using jwk and AES-GCM
-PASS Can wrap and unwrap ECDSA private key keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap ECDSA private key non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap ECDH public key keys using spki and AES-GCM
-PASS Can wrap and unwrap ECDH public key keys using jwk and AES-GCM
-PASS Can wrap and unwrap ECDH private key keys using pkcs8 and AES-GCM
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using pkcs8 and AES-GCM
-PASS Can wrap and unwrap ECDH private key keys using jwk and AES-GCM
-PASS Can wrap and unwrap ECDH private key keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap ECDH private key non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-CTR keys using raw and AES-GCM
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using raw and AES-GCM
-PASS Can wrap and unwrap AES-CTR keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap AES-CTR non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-CBC keys using raw and AES-GCM
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using raw and AES-GCM
-PASS Can wrap and unwrap AES-CBC keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap AES-CBC non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-GCM keys using raw and AES-GCM
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using raw and AES-GCM
-PASS Can wrap and unwrap AES-GCM keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap AES-GCM non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-KW keys using raw and AES-GCM
-PASS Can wrap and unwrap AES-KW keys as non-extractable using raw and AES-GCM
-PASS Can wrap and unwrap AES-KW keys using jwk and AES-GCM
-PASS Can wrap and unwrap AES-KW keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap AES-KW non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap HMAC keys using raw and AES-GCM
-PASS Can wrap and unwrap HMAC keys as non-extractable using raw and AES-GCM
-PASS Can wrap and unwrap HMAC keys using jwk and AES-GCM
-PASS Can wrap and unwrap HMAC keys as non-extractable using jwk and AES-GCM
-PASS Can unwrap HMAC non-extractable keys using jwk and AES-GCM
-PASS Can wrap and unwrap RSASSA-PKCS1-v1_5 public key keys using jwk and AES-KW
-PASS Can wrap and unwrap RSA-PSS public key keys using jwk and AES-KW
-PASS Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-KW
-PASS Can wrap and unwrap AES-CTR keys using raw and AES-KW
-PASS Can wrap and unwrap AES-CTR keys as non-extractable using raw and AES-KW
-PASS Can wrap and unwrap AES-CBC keys using raw and AES-KW
-PASS Can wrap and unwrap AES-CBC keys as non-extractable using raw and AES-KW
-PASS Can wrap and unwrap AES-GCM keys using raw and AES-KW
-PASS Can wrap and unwrap AES-GCM keys as non-extractable using raw and AES-KW
-PASS Can wrap and unwrap AES-KW keys using raw and AES-KW
-PASS Can wrap and unwrap AES-KW keys as non-extractable using raw and AES-KW
-PASS Can wrap and unwrap HMAC keys using raw and AES-KW
-PASS Can wrap and unwrap HMAC keys as non-extractable using raw and AES-KW
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-masking/parsing/clip-path-shape-parsing-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-masking/parsing/clip-path-shape-parsing-expected.txt
deleted file mode 100644
index 6d0c32b1..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-masking/parsing/clip-path-shape-parsing-expected.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-This is a testharness.js-based test.
-FAIL e.style['clip-path'] = "shape(from 0px 0px, line to 10px 10px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(evenodd from 0px 0px, line to 10px 10px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(nonzero from 0px 0px, line to 10px 10px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(  from 0px    0px, line  to 10px  10px     )" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 1em 50%, line to 10px 10px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(EvenOdd from 0px 0Px, CLOSE)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 1ch 50px, line to 10rem 10vh)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 1ch -50px, line to -10% 12px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, move by 10px 5px, line by 20px 40%, close)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, hline by 10px, vline to 5rem)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, vline by 5%, hline to 1vw)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, curve to 50px 20px via 10rem 1%)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, curve to 50px 20px via 10rem 1px 20vh 1ch)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, curve by 50px 20px via 10rem 1px 20vh 1ch)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, smooth to 50px 20px via 10rem 1%)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, smooth to 50px 1pt)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['clip-path'] = "shape(evenodd from 0px 0px, close)" should set the property value assert_not_equals: property should be set got disallowed value ""
-PASS e.style['clip-path'] = "shape(evenodd from 0px 0px, close path)" should not set the property value
-PASS e.style['clip-path'] = "shape(nonzero, from 0px 0px, line to 10px 10px)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 10px 10px, curve to 50px 20px via 10rem)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 10px 10px, curve to 50px 20px via 10rem 1% 12px)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 10px 10px, hline byy 10px, vline to 5rem)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 10px 10px, vline by 5% hline by 1vw" should not set the property value
-PASS e.style['clip-path'] = "shape(from 10px 10px, smooth to 50px 20px via 10rem)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 10px 10px, smooth to 50px 20px via 10rem 2px 2pt)" should not set the property value
-PASS e.style['clip-path'] = "shape()" should not set the property value
-PASS e.style['clip-path'] = "shape(from)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 0px)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 0px 20px,)" should not set the property value
-PASS e.style['clip-path'] = "shape(close)" should not set the property value
-PASS e.style['clip-path'] = "shape(nonzero, close)" should not set the property value
-PASS e.style['clip-path'] = "shape(from 0px 10px)" should not set the property value
-PASS e.style['clip-path'] = "shape(allkindsofnonsense)" should not set the property value
-PASS e.style['clip-path'] = "shape(arc)" should not set the property value
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text-decor/text-decoration-width-computed-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text-decor/text-decoration-width-computed-expected.txt
deleted file mode 100644
index 03ec802..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text-decor/text-decoration-width-computed-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL Property text-decoration-width value 'auto' computes to 'auto' assert_true: text-decoration-width doesn't seem to be supported in the computed style expected true got false
-FAIL Property text-decoration-width value 'from-font' computes to 'from-font' assert_true: text-decoration-width doesn't seem to be supported in the computed style expected true got false
-FAIL Property text-decoration-width value 'calc(10px - 8px)' computes to '2px' assert_true: text-decoration-width doesn't seem to be supported in the computed style expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text-decor/text-decoration-width-valid-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text-decor/text-decoration-width-valid-expected.txt
deleted file mode 100644
index 09b05db..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text-decor/text-decoration-width-valid-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL e.style['text-decoration-width'] = "auto" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['text-decoration-width'] = "from-font" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['text-decoration-width'] = "-10px" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['text-decoration-width'] = "2001em" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['text-decoration-width'] = "-49em" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['text-decoration-width'] = "53px" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['text-decoration-width'] = "calc(40em - 10px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['text-decoration-width'] = "calc(-50em + 13px)" should set the property value assert_not_equals: property should be set got disallowed value ""
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt
deleted file mode 100644
index a9b7884..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/dom/events/scrolling/scrollend-event-for-user-scroll-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL Tests that the target_div gets scrollend event when dragging scroll on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging scroll on target."
-FAIL Tests that the target_div gets scrollend event when click scrollbar on target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after clicking scrollbar on target."
-FAIL Tests that the target_div gets scrollend event when drag the thumb of target. promise_test: Unhandled rejection with value: "target_div did not receive scrollend event after dragging the thumb of target."
-PASS Tests that the target_div gets scrollend event when send DOWN key to target.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/editing/run/forwarddelete_6001-last-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/editing/run/forwarddelete_6001-last-expected.txt
deleted file mode 100644
index 1e730970..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/editing/run/forwarddelete_6001-last-expected.txt
+++ /dev/null
@@ -1,674 +0,0 @@
-This is a testharness.js-based test.
-Found 670 tests; 632 PASS, 38 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL [["forwarddelete",""]] "<ol><li>foo[<li>]bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foobar</li></ol>" but got "<ol><li>foo</li><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>]bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>]bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>]bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>]bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>]bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>]bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" compare innerHTML
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[<dl><dt>]bar<dd>baz</dl>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" compare innerHTML
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[<dl><dd>]bar</dl>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" compare innerHTML
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dd>]bar</dl>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" compare innerHTML
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo[<dt>]bar<dd>baz</dl>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" compare innerHTML
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<dl><dt>foo<dd>bar[<dd>]baz</dl>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol>bar" but got "<ol><li>foo</li></ol><ol><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol><p>bar</p>" but got "<ol><li>foo</li></ol><ol><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li><p>foo</p></li></ol><p>bar</p>" but got "<ol><li><p>foo</p></li></ol><ol><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol id=\"a\"><li>foo</li></ol>bar" but got "<ol id=\"a\"><li>foo</li></ol><ol><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol>bar" but got "<ol><li>foo</li></ol><ol id=\"b\"><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol id=\"a\"><li>foo</li></ol>bar" but got "<ol id=\"a\"><li>foo</li></ol><ol id=\"b\"><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol class=\"a\"><li>foo</li></ol>bar" but got "<ol class=\"a\"><li>foo</li></ol><ol class=\"b\"><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><ol><li>foo</li></ol><li>bar</li></ol>" but got "<ol><ol><li>foo</li></ol><li><ol><li>bar</li></ol></li></ol>"
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><ol><li>foo</li></ol><li>bar</li></ol>" but got "<ol><ol><li>foo</li></ol><ol><li>bar</li></ol></ol>"
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li><li>baz</li></ol>" but got "<ol><li>foo</li></ol><ol><li>baz</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[</ol>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("defaultparagraphseparator", false, "div") return value
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li><li>baz</li></ol>" but got "<ol><li>foo</li></ol><ol><li>baz</li></ol>"
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") before
-FAIL [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") before assert_equals: Wrong result returned expected "p" but got "div"
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("defaultparagraphseparator", false, "p") return value
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li><li>baz</li></ol>" but got "<ol><li>foo</li></ol><ol><li>baz</li></ol>"
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("defaultparagraphseparator", false, "div") return value
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li><p>foo</p></li><li>baz</li></ol>" but got "<ol><li><p>foo</p></li></ol><ol><li>baz</li></ol>"
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("defaultparagraphseparator", false, "p") return value
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li><p>foo</p></li><li>baz</li></ol>" but got "<ol><li><p>foo</p></li></ol><ol><li>baz</li></ol>"
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandState("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" compare innerHTML
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>fo[]o</ol><ol><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol>baz" but got "<ol><li>foo</li></ol><ol><li>baz</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>[bar<ol><li>]baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol><p>baz</p>" but got "<ol><li>foo</li></ol><ol><li>baz</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>": execCommand("defaultparagraphseparator", false, "div") return value
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol><p>baz</p>" but got "<ol><li>foo</li></ol><ol><li><p>baz</p></li></ol>"
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("forwarddelete") after
-PASS [["defaultparagraphseparator","div"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>": execCommand("defaultparagraphseparator", false, "p") return value
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol><p>baz</p>" but got "<ol><li>foo</li></ol><ol><li><p>baz</p></li></ol>"
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("defaultparagraphseparator") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("defaultparagraphseparator") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("forwarddelete") before
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandState("forwarddelete") after
-PASS [["defaultparagraphseparator","p"],["forwarddelete",""]] "<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" compare innerHTML
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><ol><li>[]bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><ol><li>foo</li></ol><li>quz</li></ol>" but got "<ol><ol><li>foo</li></ol></ol><ol><li>quz</li></ol>"
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ul><li>foo</li></ul>bar" but got "<ul><li>foo</li></ul><ul><li>bar</li></ul>"
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ul><li>bar</ul>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ul><li>foo</li></ul><p>bar</p>" but got "<ul><li>foo</li></ul><ul><li>bar</li></ul>"
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li><li>baz</li><li>quz</li></ol>" but got "<ol><li>foo</li></ol><ol><li>baz</li></ol><ol><li>quz</li></ol>"
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol>bar" but got "<ol><li>foo</li></ol><ul><li>bar</li></ul>"
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol>{}<br><ul><li>bar</ul>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ol><li>foo</li></ol><p>bar</p>" but got "<ol><li>foo</li></ol><ul><li>bar</li></ul>"
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ul><li>foo</li></ul>bar" but got "<ul><li>foo</li></ul><ol><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul>{}<br><ol><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<ul><li>foo</li></ul><p>bar</p>" but got "<ul><li>foo</li></ul><ol><li>bar</li></ol>"
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<p><b>[foo]</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>[foo]</b>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><quasit><br></quasit></p>" but got "<p><br></p>"
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><quasit>[foo]</quasit>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><i><br></i></b></p>" but got "<p><br></p>"
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b><i>[foo]</i></b>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<p><b>{foo}</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>{foo}</b>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<p>{<b>foo</b>}" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p>{<b>foo</b>}" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>[]f</b>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p><b>[]f</b>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<p><b>[]f</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
-PASS [["forwarddelete",""]] "<p><b>[]f</b>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>[]f</b>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>[]f</b>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><b>[]f</b>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>[]f</b>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><b>[]f</b>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<b>[foo]</b>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<b>[foo]</b>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<b>[foo]</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<b><br></b>" but got "<br>"
-PASS [["forwarddelete",""]] "<b>[foo]</b>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<b>[foo]</b>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<b>[foo]</b>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<b>[foo]</b>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<b>[foo]</b>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<b>[foo]</b>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "<div><b>[foo]</b></div>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div><b><br></b></div>" but got "<br>"
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div><b>[foo]</b></div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><div></div><div>bar</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><span></span><div>bar</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>foo[]</div><!-- comment --><div>bar</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>ab[]c </div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>ab[]c </div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>ab[]c  </div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc[] </div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc[] </div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc[] </div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc [] </div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc [] </div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc [] </div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div><div>def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]  </div><div>def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]</div><div> def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]</div><div>  def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[] </div><div> def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc [] </div><div>  def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" compare innerHTML
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<div>abc[]  </div> <div>  def</div>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foobar" but got "foo<img contenteditable=\"false\" src=\"/img/lion.svg\">bar"
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<img contenteditable=false src=/img/lion.svg>bar" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" compare innerHTML
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span>baz" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" compare innerHTML
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" compare innerHTML
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" compare innerHTML
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<div contenteditable=false>bar</div>baz" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" compare innerHTML
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo[]<span contenteditable=false><b>bar</b></span>baz" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" checks for modifications to non-editable content
-FAIL [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<span>bar</span>qux" but got "foo<span>bar</span>ux"
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "foo<span>bar[]<span contenteditable=false>baz</span></span>qux" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<span>[abc]</span>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<span>[abc]</span>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<span>[abc]</span>" compare innerHTML
-PASS [["forwarddelete",""]] "<span>[abc]</span>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<span>[abc]</span>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<span>[abc]</span>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<span>[abc]</span>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<span>[abc]</span>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<span>[abc]</span>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" compare innerHTML
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<span>[abc]</span><br>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" compare innerHTML
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><span>[abc]</span></p>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" compare innerHTML
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p><span>[abc]</span><br></p>" queryCommandValue("forwarddelete") after
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>": execCommand("forwarddelete", false, "") return value
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" checks for modifications to non-editable content
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" compare innerHTML
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandIndeterm("forwarddelete") before
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandState("forwarddelete") before
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandValue("forwarddelete") before
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandIndeterm("forwarddelete") after
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandState("forwarddelete") after
-PASS [["forwarddelete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandValue("forwarddelete") after
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative-expected.txt
deleted file mode 100644
index 4c79453..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS same-site_unsafe-allow-outgoing document opening popup to http://web-platform.test:8001 with COOP: ""
-PASS same-site_unsafe-allow-outgoing document opening popup to http://web-platform.test:8001 with COOP: "jibberish"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://web-platform.test:8001 with COOP: "same-site" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_SAME_ORIGIN_same-site"
-PASS same-site_unsafe-allow-outgoing document opening popup to http://web-platform.test:8001 with COOP: "same-site unsafe-allow-outgoing"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://web-platform.test:8001 with COOP: "same-origin" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_SAME_ORIGIN_same-origin"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://web-platform.test:8001 with COOP: "same-origin unsafe-allow-outgoing" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_SAME_ORIGIN_same-origin-unsafe-allow-outgoing"
-PASS same-site_unsafe-allow-outgoing document opening popup to http://www1.web-platform.test:8001 with COOP: ""
-PASS same-site_unsafe-allow-outgoing document opening popup to http://www1.web-platform.test:8001 with COOP: "jibberish"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://www1.web-platform.test:8001 with COOP: "same-site" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_SAME_SITE_same-site"
-PASS same-site_unsafe-allow-outgoing document opening popup to http://www1.web-platform.test:8001 with COOP: "same-site unsafe-allow-outgoing"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://www1.web-platform.test:8001 with COOP: "same-origin" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_SAME_SITE_same-origin"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://www1.web-platform.test:8001 with COOP: "same-origin unsafe-allow-outgoing" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_SAME_SITE_same-origin-unsafe-allow-outgoing"
-PASS same-site_unsafe-allow-outgoing document opening popup to http://not-web-platform.test:8001 with COOP: ""
-PASS same-site_unsafe-allow-outgoing document opening popup to http://not-web-platform.test:8001 with COOP: "jibberish"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://not-web-platform.test:8001 with COOP: "same-site" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_CROSS_ORIGIN_same-site"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://not-web-platform.test:8001 with COOP: "same-site unsafe-allow-outgoing" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_CROSS_ORIGIN_same-site-unsafe-allow-outgoing"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://not-web-platform.test:8001 with COOP: "same-origin" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_CROSS_ORIGIN_same-origin"
-FAIL same-site_unsafe-allow-outgoing document opening popup to http://not-web-platform.test:8001 with COOP: "same-origin unsafe-allow-outgoing" assert_equals: expected "" but got "same-site_unsafe-allow-outgoing_to_CROSS_ORIGIN_same-origin-unsafe-allow-outgoing"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/NavigatorID-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/NavigatorID-expected.txt
deleted file mode 100644
index d9f302c..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/NavigatorID-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-PASS appCodeName
-PASS appName
-PASS appVersion
-PASS platform
-PASS product
-PASS productSub
-PASS userAgent type
-FAIL userAgent value assert_equals: userAgent should return the value sent in the User-Agent header expected "{\"error\": {\"message\": \"\", \"code\": 404}}" but got "user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/999.77.34.5 Safari/537.36\n"
-PASS vendor
-PASS vendorSub
-PASS taintEnabled
-PASS oscpu
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https-expected.txt
deleted file mode 100644
index c4f0add2..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL enumerateDevices has stable deviceIds across same-origin iframe assert_true: deviceIds stay the same when loaded in same origin expected true got false
-PASS enumerateDevices rotates deviceId across different-origin iframe
-FAIL enumerateDevices rotates deviceId after clearing site data assert_false: deviceIds are not kept after clearing site data expected false got true
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/paint-timing/fcp-only/fcp-document-opacity-image-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/paint-timing/fcp-only/fcp-document-opacity-image-expected.txt
deleted file mode 100644
index cb851db07..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/paint-timing/fcp-only/fcp-document-opacity-image-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test that FCP after opacity change is not a larger value than LCP assert_less_than_equal: LCP is not smaller than FCP expected a number less than or equal to 23.7 but got 23.700000001117587
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/selection/contenteditable/initial-selection-on-focus.tentative_div-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/selection/contenteditable/initial-selection-on-focus.tentative_div-expected.txt
deleted file mode 100644
index 9d7c828..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/selection/contenteditable/initial-selection-on-focus.tentative_div-expected.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-This is a testharness.js-based test.
-Found 98 tests; 94 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS empty editor should set focus to start of it
-PASS editor should set selection to start of the text node
-PASS editor should set selection to before the <br> node
-PASS editor should set selection to before the first <br> node
-PASS editor should set selection to start of the text node in the <p> node
-PASS editor should set selection to start of the first visible character in the text node in the <p> node
-PASS editor should set selection to start of the text node in the <p> node because of preformatted white-space
-PASS editor should set selection to start of the text node in the <p> node because of preformatted line break
-PASS editor should set selection to before the <br> node in the <p> node
-PASS editor should set selection to before the first <br> node in the <p> node
-PASS editor should set selection to start of the text node in the <span> node
-PASS editor should set selection to before the <br> node in the <span> node
-PASS editor should set selection to before the first <br> node in the <span> node
-PASS editor should set selection to before the empty <span> node
-PASS editor should set selection to before the empty <b> node
-PASS editor should set selection to before the empty <i> node
-PASS editor should set selection to before the empty <u> node
-PASS editor should set selection to before the empty <s> node
-PASS editor should set selection to before the empty <code> node
-PASS editor should set selection to before the empty <a> node
-PASS editor should set selection to before the empty <foobar> node
-PASS editor should set selection to before the <input> node
-PASS editor should set selection to before the <img> node
-PASS editor should set selection to start of the text node in the second <span> node
-PASS editor should set selection to before the <br> node in the second <span> node
-PASS editor should set selection to start of the text node in the first <span> node #1
-PASS editor should set selection to start of the text node in the first <span> node #2
-PASS editor should set selection to before the <br> node in the first <span> node #1
-PASS editor should set selection to before the <br> node in the first <span> node #2
-PASS editor should set selection to start of the text node in the second <span> node since the text node in the first <span> node is only whitespaces
-PASS editor should set selection to before the <br> node in the second <span> node since the text node in the first <span> node is only whitespaces
-PASS editor should set selection to start of the text node in the second <span> node even if there is a whitespace only text node before the first <span> node
-PASS editor should set selection to before the <br> node in the second <span> node even if there is a whitespace only text node before the first <span> node
-PASS editor should set selection to start of the text node in the second <p> node following the empty <p> node
-PASS editor should set selection to start of the text node in the second <p> node following another <p> node containing only a comment node
-PASS editor should set selection to before the <br> node in the second <p> node
-PASS editor should set selection to start of the text node in the first <p> node #1
-PASS editor should set selection to start of the text node in the first <p> node #2
-PASS editor should set selection to before the <br> node in the first <p> node #1
-PASS editor should set selection to before the <br> node in the first <p> node #2
-PASS editor should set selection to start of the text node in the second <p> node since the text node in the first <p> node is only whitespaces
-PASS editor should set selection to start of the text node in the first <p> node whose white-spaces are preformatted
-PASS editor should set selection to start of the text node in the first <p> node whose line breaks are preformatted
-PASS editor should set selection to before the <br> node in the second <p> node since the text node in the first <p> node is only whitespaces
-PASS editor should set selection to start of the text node in the second <p> node even if there is a whitespace only text node before the first <p> node
-PASS editor should set selection to before the <br> node in the second <p> node even if there is a whitespace only text node before the first <p> node
-PASS editor should set selection to start of the text node in the <span> node in the second <p> node
-PASS editor should set selection to before the <br> node in the <span> node in the second <p> node
-PASS editor should set selection to start of the text node in the <span> node in the first <p> node #1
-PASS editor should set selection to start of the text node in the <span> node in the first <p> node #2
-PASS editor should set selection to before the <br> node in the <span> node in the first <p> node #1
-PASS editor should set selection to before the <br> node in the <span> node in the first <p> node #2
-PASS editor should collapse selection before the non-editable <span> node
-PASS editor should collapse selection before the non-editable <span> node even if it has a text node
-PASS editor should collapse selection before the non-editable <span> node even if it has a <br> node
-PASS editor should collapse selection before the non-editable empty <span> node followed by a text node
-PASS editor should collapse selection before the non-editable <span> node having a text node and followed by another text node
-PASS editor should collapse selection before the non-editable <span> node having a <br> node and followed by a text node
-PASS editor should collapse selection before the non-editable empty <span> node followed by a <br> node
-PASS editor should collapse selection before the non-editable <span> node having text node and followed by a <br> node
-PASS editor should collapse selection before the non-editable <span> node having a <br> node and followed by another <br> node
-PASS editor should collapse selection before the non-editable empty <p> node followed by a text node
-FAIL editor should collapse selection before the non-editable <p> node having a text node and followed by another text node assert_equals: Only one caret should be in the editor expected 1 but got 0
-FAIL editor should collapse selection before the non-editable <p> node having a <br> node and followed by a text node assert_equals: Only one caret should be in the editor expected 1 but got 0
-PASS editor should collapse selection before the non-editable empty <p> node followed by a <br> node
-FAIL editor should collapse selection before the non-editable <p> node having text node and followed by a <br> node assert_equals: Only one caret should be in the editor expected 1 but got 0
-FAIL editor should collapse selection before the non-editable <p> node having a <br> node and followed by another <br> node assert_equals: Only one caret should be in the editor expected 1 but got 0
-PASS editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node before first editable text node
-PASS editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a text node before first editable text node
-PASS editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a <br> node before first editable text node
-PASS editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node before first editable <br> node
-PASS editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a text node before first editable <br> node
-PASS editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a <br> node before first editable <br> node
-PASS editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node before first editable text node
-PASS editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a text node before first editable text node
-PASS editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a <br> node before first editable text node
-PASS editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node before first editable <br> node
-PASS editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a text node before first editable <br> node
-PASS editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a <br> node before first editable <br> node
-PASS editor should collapse selection to the first editable text node in the first <span> node even if followed by a non-editable node
-PASS editor should collapse selection to the first editable text node in the first <span> node even if followed by a non-editable node having another text node
-PASS editor should collapse selection to the first editable text node in the first <span> node even if followed by a non-editable node having a <br> node
-PASS editor should collapse selection to the first editable <br> node in the first <span> node even if followed by a non-editable node
-PASS editor should collapse selection to the first editable <br> node in the first <span> node even if followed by a non-editable node having a text node
-PASS editor should collapse selection to the first editable <br> node in the first <span> node even if followed by a non-editable node having a <br> node
-PASS editor should collapse selection to the first editable text node in the first <p> node even if followed by a non-editable node
-PASS editor should collapse selection to the first editable text node in the first <p> node even if followed by a non-editable node having another text node
-PASS editor should collapse selection to the first editable text node in the first <p> node even if followed by a non-editable node having a <br> node
-PASS editor should collapse selection to the first editable <br> node in the first <p> node even if followed by a non-editable node
-PASS editor should collapse selection to the first editable <br> node in the first <p> node even if followed by a non-editable node having a text node
-PASS editor should collapse selection to the first editable <br> node in the first <p> node even if followed by a non-editable node having a <br> node
-PASS editor should collapse selection to start of itself if first content is an input element
-PASS editor should collapse selection to start of itself if first content is an hr element
-PASS editor should collapse selection to start of itself if first content is an textarea element
-PASS editor should collapse selection to the input element
-PASS editor should collapse selection to the hr element
-PASS editor should collapse selection to the textarea element
-PASS editor shouldn't reset selection when it gets focus again
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index f8bae45b7..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634044577107.8 but got 1634044577107.5
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/wasm/jsapi/exception/basic.tentative.any-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/wasm/jsapi/exception/basic.tentative.any-expected.txt
deleted file mode 100644
index 73f209a..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/wasm/jsapi/exception/basic.tentative.any-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Wasm function throws argument promise_test: Unhandled rejection with value: object "CompileError: WebAssembly.instantiate(): invalid value type 'externref', enable with --experimental-wasm-reftypes @+13"
-FAIL Wasm function throws null promise_test: Unhandled rejection with value: object "CompileError: WebAssembly.instantiate(): invalid value type 'funcref', enable with --experimental-wasm-reftypes @+13"
-FAIL Wasm function throws integer assert_true: Error should be a WebAssembly.Exception with undefined expected true got false
-FAIL Imported JS function throws promise_test: Unhandled rejection with value: object "CompileError: WebAssembly.instantiate(): invalid value type 'externref', enable with --experimental-wasm-reftypes @+16"
-FAIL Imported JS function throws, Wasm catches and rethrows promise_test: Unhandled rejection with value: object "CompileError: WebAssembly.instantiate(): invalid value type 'externref', enable with --experimental-wasm-reftypes @+17"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/processing-after-resume.https-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/processing-after-resume.https-expected.txt
deleted file mode 100644
index a510e1da..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/processing-after-resume.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test consistency of processing after resume() assert_equals: construct time before resume expected 0.029024943310657598 but got 0
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt
deleted file mode 100644
index d0960ed..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-PASS Element Source tests completed
-PASS Channel 0 processed some data
-FAIL All data processed correctly assert_array_approx_equals: comparing expected and rendered buffers (channel 0) lengths differ, expected 44098 got 43970
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
deleted file mode 100644
index 09e47e3..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-This is a testharness.js-based test.
-Found 78 tests; 77 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL Basic check assert_unreached: Reached unreachable code
-PASS WebSocket blocked port test 1
-PASS WebSocket blocked port test 7
-PASS WebSocket blocked port test 9
-PASS WebSocket blocked port test 11
-PASS WebSocket blocked port test 13
-PASS WebSocket blocked port test 15
-PASS WebSocket blocked port test 17
-PASS WebSocket blocked port test 19
-PASS WebSocket blocked port test 20
-PASS WebSocket blocked port test 21
-PASS WebSocket blocked port test 22
-PASS WebSocket blocked port test 23
-PASS WebSocket blocked port test 25
-PASS WebSocket blocked port test 37
-PASS WebSocket blocked port test 42
-PASS WebSocket blocked port test 43
-PASS WebSocket blocked port test 53
-PASS WebSocket blocked port test 69
-PASS WebSocket blocked port test 77
-PASS WebSocket blocked port test 79
-PASS WebSocket blocked port test 87
-PASS WebSocket blocked port test 95
-PASS WebSocket blocked port test 101
-PASS WebSocket blocked port test 102
-PASS WebSocket blocked port test 103
-PASS WebSocket blocked port test 104
-PASS WebSocket blocked port test 109
-PASS WebSocket blocked port test 110
-PASS WebSocket blocked port test 111
-PASS WebSocket blocked port test 113
-PASS WebSocket blocked port test 115
-PASS WebSocket blocked port test 117
-PASS WebSocket blocked port test 119
-PASS WebSocket blocked port test 123
-PASS WebSocket blocked port test 135
-PASS WebSocket blocked port test 137
-PASS WebSocket blocked port test 139
-PASS WebSocket blocked port test 143
-PASS WebSocket blocked port test 179
-PASS WebSocket blocked port test 389
-PASS WebSocket blocked port test 427
-PASS WebSocket blocked port test 465
-PASS WebSocket blocked port test 512
-PASS WebSocket blocked port test 513
-PASS WebSocket blocked port test 514
-PASS WebSocket blocked port test 515
-PASS WebSocket blocked port test 526
-PASS WebSocket blocked port test 530
-PASS WebSocket blocked port test 531
-PASS WebSocket blocked port test 532
-PASS WebSocket blocked port test 540
-PASS WebSocket blocked port test 548
-PASS WebSocket blocked port test 554
-PASS WebSocket blocked port test 556
-PASS WebSocket blocked port test 563
-PASS WebSocket blocked port test 587
-PASS WebSocket blocked port test 601
-PASS WebSocket blocked port test 636
-PASS WebSocket blocked port test 989
-PASS WebSocket blocked port test 990
-PASS WebSocket blocked port test 993
-PASS WebSocket blocked port test 995
-PASS WebSocket blocked port test 1719
-PASS WebSocket blocked port test 1720
-PASS WebSocket blocked port test 1723
-PASS WebSocket blocked port test 2049
-PASS WebSocket blocked port test 3659
-PASS WebSocket blocked port test 4045
-PASS WebSocket blocked port test 6000
-PASS WebSocket blocked port test 6566
-PASS WebSocket blocked port test 6665
-PASS WebSocket blocked port test 6666
-PASS WebSocket blocked port test 6667
-PASS WebSocket blocked port test 6668
-PASS WebSocket blocked port test 6669
-PASS WebSocket blocked port test 6697
-PASS WebSocket blocked port test 10080
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
deleted file mode 100644
index 09e47e3..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-This is a testharness.js-based test.
-Found 78 tests; 77 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL Basic check assert_unreached: Reached unreachable code
-PASS WebSocket blocked port test 1
-PASS WebSocket blocked port test 7
-PASS WebSocket blocked port test 9
-PASS WebSocket blocked port test 11
-PASS WebSocket blocked port test 13
-PASS WebSocket blocked port test 15
-PASS WebSocket blocked port test 17
-PASS WebSocket blocked port test 19
-PASS WebSocket blocked port test 20
-PASS WebSocket blocked port test 21
-PASS WebSocket blocked port test 22
-PASS WebSocket blocked port test 23
-PASS WebSocket blocked port test 25
-PASS WebSocket blocked port test 37
-PASS WebSocket blocked port test 42
-PASS WebSocket blocked port test 43
-PASS WebSocket blocked port test 53
-PASS WebSocket blocked port test 69
-PASS WebSocket blocked port test 77
-PASS WebSocket blocked port test 79
-PASS WebSocket blocked port test 87
-PASS WebSocket blocked port test 95
-PASS WebSocket blocked port test 101
-PASS WebSocket blocked port test 102
-PASS WebSocket blocked port test 103
-PASS WebSocket blocked port test 104
-PASS WebSocket blocked port test 109
-PASS WebSocket blocked port test 110
-PASS WebSocket blocked port test 111
-PASS WebSocket blocked port test 113
-PASS WebSocket blocked port test 115
-PASS WebSocket blocked port test 117
-PASS WebSocket blocked port test 119
-PASS WebSocket blocked port test 123
-PASS WebSocket blocked port test 135
-PASS WebSocket blocked port test 137
-PASS WebSocket blocked port test 139
-PASS WebSocket blocked port test 143
-PASS WebSocket blocked port test 179
-PASS WebSocket blocked port test 389
-PASS WebSocket blocked port test 427
-PASS WebSocket blocked port test 465
-PASS WebSocket blocked port test 512
-PASS WebSocket blocked port test 513
-PASS WebSocket blocked port test 514
-PASS WebSocket blocked port test 515
-PASS WebSocket blocked port test 526
-PASS WebSocket blocked port test 530
-PASS WebSocket blocked port test 531
-PASS WebSocket blocked port test 532
-PASS WebSocket blocked port test 540
-PASS WebSocket blocked port test 548
-PASS WebSocket blocked port test 554
-PASS WebSocket blocked port test 556
-PASS WebSocket blocked port test 563
-PASS WebSocket blocked port test 587
-PASS WebSocket blocked port test 601
-PASS WebSocket blocked port test 636
-PASS WebSocket blocked port test 989
-PASS WebSocket blocked port test 990
-PASS WebSocket blocked port test 993
-PASS WebSocket blocked port test 995
-PASS WebSocket blocked port test 1719
-PASS WebSocket blocked port test 1720
-PASS WebSocket blocked port test 1723
-PASS WebSocket blocked port test 2049
-PASS WebSocket blocked port test 3659
-PASS WebSocket blocked port test 4045
-PASS WebSocket blocked port test 6000
-PASS WebSocket blocked port test 6566
-PASS WebSocket blocked port test 6665
-PASS WebSocket blocked port test 6666
-PASS WebSocket blocked port test 6667
-PASS WebSocket blocked port test 6668
-PASS WebSocket blocked port test 6669
-PASS WebSocket blocked port test 6697
-PASS WebSocket blocked port test 10080
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt
deleted file mode 100644
index e69de29..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt
+++ /dev/null
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker-expected.txt
deleted file mode 100644
index f3a694c..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-PASS Blob URLs work on importScripts
-PASS A revoked blob URL will fail
-FAIL Revoking a blob URL in an earlier script will not fail Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'blob:http://web-platform.test:8001/f0d06419-92c1-4f5b-b9b0-291dd3706b4f' failed to load.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/fast/block/basic/minheight-expected.png b/third_party/blink/web_tests/platform/win7/fast/block/basic/minheight-expected.png
deleted file mode 100644
index 736ddb5..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/block/basic/minheight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/block/positioning/047-expected.png b/third_party/blink/web_tests/platform/win7/fast/block/positioning/047-expected.png
deleted file mode 100644
index 19feb35..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/block/positioning/047-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/css/font-weight-1-expected.png b/third_party/blink/web_tests/platform/win7/fast/css/font-weight-1-expected.png
deleted file mode 100644
index 71808cf99..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/css/font-weight-1-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/css/invalidation-errors-2-expected.png b/third_party/blink/web_tests/platform/win7/fast/css/invalidation-errors-2-expected.png
deleted file mode 100644
index c8e2b7e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/css/invalidation-errors-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/css/invalidation-errors-expected.png b/third_party/blink/web_tests/platform/win7/fast/css/invalidation-errors-expected.png
deleted file mode 100644
index c8e2b7e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/css/invalidation-errors-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-cjk-expected.png b/third_party/blink/web_tests/platform/win7/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-cjk-expected.png
deleted file mode 100644
index 7f7337b..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-cjk-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/dynamic/text-combine-expected.png b/third_party/blink/web_tests/platform/win7/fast/dynamic/text-combine-expected.png
deleted file mode 100644
index ab21af1..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/dynamic/text-combine-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
deleted file mode 100644
index dbb8173..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
deleted file mode 100644
index ae8473c0..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
deleted file mode 100644
index ae8473c0..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
deleted file mode 100644
index 2cfe02a..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
deleted file mode 100644
index 447df706..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
deleted file mode 100644
index 33f746a..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
deleted file mode 100644
index ece6c807..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
deleted file mode 100644
index e0e3232..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-coarse-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-coarse-expected.png
deleted file mode 100644
index ae8473c0..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-coarse-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-disabled-previous-month-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-disabled-previous-month-expected.png
deleted file mode 100644
index 673f861..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-disabled-previous-month-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-rtl-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-rtl-expected.png
deleted file mode 100644
index dbb8173..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-step-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-step-expected.png
deleted file mode 100644
index e7f4454..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-appearance-step-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-month-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-month-appearance-expected.png
deleted file mode 100644
index bf3e50c..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-month-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-month-selection-changed-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-month-selection-changed-appearance-expected.png
deleted file mode 100644
index b3d9d70..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/date-picker-month-selection-changed-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png
deleted file mode 100644
index 95ffe47..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
deleted file mode 100644
index 230975b1..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png
deleted file mode 100644
index 6712aacf..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
deleted file mode 100644
index 30cbb4b..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png
deleted file mode 100644
index ae8473c0..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png
deleted file mode 100644
index 32da780..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png
deleted file mode 100644
index 4dec388..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
deleted file mode 100644
index b0600727d..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png
deleted file mode 100644
index 2a2fa242..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png
deleted file mode 100644
index 39b5172..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png
deleted file mode 100644
index 6f12b349..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month/month-appearance-basic-expected.png
deleted file mode 100644
index 8ee78ff..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/search/search-appearance-basic-expected.png
deleted file mode 100644
index 7963506..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/search/search-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png
deleted file mode 100644
index 70054fe..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png
deleted file mode 100644
index c8e0143..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png
deleted file mode 100644
index ce39b062..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/date/date-text-height-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/date/date-text-height-appearance-expected.png
deleted file mode 100644
index 1fd205a..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/date/date-text-height-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/datetimelocal/datetimelocal-appearance-l10n-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/datetimelocal/datetimelocal-appearance-l10n-expected.png
deleted file mode 100644
index 3de79c6..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/datetimelocal/datetimelocal-appearance-l10n-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/datetimelocal/datetimelocal-picker-step2-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/datetimelocal/datetimelocal-picker-step2-expected.png
deleted file mode 100644
index 80f29e8..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/datetimelocal/datetimelocal-picker-step2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/file/file-appearance-bidi-filenames-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/file/file-appearance-bidi-filenames-expected.png
deleted file mode 100644
index 94e2371..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/file/file-appearance-bidi-filenames-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month-multiple-fields/month-multiple-fields-preserve-value-after-history-back-expected.txt b/third_party/blink/web_tests/platform/win7/fast/forms/month-multiple-fields/month-multiple-fields-preserve-value-after-history-back-expected.txt
deleted file mode 100644
index 8d955b8..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month-multiple-fields/month-multiple-fields-preserve-value-after-history-back-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Checks input value is preserved after backward and forward
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Went back to a page. Checking a form control which had a full value:
-PASS "12012-10" is "12012-10"
-Went back to a page. Checking a form control which had a partial value:
-FAIL "January, ----" should be January ----. Was January, ----.
-Went forward to a page. Checking a form control which had a full value:
-PASS "0001-11" is "0001-11"
-Went forward to a page. Checking a form control which had a partial value:
-FAIL "---------, 1999" should be --------- 1999. Was ---------, 1999.
-
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month-multiple-fields/month-multiple-fields-value-set-empty-expected.txt b/third_party/blink/web_tests/platform/win7/fast/forms/month-multiple-fields/month-multiple-fields-value-set-empty-expected.txt
deleted file mode 100644
index 54d26fe..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month-multiple-fields/month-multiple-fields-value-set-empty-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Check if input.value="" clears an input with partially-specified value.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Empty text: ---------, ----
-PASS eventSender.keyDown("ArrowUp"); getUserAgentShadowTextContent(input) is not emptyText
-PASS input.value = ""; getUserAgentShadowTextContent(input) is emptyText
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-basic-expected.png
deleted file mode 100644
index c267e7b6..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-l10n-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-l10n-expected.png
deleted file mode 100644
index 949f71b..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-l10n-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-pseudo-elements-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-pseudo-elements-expected.png
deleted file mode 100644
index 7032f70..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-appearance-pseudo-elements-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-disabled-today-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-disabled-today-expected.png
deleted file mode 100644
index ecfbf9f0..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-disabled-today-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-rtl-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-rtl-expected.png
deleted file mode 100644
index 3fb75b1..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-step-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-step-expected.png
deleted file mode 100644
index cfe63553..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-step-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-value-not-in-interval-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-value-not-in-interval-expected.png
deleted file mode 100644
index 1914199..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-value-not-in-interval-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-zoom150-expected.png
deleted file mode 100644
index ff306a1..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/month/month-picker-appearance-zoom150-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/placeholder-position-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/placeholder-position-expected.png
deleted file mode 100644
index 3008b3c..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/placeholder-position-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/search/search-appearance-basic-expected.png
deleted file mode 100644
index facaf44..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/search/search-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-styled-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
deleted file mode 100644
index 973f8643..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-styled-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-tall-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-tall-expected.png
deleted file mode 100644
index af2b748..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-tall-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-zoom110-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-zoom110-expected.png
deleted file mode 100644
index e1bcef4..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/select-popup/popup-menu-appearance-zoom110-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/select/menulist-appearance-rtl-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/select/menulist-appearance-rtl-expected.png
deleted file mode 100644
index 45c94f5..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/select/menulist-appearance-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/suggested-value-expected.txt b/third_party/blink/web_tests/platform/win7/fast/forms/suggested-value-expected.txt
deleted file mode 100644
index ebd20331..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/suggested-value-expected.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-This test setting suggested values on an input element 
-and a textarea element. The dump below should have the "suggested value"
-instead of "initial value".
-| <input>
-|   id="test"
-|   type="text"
-|   value="initial value"
-|   this.value="initial value"
-|   <shadow:root>
-|     <div>
-|       id="placeholder"
-|       pseudo="-internal-input-suggested"
-|       style="display: block !important;"
-|       shadow:pseudoId="-internal-input-suggested"
-|       "suggested value"
-|     <div>
-|       "suggested value"
-| <input>
-|   id="month"
-|   type="month"
-|   this.value=""
-|   <shadow:root>
-|     <div>
-|       datetimeformat="MMMM, yyyy"
-|       id="date-time-edit"
-|       pseudo="-webkit-datetime-edit"
-|       shadow:pseudoId="-webkit-datetime-edit"
-|       <div>
-|         pseudo="-webkit-datetime-edit-fields-wrapper"
-|         shadow:pseudoId="-webkit-datetime-edit-fields-wrapper"
-|         <span>
-|           aria-help="Month"
-|           aria-valuemax="12"
-|           aria-valuemin="1"
-|           aria-valuenow="1"
-|           aria-valuetext="January"
-|           pseudo="-webkit-datetime-edit-month-field"
-|           role="spinbutton"
-|           shadow:pseudoId="-webkit-datetime-edit-month-field"
-|           "January"
-|         <div>
-|           pseudo="-webkit-datetime-edit-text"
-|           shadow:pseudoId="-webkit-datetime-edit-text"
-|           ", "
-|         <span>
-|           aria-help="Year"
-|           aria-valuemax="275760"
-|           aria-valuemin="1"
-|           aria-valuenow="2014"
-|           aria-valuetext="2014"
-|           pseudo="-webkit-datetime-edit-year-field"
-|           role="spinbutton"
-|           shadow:pseudoId="-webkit-datetime-edit-year-field"
-|           "2014"
-|     <div>
-|       id="clear"
-|       pseudo="-webkit-clear-button"
-|       style=""
-|       shadow:pseudoId="-webkit-clear-button"
-|     <div>
-|       id="spin"
-|       pseudo="-webkit-inner-spin-button"
-|       shadow:pseudoId="-webkit-inner-spin-button"
-|     <div>
-|       id="picker"
-|       pseudo="-webkit-calendar-picker-indicator"
-|       shadow:pseudoId="-webkit-calendar-picker-indicator"
-| <textarea>
-|   id="textarea"
-|   this.value="initial value"
-|   <shadow:root>
-|       id="placeholder"
-|       pseudo="-internal-input-suggestedx"
-|       style="display: block !important;"
-|       shadow:pseudoId="-internal-input-suggested"
-|     <div>
-| <select>
-|   id="select"
-|   <option>
-|     "initial value"
-|     <shadow:root>
-|       "initial value"
-|   <option>
-|     "inserted value"
-|     <shadow:root>
-|       "inserted value"
-|   <shadow:root>
-|     <content>
-|       select="option,optgroup,hr"
-| "input.value: initial value"
-| "internals.suggestedValue(input): suggested value"
-| "input.selectionStart: 0"
-| "input.selectionEnd: 0"
-| "month.value: "
-| "internals.suggestedValue(month): 2014-01"
-| "textarea.value: initial value"
-| "internals.suggestedValue(textarea): suggested value"
-| "select.value: initial value"
-| "internals.suggestedValue(select): suggested value"
-| "internals.suggestedValue(select): "
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-expected.png
deleted file mode 100644
index f106401..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl-expected.png
deleted file mode 100644
index 7d762c1..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png
deleted file mode 100644
index f1d54e9..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/text-control-intrinsic-widths-expected.txt b/third_party/blink/web_tests/platform/win7/fast/forms/text-control-intrinsic-widths-expected.txt
deleted file mode 100644
index 840c2a79..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/text-control-intrinsic-widths-expected.txt
+++ /dev/null
@@ -1,414 +0,0 @@
-This test measures the width of textareas and text inputs for different fonts.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Lucida Grande
-input
-size=1 clientWidth=10
-size=2 clientWidth=16
-size=3 clientWidth=22
-size=4 clientWidth=28
-size=5 clientWidth=34
-size=10 clientWidth=64
-size=20 clientWidth=124
-size=50 clientWidth=304
-size=100 clientWidth=604
-size=500 clientWidth=3004
-size=1000 clientWidth=6004
-
-
-textarea
-cols=1 clientWidth=25
-cols=2 clientWidth=31
-cols=3 clientWidth=37
-cols=4 clientWidth=43
-cols=5 clientWidth=49
-cols=10 clientWidth=79
-cols=20 clientWidth=139
-cols=50 clientWidth=319
-cols=100 clientWidth=619
-cols=500 clientWidth=3019
-cols=1000 clientWidth=6019
-
-
-Courier
-input
-size=1 clientWidth=12
-size=2 clientWidth=20
-size=3 clientWidth=28
-size=4 clientWidth=36
-size=5 clientWidth=44
-size=10 clientWidth=84
-size=20 clientWidth=164
-size=50 clientWidth=404
-size=100 clientWidth=804
-size=500 clientWidth=4004
-size=1000 clientWidth=8004
-
-
-textarea
-cols=1 clientWidth=27
-cols=2 clientWidth=35
-cols=3 clientWidth=43
-cols=4 clientWidth=51
-cols=5 clientWidth=59
-cols=10 clientWidth=99
-cols=20 clientWidth=179
-cols=50 clientWidth=419
-cols=100 clientWidth=819
-cols=500 clientWidth=4019
-cols=1000 clientWidth=8019
-
-
-Helvetica
-input
-size=1 clientWidth=11
-size=2 clientWidth=18
-size=3 clientWidth=25
-size=4 clientWidth=32
-size=5 clientWidth=39
-size=10 clientWidth=74
-size=20 clientWidth=144
-size=50 clientWidth=354
-size=100 clientWidth=704
-size=500 clientWidth=3504
-size=1000 clientWidth=7004
-
-
-textarea
-cols=1 clientWidth=26
-cols=2 clientWidth=33
-cols=3 clientWidth=40
-cols=4 clientWidth=47
-cols=5 clientWidth=54
-cols=10 clientWidth=89
-cols=20 clientWidth=159
-cols=50 clientWidth=369
-cols=100 clientWidth=719
-cols=500 clientWidth=3519
-cols=1000 clientWidth=7019
-
-
-Monaco
-input
-size=1 clientWidth=10
-size=2 clientWidth=16
-size=3 clientWidth=22
-size=4 clientWidth=28
-size=5 clientWidth=34
-size=10 clientWidth=64
-size=20 clientWidth=124
-size=50 clientWidth=304
-size=100 clientWidth=604
-size=500 clientWidth=3004
-size=1000 clientWidth=6004
-
-
-textarea
-cols=1 clientWidth=25
-cols=2 clientWidth=31
-cols=3 clientWidth=37
-cols=4 clientWidth=43
-cols=5 clientWidth=49
-cols=10 clientWidth=79
-cols=20 clientWidth=139
-cols=50 clientWidth=319
-cols=100 clientWidth=619
-cols=500 clientWidth=3019
-cols=1000 clientWidth=6019
-
-
-Times
-input
-size=1 clientWidth=10
-size=2 clientWidth=16
-size=3 clientWidth=22
-size=4 clientWidth=28
-size=5 clientWidth=34
-size=10 clientWidth=64
-size=20 clientWidth=124
-size=50 clientWidth=304
-size=100 clientWidth=604
-size=500 clientWidth=3004
-size=1000 clientWidth=6004
-
-
-textarea
-cols=1 clientWidth=25
-cols=2 clientWidth=31
-cols=3 clientWidth=37
-cols=4 clientWidth=43
-cols=5 clientWidth=49
-cols=10 clientWidth=79
-cols=20 clientWidth=139
-cols=50 clientWidth=319
-cols=100 clientWidth=619
-cols=500 clientWidth=3019
-cols=1000 clientWidth=6019
-
-
-Andale Mono
-input
-size=1 clientWidth=38
-size=2 clientWidth=43
-size=3 clientWidth=48
-size=4 clientWidth=53
-size=5 clientWidth=58
-size=10 clientWidth=83
-size=20 clientWidth=133
-size=50 clientWidth=283
-size=100 clientWidth=533
-size=500 clientWidth=2533
-size=1000 clientWidth=5033
-
-
-textarea
-cols=1 clientWidth=24
-cols=2 clientWidth=29
-cols=3 clientWidth=34
-cols=4 clientWidth=39
-cols=5 clientWidth=44
-cols=10 clientWidth=69
-cols=20 clientWidth=119
-cols=50 clientWidth=269
-cols=100 clientWidth=519
-cols=500 clientWidth=2519
-cols=1000 clientWidth=5019
-
-
-Arial
-input
-size=1 clientWidth=40
-size=2 clientWidth=47
-size=3 clientWidth=54
-size=4 clientWidth=61
-size=5 clientWidth=68
-size=10 clientWidth=103
-size=20 clientWidth=173
-size=50 clientWidth=383
-size=100 clientWidth=733
-size=500 clientWidth=3533
-size=1000 clientWidth=7033
-
-
-textarea
-cols=1 clientWidth=26
-cols=2 clientWidth=33
-cols=3 clientWidth=40
-cols=4 clientWidth=47
-cols=5 clientWidth=54
-cols=10 clientWidth=89
-cols=20 clientWidth=159
-cols=50 clientWidth=369
-cols=100 clientWidth=719
-cols=500 clientWidth=3519
-cols=1000 clientWidth=7019
-
-
-Comic Sans MS
-input
-size=1 clientWidth=21
-size=2 clientWidth=29
-size=3 clientWidth=37
-size=4 clientWidth=45
-size=5 clientWidth=53
-size=10 clientWidth=93
-size=20 clientWidth=173
-size=50 clientWidth=413
-size=100 clientWidth=813
-size=500 clientWidth=4013
-size=1000 clientWidth=8013
-
-
-textarea
-cols=1 clientWidth=27
-cols=2 clientWidth=35
-cols=3 clientWidth=43
-cols=4 clientWidth=51
-cols=5 clientWidth=59
-cols=10 clientWidth=99
-cols=20 clientWidth=179
-cols=50 clientWidth=419
-cols=100 clientWidth=819
-cols=500 clientWidth=4019
-cols=1000 clientWidth=8019
-
-
-Courier New
-input
-size=1 clientWidth=14
-size=2 clientWidth=22
-size=3 clientWidth=30
-size=4 clientWidth=38
-size=5 clientWidth=46
-size=10 clientWidth=86
-size=20 clientWidth=166
-size=50 clientWidth=406
-size=100 clientWidth=806
-size=500 clientWidth=4006
-size=1000 clientWidth=8006
-
-
-textarea
-cols=1 clientWidth=27
-cols=2 clientWidth=35
-cols=3 clientWidth=43
-cols=4 clientWidth=51
-cols=5 clientWidth=59
-cols=10 clientWidth=99
-cols=20 clientWidth=179
-cols=50 clientWidth=419
-cols=100 clientWidth=819
-cols=500 clientWidth=4019
-cols=1000 clientWidth=8019
-
-
-Georgia
-input
-size=1 clientWidth=22
-size=2 clientWidth=30
-size=3 clientWidth=38
-size=4 clientWidth=46
-size=5 clientWidth=54
-size=10 clientWidth=94
-size=20 clientWidth=174
-size=50 clientWidth=414
-size=100 clientWidth=814
-size=500 clientWidth=4014
-size=1000 clientWidth=8014
-
-
-textarea
-cols=1 clientWidth=27
-cols=2 clientWidth=35
-cols=3 clientWidth=43
-cols=4 clientWidth=51
-cols=5 clientWidth=59
-cols=10 clientWidth=99
-cols=20 clientWidth=179
-cols=50 clientWidth=419
-cols=100 clientWidth=819
-cols=500 clientWidth=4019
-cols=1000 clientWidth=8019
-
-
-Times New Roman
-input
-size=1 clientWidth=38
-size=2 clientWidth=43
-size=3 clientWidth=48
-size=4 clientWidth=53
-size=5 clientWidth=58
-size=10 clientWidth=83
-size=20 clientWidth=133
-size=50 clientWidth=283
-size=100 clientWidth=533
-size=500 clientWidth=2533
-size=1000 clientWidth=5033
-
-
-textarea
-cols=1 clientWidth=24
-cols=2 clientWidth=29
-cols=3 clientWidth=34
-cols=4 clientWidth=39
-cols=5 clientWidth=44
-cols=10 clientWidth=69
-cols=20 clientWidth=119
-cols=50 clientWidth=269
-cols=100 clientWidth=519
-cols=500 clientWidth=2519
-cols=1000 clientWidth=5019
-
-
-Trebuchet MS
-input
-size=1 clientWidth=20
-size=2 clientWidth=27
-size=3 clientWidth=34
-size=4 clientWidth=41
-size=5 clientWidth=48
-size=10 clientWidth=83
-size=20 clientWidth=153
-size=50 clientWidth=363
-size=100 clientWidth=713
-size=500 clientWidth=3513
-size=1000 clientWidth=7013
-
-
-textarea
-cols=1 clientWidth=26
-cols=2 clientWidth=33
-cols=3 clientWidth=40
-cols=4 clientWidth=47
-cols=5 clientWidth=54
-cols=10 clientWidth=89
-cols=20 clientWidth=159
-cols=50 clientWidth=369
-cols=100 clientWidth=719
-cols=500 clientWidth=3519
-cols=1000 clientWidth=7019
-
-
-Verdana
-input
-size=1 clientWidth=31
-size=2 clientWidth=38
-size=3 clientWidth=45
-size=4 clientWidth=52
-size=5 clientWidth=59
-size=10 clientWidth=94
-size=20 clientWidth=164
-size=50 clientWidth=374
-size=100 clientWidth=724
-size=500 clientWidth=3524
-size=1000 clientWidth=7024
-
-
-textarea
-cols=1 clientWidth=26
-cols=2 clientWidth=33
-cols=3 clientWidth=40
-cols=4 clientWidth=47
-cols=5 clientWidth=54
-cols=10 clientWidth=89
-cols=20 clientWidth=159
-cols=50 clientWidth=369
-cols=100 clientWidth=719
-cols=500 clientWidth=3519
-cols=1000 clientWidth=7019
-
-
-Webdings
-input
-size=1 clientWidth=57
-size=2 clientWidth=70
-size=3 clientWidth=83
-size=4 clientWidth=96
-size=5 clientWidth=109
-size=10 clientWidth=174
-size=20 clientWidth=304
-size=50 clientWidth=694
-size=100 clientWidth=1344
-size=500 clientWidth=6544
-size=1000 clientWidth=13044
-
-
-textarea
-cols=1 clientWidth=32
-cols=2 clientWidth=45
-cols=3 clientWidth=58
-cols=4 clientWidth=71
-cols=5 clientWidth=84
-cols=10 clientWidth=149
-cols=20 clientWidth=279
-cols=50 clientWidth=669
-cols=100 clientWidth=1319
-cols=500 clientWidth=6519
-cols=1000 clientWidth=13019
-
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/text/text-font-height-mismatch-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/text/text-font-height-mismatch-expected.png
deleted file mode 100644
index dccf16a3..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/text/text-font-height-mismatch-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/time/time-picker-appearance-ko-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/time/time-picker-appearance-ko-expected.png
deleted file mode 100644
index 8c422c73..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/time/time-picker-appearance-ko-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/validationMessage-expected.txt b/third_party/blink/web_tests/platform/win7/fast/forms/validationMessage-expected.txt
deleted file mode 100644
index bbe1620..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/forms/validationMessage-expected.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-CONSOLE WARNING: The specified value "1999-01-02" cannot be parsed, or is out of range.
-CONSOLE WARNING: The specified value "2000-01-01T00:00" cannot be parsed, or is out of range.
-CONSOLE WARNING: The specified value "1999-01" cannot be parsed, or is out of range.
-CONSOLE WARNING: The specified value "1999-W01" cannot be parsed, or is out of range.
-CONSOLE WARNING: The specified value "06:00" cannot be parsed, or is out of range.
-Test for validationMessage DOM property.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-input patternMismatch: Please match the requested format.
-input valueMissing: Please fill out this field.
-textarea valueMissing: Please fill out this field.
-select valueMissing: Please select an item in the list.
-input typeMismatch for incorrectValue: Please include an '@' in the email address. 'incorrectValue' is missing an '@'.
-input typeMismatch for @xn--fsq.com: Please enter a part followed by '@'. '@例.com' is incomplete.
-input typeMismatch for user@: Please enter a part following '@'. 'user@' is incomplete.
-input typeMismatch for user@example*.com: A part following '@' should not contain the symbol '*'.
-input typeMismatch for user🙇@example.com: A part followed by '@' should not contain the symbol '🙇'.
-input typeMismatch for userí €@example.com: A part followed by '@' should not contain the symbol 'í €'.
-input typeMismatch for user@.example.com: '.' is used at a wrong position in '.example.com'.
-input typeMismatch for user@example.com.: '.' is used at a wrong position in 'example.com.'.
-input typeMismatch for user@xn--z8ja1psq..com: '.' is used at a wrong position in 'ぐーぐる..com'.
-input typeMismatch for foo@example.com,,bar@example.com: Please enter a non-empty email address.
-input typeMismatch for ,foo@example.com: Please enter a non-empty email address.
-input typeMismatch for foo@example.com,: Please enter a non-empty email address.
-input typeMismatch for foo@example.com,bar@..example.com: '.' is used at a wrong position in '..example.com'.
-input badInput: Please enter a number.
-badInput and valueMissing:
-PASS numberInput.validationMessage is nonRequiredBadInputMessage
-stepMismatch:
-input stepMismatch: Please enter a valid value. The two nearest valid values are 0.1 and 0.2.
-input stepMismatch: Please enter a valid value. The two nearest valid values are 0.1 and 0.2.
-input stepMismatch: Please enter a valid value. The nearest valid value is 10.
-rangeOverflow and rangeUnderflow:
-input rangeOverflow and rangeUnderflow: Value must be 1.
-input rangeOverflow and rangeUnderflow: Value must be 1.
-input rangeOverflow and rangeUnderflow: Value must be 01/02/2000.
-input rangeOverflow and rangeUnderflow: Value must be 01/02/2000.
-input rangeOverflow and rangeUnderflow: Value must be 01/02/2000 12:00 AM.
-input rangeOverflow and rangeUnderflow: Value must be 01/02/2000 12:00 AM.
-input rangeOverflow and rangeUnderflow: Value must be January, 2000.
-input rangeOverflow and rangeUnderflow: Value must be January, 2000.
-input rangeOverflow and rangeUnderflow: Value must be Week 01, 2000.
-input rangeOverflow and rangeUnderflow: Value must be Week 01, 2000.
-input rangeOverflow and rangeUnderflow: Value must be 7:00 AM.
-input rangeOverflow and rangeUnderflow: Value must be 7:00 AM.
-tooLong:
-input tooLong: Please shorten this text to 3 characters or less (you are currently using 5 characters).
-input tooLong: Please shorten this text to 2 characters or less (you are currently using 3 characters).
-input tooLong: Please shorten this text to ٢ characters or less (you are currently using ٣ characters).
-textarea tooLong: Please shorten this text to 3 characters or less (you are currently using 4 characters).
-tooShort:
-input tooShort: Please lengthen this text to 3 characters or more (you are currently using 1 character).
-input tooShort: Please lengthen this text to 4 characters or more (you are currently using 3 characters).
-input tooShort: Please lengthen this text to ٤ characters or more (you are currently using ٣ characters).
-textarea tooShort: Please lengthen this text to 4 characters or more (you are currently using 2 characters).
-PASS but.validationMessage is ''
-PASS anoninput.validationMessage is ''
-PASS happyFieldset.validationMessage is ''
-PASS happySelect.validationMessage is ''
-PASS happyOutput.validationMessage is ''
-PASS happyObject.validationMessage is ''
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/platform/win7/fast/hidpi/video-controls-in-hidpi-expected.png b/third_party/blink/web_tests/platform/win7/fast/hidpi/video-controls-in-hidpi-expected.png
deleted file mode 100644
index cb1c184..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/hidpi/video-controls-in-hidpi-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/inline/absolute-positioned-inline-in-centred-block-expected.png b/third_party/blink/web_tests/platform/win7/fast/inline/absolute-positioned-inline-in-centred-block-expected.png
deleted file mode 100644
index 58bccd99..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/inline/absolute-positioned-inline-in-centred-block-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/inline/justify-emphasis-inline-box-expected.png b/third_party/blink/web_tests/platform/win7/fast/inline/justify-emphasis-inline-box-expected.png
deleted file mode 100644
index 9ed65d9..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/inline/justify-emphasis-inline-box-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks-expected.png b/third_party/blink/web_tests/platform/win7/fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks-expected.png
deleted file mode 100644
index 348855f..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/inline/vertical-align-with-fallback-fonts-expected.png b/third_party/blink/web_tests/platform/win7/fast/inline/vertical-align-with-fallback-fonts-expected.png
deleted file mode 100644
index 1462ad4..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/inline/vertical-align-with-fallback-fonts-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/layers/video-layer-expected.png b/third_party/blink/web_tests/platform/win7/fast/layers/video-layer-expected.png
deleted file mode 100644
index e204f1aa..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/layers/video-layer-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/overflow/003-expected.png b/third_party/blink/web_tests/platform/win7/fast/overflow/003-expected.png
deleted file mode 100644
index 2ef101f..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/overflow/003-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/ruby/base-shorter-than-text-expected.png b/third_party/blink/web_tests/platform/win7/fast/ruby/base-shorter-than-text-expected.png
deleted file mode 100644
index 499a44d0..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/ruby/base-shorter-than-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/ruby/nested-ruby-expected.png b/third_party/blink/web_tests/platform/win7/fast/ruby/nested-ruby-expected.png
deleted file mode 100644
index 90f809d..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/ruby/nested-ruby-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-cell-collapsed-border-expected.png
deleted file mode 100644
index fdb4dcb..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-cell-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-cell-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-cell-expected.png
deleted file mode 100644
index ed03df26..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-cell-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-collapsed-border-expected.png
deleted file mode 100644
index 5d57e3e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-collapsed-border-expected.png
deleted file mode 100644
index 739e58bb5..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-expected.png
deleted file mode 100644
index fbb4c11..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
deleted file mode 100644
index 6e62d847..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-group-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-group-expected.png
deleted file mode 100644
index e913eef4..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-column-group-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-expected.png
deleted file mode 100644
index fec9104..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-quirks-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
deleted file mode 100644
index 65a1674..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-quirks-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-quirks-expected.png
deleted file mode 100644
index f13d63e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-quirks-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-collapsed-border-expected.png
deleted file mode 100644
index 8eea2783..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-expected.png
deleted file mode 100644
index 3c2cc29b..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
deleted file mode 100644
index 70f518e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-group-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-group-expected.png
deleted file mode 100644
index c5fdf999..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_border-table-row-group-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_layers-hide-collapsed-border-expected.png
deleted file mode 100644
index 05c02142..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_layers-hide-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_layers-hide-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_layers-hide-expected.png
deleted file mode 100644
index b5cfac2..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_layers-hide-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-cell-collapsed-border-expected.png
deleted file mode 100644
index a335515..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-cell-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-cell-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-cell-expected.png
deleted file mode 100644
index 054fe732..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-cell-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-collapsed-border-expected.png
deleted file mode 100644
index f218cfd..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-collapsed-border-expected.png
deleted file mode 100644
index 0ff5392..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-expected.png
deleted file mode 100644
index 530dc35..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
deleted file mode 100644
index 8f31574..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-group-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-group-expected.png
deleted file mode 100644
index d5f77047..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-column-group-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-expected.png
deleted file mode 100644
index cc43f511..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-collapsed-border-expected.png
deleted file mode 100644
index f224bc31e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-expected.png
deleted file mode 100644
index 30e3c9f..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
deleted file mode 100644
index c36af2e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-group-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-group-expected.png
deleted file mode 100644
index 0aecf6b..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_position-table-row-group-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
deleted file mode 100644
index 2ffe4e41..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-cell-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
deleted file mode 100644
index 84c68b8c..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-collapsed-border-expected.png
deleted file mode 100644
index a8e4c93..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-collapsed-border-expected.png
deleted file mode 100644
index ace5cd4..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-expected.png
deleted file mode 100644
index 0e63b911..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
deleted file mode 100644
index 743dbad..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
deleted file mode 100644
index b222ea0..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-expected.png
deleted file mode 100644
index 0149d66..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
deleted file mode 100644
index d68d67a..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-expected.png
deleted file mode 100644
index 2beb79f..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
deleted file mode 100644
index 469ce53b..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-group-expected.png b/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-group-expected.png
deleted file mode 100644
index 388608b..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/table/backgr_simple-table-row-group-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/writing-mode/Kusa-Makura-background-canvas-expected.png b/third_party/blink/web_tests/platform/win7/fast/writing-mode/Kusa-Makura-background-canvas-expected.png
deleted file mode 100644
index 57ac6ce..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/writing-mode/Kusa-Makura-background-canvas-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/writing-mode/border-image-vertical-lr-expected.png b/third_party/blink/web_tests/platform/win7/fast/writing-mode/border-image-vertical-lr-expected.png
deleted file mode 100644
index c4aa7cf..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/writing-mode/border-image-vertical-lr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/platform/win7/fast/writing-mode/english-lr-text-expected.png
deleted file mode 100644
index 6e4e3d8..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/writing-mode/english-lr-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/writing-mode/japanese-ruby-vertical-lr-expected.png b/third_party/blink/web_tests/platform/win7/fast/writing-mode/japanese-ruby-vertical-lr-expected.png
deleted file mode 100644
index 8cab23e..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/writing-mode/japanese-ruby-vertical-lr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/writing-mode/japanese-ruby-vertical-rl-expected.png b/third_party/blink/web_tests/platform/win7/fast/writing-mode/japanese-ruby-vertical-rl-expected.png
deleted file mode 100644
index 36d2e91..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/writing-mode/japanese-ruby-vertical-rl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/writing-mode/text-combine-various-fonts-expected.png b/third_party/blink/web_tests/platform/win7/fast/writing-mode/text-combine-various-fonts-expected.png
deleted file mode 100644
index 402d47ff..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/writing-mode/text-combine-various-fonts-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/writing-mode/text_combine_oblique-expected.png b/third_party/blink/web_tests/platform/win7/fast/writing-mode/text_combine_oblique-expected.png
deleted file mode 100644
index 0eacc326..0000000
--- a/third_party/blink/web_tests/platform/win7/fast/writing-mode/text_combine_oblique-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fonts/cursive-expected.png b/third_party/blink/web_tests/platform/win7/fonts/cursive-expected.png
deleted file mode 100644
index 0048edd3..0000000
--- a/third_party/blink/web_tests/platform/win7/fonts/cursive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fonts/fantasy-expected.png b/third_party/blink/web_tests/platform/win7/fonts/fantasy-expected.png
deleted file mode 100644
index 9b80ad42..0000000
--- a/third_party/blink/web_tests/platform/win7/fonts/fantasy-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-expand-object-expected.txt b/third_party/blink/web_tests/platform/win7/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-expand-object-expected.txt
deleted file mode 100644
index c978ab2..0000000
--- a/third_party/blink/web_tests/platform/win7/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-expand-object-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Verifies viewport stick-to-bottom behavior when prompt has space below editable area.
-
-Message count: 150
-
-Running: testExpandLastVisibleObjectRemainsInView
-
-Force selecting index 149
-Is at bottom: true, should stick: true, selected element is fully visible? true
-Expanding object
-Is at bottom: false, should stick: false, selected element is fully visible? true
-Collapsing object
-Is at bottom: true, should stick: false, selected element is fully visible? true
-
-Running: testExpandFirstVisibleObjectRemainsInView
-
-Force selecting index 146
-Is at bottom: false, should stick: false, selected element is fully visible? true
-Expanding object
-Is at bottom: false, should stick: false, selected element is fully visible? true
-Collapsing object
-Is at bottom: false, should stick: false, selected element is fully visible? true
-
diff --git a/third_party/blink/web_tests/platform/win7/http/tests/devtools/elements/styles-3/style-rule-from-imported-stylesheet-expected.txt b/third_party/blink/web_tests/platform/win7/http/tests/devtools/elements/styles-3/style-rule-from-imported-stylesheet-expected.txt
deleted file mode 100644
index 2d1ad02e..0000000
--- a/third_party/blink/web_tests/platform/win7/http/tests/devtools/elements/styles-3/style-rule-from-imported-stylesheet-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Tests that rules from imported stylesheets are correctly shown and are editable in inspector.
-
-TEST ENDED IN ERROR: TypeError: Cannot read property 'nodeType' of null
-    at Elements.ElementsTreeOutline.findTreeElement (file:///b/s/w/ir/out/Release/resources/inspector/elements/elements_module.js:514:91)
-    at Elements.ElementsTreeOutline._innerUpdateChildren (file:///b/s/w/ir/out/Release/resources/inspector/elements/elements_module.js:680:177)
-    at Elements.ElementsTreeOutline._updateChildren (file:///b/s/w/ir/out/Release/resources/inspector/elements/elements_module.js:670:50)
-    at Elements.ElementsTreeOutline._updateModifiedParentNode (file:///b/s/w/ir/out/Release/resources/inspector/elements/elements_module.js:639:6)
-    at Elements.ElementsTreeOutline._updateModifiedNodes (file:///b/s/w/ir/out/Release/resources/inspector/elements/elements_module.js:631:6)
-
diff --git a/third_party/blink/web_tests/platform/win7/http/tests/media/video-frame-size-change-expected.png b/third_party/blink/web_tests/platform/win7/http/tests/media/video-frame-size-change-expected.png
deleted file mode 100644
index 3793f0e9f..0000000
--- a/third_party/blink/web_tests/platform/win7/http/tests/media/video-frame-size-change-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/http/tests/misc/acid3-expected.png b/third_party/blink/web_tests/platform/win7/http/tests/misc/acid3-expected.png
deleted file mode 100644
index 8081dd8..0000000
--- a/third_party/blink/web_tests/platform/win7/http/tests/misc/acid3-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang-expected.txt b/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang-expected.txt
deleted file mode 100644
index edef994..0000000
--- a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang-expected.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-zh-CN: 誤過骨
-#zh-CN:
-"Times New Roman" : 7,
-"SimSun" : 3
-
-zh-TW: 誤過骨
-#zh-TW:
-"Times New Roman" : 7,
-"PMingLiU" : 3
-
-zh-HK: 誤過骨
-#zh-HK:
-"Times New Roman" : 7,
-"PMingLiU" : 3
-
-ja: 誤過骨
-#ja:
-"Times New Roman" : 4,
-"Meiryo" : 3
-
-ja-JP: 誤過骨
-#ja-JP:
-"Times New Roman" : 7,
-"Meiryo" : 3
-
-ko: 誤過骨
-#ko:
-"Times New Roman" : 4,
-"MS PGothic" : 3
-
-ko-KR: 誤過骨
-#ko-KR:
-"Times New Roman" : 7,
-"MS PGothic" : 3
-
-en-CN: 誤過骨
-#en-CN:
-"Times New Roman" : 7,
-"SimSun" : 3
-
-en-JP: 誤過骨
-#en-JP:
-"Times New Roman" : 7,
-"Meiryo" : 3
-
-en-KR: 誤過骨
-#en-KR:
-"Times New Roman" : 7,
-"MS PGothic" : 3
-
-en-HK: 誤過骨
-#en-HK:
-"Times New Roman" : 7,
-"PMingLiU" : 3
-
-en-TW: 誤過骨
-#en-TW:
-"Times New Roman" : 7,
-"PMingLiU" : 3
-
-en-HanS: 誤過骨
-#en-HanS:
-"Times New Roman" : 9,
-"SimSun" : 3
-
-en-HanT: 誤過骨
-#en-HanT:
-"Times New Roman" : 9,
-"PMingLiU" : 3
-
-en-HanS-JP: 誤過骨
-#en-HanS-JP:
-"Times New Roman" : 12,
-"SimSun" : 3
-
-en-HanT-JP: 誤過骨
-#en-HanT-JP:
-"Times New Roman" : 12,
-"PMingLiU" : 3
-
-en-US: 誤過骨
-#en-US:
-"Times New Roman" : 7,
-"SimSun" : 3
-
-
diff --git a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/fallback-myanmar-expected.txt b/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/fallback-myanmar-expected.txt
deleted file mode 100644
index 7378c948..0000000
--- a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/fallback-myanmar-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Test passes if a maxmium of the two first glyphs are notdef's (for Myanmar fonts that do not combine a left quote with a Myanmar spacing mark and the rest of the run is shaped, given a system Myanmar font is available.
-‘ေရွးျမန္မာမင္းေတြလက္ထက္က
-#myanmar:
-"Times New Roman" : 25
-
-FAIL
-
diff --git a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/font-weight-granularity-matching-expected.txt b/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/font-weight-granularity-matching-expected.txt
deleted file mode 100644
index 8be8514d..0000000
--- a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/font-weight-granularity-matching-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Text should be in the regular Segoe UI font.
-#regular-weight:
-"Segoe UI" : 44
-
-Text should be Segoe UI Semilight on Win10+, else Segoe UI Light.
-#semilight-weight:
-"Segoe UI Light" : 65
-
-
diff --git a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/lang-fallback-expected.txt b/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/lang-fallback-expected.txt
deleted file mode 100644
index fc936e0..0000000
--- a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/lang-fallback-expected.txt
+++ /dev/null
@@ -1,249 +0,0 @@
-تح
-#ar:
-"Times New Roman" : 2
-
-ՀՁ
-#hy-am:
-"Tahoma" : 2
-
-সম
-#bn:
-"Vrinda" : 2
-
-⡰⡱
-#en-us-brai:
-"Segoe UI Symbol" : 2
-
-ᨀᨁ
-#bug:
-"Times New Roman" : 2
-
-ᐐᐑ
-#cans:
-"Euphemia" : 2
-
-𐊠𐊡
-#xcr:
-"Times New Roman" : 2
-
-ᎡᎢ
-#chr:
-"Times New Roman" : 2
-
-ⲁⲂ
-#copt:
-"Times New Roman" : 2
-
-𒀀𒀌
-#akk:
-"Times New Roman" : 2
-
-𐠀𐠁
-#ecy:
-"Times New Roman" : 2
-
-АБВ
-#ru:
-"Times New Roman" : 3
-
-𐐀𐐁
-#en:
-"Times New Roman" : 2
-
-अआ
-#hi:
-"Mangal" : 2
-
-ሁሂ
-#am:
-"Nyala" : 2
-
-ႠႡ
-#ka:
-"Times New Roman" : 2
-
-ΑΒ
-#el:
-"Times New Roman" : 2
-
-ਡਢ
-#pa:
-"Raavi" : 2
-
-我
-#zh-CN:
-"Microsoft YaHei" : 1
-
-我
-#zh-HK:
-"Microsoft JhengHei" : 1
-
-我
-#zh-Hans:
-"Microsoft YaHei" : 1
-
-我
-#zh-Hant:
-"Microsoft JhengHei" : 1
-
-我
-#ja:
-"Meiryo" : 1
-
-ᄀᄁ
-#ko:
-"Malgun Gothic" : 2
-
-בג
-#he:
-"Times New Roman" : 2
-
-កខ
-#km:
-"Khmer UI" : 2
-
-𐡁𐡂
-#arc:
-"Times New Roman" : 2
-
-𐭡𐭢
-#pal:
-"Times New Roman" : 2
-
-𐭁𐭂
-#xpr:
-"Times New Roman" : 2
-
-ꦑꦒ
-#jv:
-"Times New Roman" : 2
-
-ಡಢ
-#kn:
-"Tunga" : 2
-
-𐨐𐨑
-#sa:
-"Times New Roman" : 2
-
-໐໑
-#lo:
-"Lao UI" : 2
-
-ꓐꓑ
-#lis:
-"Times New Roman" : 2
-
-𐊁𐊂
-#xlc:
-"Times New Roman" : 2
-
-𐤡𐤢
-#xld:
-"Times New Roman" : 2
-
-ഡഢ
-#ml:
-"Kartika" : 2
-
-𐦡𐦢
-#script_meroitic:
-"Times New Roman" : 2
-
-ကခ
-#my:
-"Times New Roman" : 2
-
-ᦁᦂ
-#script_new_tai_lue:
-"Microsoft New Tai Lue" : 2
-
-߁߂
-#nko:
-"Ebrima" : 2
-
-ᚁ
-#script_ogham:
-"Segoe UI Symbol" : 2
-
-᱑᱒
-#script_ol_chiki:
-"Times New Roman" : 2
-
-𐌁𐌂
-#script_old_italic:
-"Times New Roman" : 2
-
-𐎡𐎢
-#peo:
-"Times New Roman" : 2
-
-𐩡𐩢
-#script_old_south_arabian:
-"Times New Roman" : 2
-
-ଡଢ
-#or:
-"Kalinga" : 2
-
-ꡁꡂ
-#script_phags_pa:
-"Microsoft PhagsPa" : 2
-
-ᚠᚡ
-#script_runic:
-"Segoe UI Symbol" : 2
-
-𐑑𐑒
-#script_shavian:
-"Times New Roman" : 2
-
-එඒ
-#si:
-"Iskoola Pota" : 2
-
-𑃑𑃒
-#script_sora_sompeng:
-"Times New Roman" : 2
-
-ܑܒ
-#syr:
-"Estrangelo Edessa" : 2
-
-ᥑᥒ
-#script_tai_le:
-"Microsoft Tai Le" : 2
-
-றல
-#ta:
-"Latha" : 2
-
-డఢ
-#te:
-"Gautami" : 2
-
-ށނ
-#script_thaana:
-"MV Boli" : 2
-
-กข
-#th:
-"Tahoma" : 2
-
-༁༂
-#bo:
-"Microsoft Himalaya" : 2
-
-ⴱⴲ
-#script_tifinagh:
-"Ebrima" : 2
-
-ꔁꔂ
-#vai:
-"Ebrima" : 2
-
-ꀀꀁ
-#yi:
-"Microsoft Yi Baiti" : 2
-
-
diff --git a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/languages-emoji-rare-glyphs-expected.txt b/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/languages-emoji-rare-glyphs-expected.txt
deleted file mode 100644
index 9dcc0187..0000000
--- a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/languages-emoji-rare-glyphs-expected.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-百家姓 趙錢孫李 周吳鄭王 馮陳褚衛 蔣沈韓楊 朱秦尤許 何呂施張 孔曹嚴華 金魏陶薑 戚謝鄒喻 柏水竇章 雲蘇潘葛 奚範彭郎 魯韋昌馬 苗鳳花方 俞任袁柳 酆鮑史唐 費廉岑薛 雷賀倪湯 滕殷羅畢 郝鄔安常 樂於時傅 皮卞齊康 伍餘元蔔 顧孟平黃 和穆蕭尹 姚邵堪汪 祁毛禹狄 米貝明臧 計伏成戴 談宋茅龐 熊紀舒屈 項祝董梁 杜阮藍閔 席季麻強 賈路婁危 江童顏郭 梅盛林刁 鍾徐邱駱 高夏蔡田 樊胡淩霍 虞萬支柯 昝管盧莫 經房裘繆 幹解應宗 丁宣賁鄧 鬱單杭洪 包諸左石 崔吉鈕龔 程嵇邢滑 裴陸榮翁 荀羊於惠 甄曲家封 芮羿儲靳 汲邴糜松 井段富巫 烏焦巴弓 牧隗山穀 車侯宓蓬 全郗班仰 秋仲伊宮 寧仇欒暴 甘鈄厲戎 祖武符劉 景詹束龍 葉幸司韶 郜黎薊薄 印宿白懷 蒲台從鄂 索鹹籍賴 卓藺屠蒙 池喬陰鬱 胥能蒼雙 聞莘黨翟 譚貢勞逄 姬申扶堵 冉宰酈雍 卻璩桑桂 濮牛壽通 邊扈燕冀 郟浦尚農 溫別莊晏 柴瞿閻充 慕連茹習 宦艾魚容 向古易慎 戈廖庚終 暨居衡步 都耿滿弘 匡國文寇 廣祿闕東 毆殳沃利 蔚越夔隆 師鞏厙聶 晁勾敖融 冷訾辛闞 那簡饒空 曾毋沙乜 養鞠須豐 巢關蒯相 查後荊紅 遊竺權逯 蓋益桓公 萬俟司馬 上官歐陽 夏侯諸葛 聞人東方 赫連皇甫 尉遲公羊 澹台公冶 宗政濮陽 淳於單於 太叔申屠 公孫仲孫 軒轅令狐 鐘離宇文 長孫慕容 鮮於閭丘 司徒司空 亓官司寇 仉督子車 顓孫端木 巫馬公西 漆雕樂正 壤駟公良 拓拔夾穀 宰父穀粱 晉楚閆法 汝鄢塗欽 段幹百里 東郭南門 呼延歸海 羊舌微生 嶽帥緱亢 況後有琴 梁丘左丘 東門西門 商牟佘佴 伯賞南宮 墨哈譙笪 年愛陽佟
-#hundred_chinese_surnames:
-"Microsoft YaHei" : 563,
-"Times New Roman" : 140
-
-いろはにほへと ちりぬるを わかよたれそ つねならむ うゐのおくやま けふこえて あさき ゆめみし ゑひもせす(ん)色は匂へど 散りぬるを 我が世誰ぞ 常ならむ 有為の奥山 今日越えて 浅き夢見じ 酔ひもせず(ん)
-#japanese_iroha:
-"Meiryo" : 92,
-"Times New Roman" : 15
-
-키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다.
-#korean_pangram:
-"Malgun Gothic" : 28,
-"Times New Roman" : 9
-
-ऋषियों को सताने वाले दुष्ट राक्षसों के राजा रावण का सर्वनाश करने वाले विष्णुवतार भगवान श्रीराम, अयोध्या के महाराज दशरथ के बड़े सपुत्र थे।
-#hindi_pangram:
-"Mangal" : 100,
-"Times New Roman" : 23
-
-نصٌّ حكيمٌ لهُ سِرٌّ قاطِعٌ وَذُو شَأنٍ عَظيمٍ مكتوبٌ على ثوبٍ أخضرَ ومُغلفٌ بجلدٍ أزرق
-#arabic_pangram:
-"Times New Roman" : 85
-
-🌱🌲🌳🌴🌵🌷🌸🌹🌺🌻🌼💐🌾🌿🍀🍁🍂🍃🍄🌰☺️😀👪
-#emoji:
-"Segoe UI Symbol" : 19,
-"Times New Roman" : 5
-
-𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏
-#egyptian_hieroglyphs:
-"Times New Roman" : 16
-
-ខ្ញុំអាចញុំកញ្ចក់បាន ដោយគ្មានបញ្ហារ
-#khmer:
-"Khmer UI" : 26,
-"Times New Roman" : 1
-
-𐌲𐌿𐍄𐌹𐍃𐌺
-#gothic:
-"Segoe UI Symbol" : 6
-
-ܐܬܘܪܝܐ
-#syriac:
-"Estrangelo Edessa" : 6
-
-⇦⇧⇨⇩←↑→↓⟀
-#text_presentation_arrows_maths:
-"MS PGothic" : 4,
-"Cambria Math" : 4,
-"Times New Roman" : 1
-
-
diff --git a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/ogham-expected.txt b/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/ogham-expected.txt
deleted file mode 100644
index 2b04a187..0000000
--- a/third_party/blink/web_tests/platform/win7/inspector-protocol/layout-fonts/ogham-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-ᚁᚂᚃᚄᚅᚆᚇᚈᚉᚊᚋᚌᚍᚎᚏᚐᚑᚒᚓᚔᚕᚖᚗᚘᚙᚚ᚛᚜
-#oghammonofont:
-"Segoe UI Symbol" : 29
-
-ᚁᚂᚃᚄᚅᚆᚇᚈᚉᚊᚋᚌᚍᚎᚏᚐᚑᚒᚓᚔᚕᚖᚗᚘᚙᚚ᚛᚜
-#oghamdefaultfont:
-"Segoe UI Symbol" : 29
-
-There should be two lines of Ogham above.
-
diff --git a/third_party/blink/web_tests/platform/win7/media/controls-focus-ring-expected.png b/third_party/blink/web_tests/platform/win7/media/controls-focus-ring-expected.png
deleted file mode 100644
index 5f2bfa5..0000000
--- a/third_party/blink/web_tests/platform/win7/media/controls-focus-ring-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/win7/media/track/track-cue-rendering-vertical-expected.png
deleted file mode 100644
index a196ac5..0000000
--- a/third_party/blink/web_tests/platform/win7/media/track/track-cue-rendering-vertical-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/paint/invalidation/selection/japanese-rl-selection-clear-expected.png b/third_party/blink/web_tests/platform/win7/paint/invalidation/selection/japanese-rl-selection-clear-expected.png
deleted file mode 100644
index 89df879..0000000
--- a/third_party/blink/web_tests/platform/win7/paint/invalidation/selection/japanese-rl-selection-clear-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/paint/invalidation/selection/japanese-rl-selection-clear-expected.txt b/third_party/blink/web_tests/platform/win7/paint/invalidation/selection/japanese-rl-selection-clear-expected.txt
deleted file mode 100644
index 7b7897d..0000000
--- a/third_party/blink/web_tests/platform/win7/paint/invalidation/selection/japanese-rl-selection-clear-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "Scrolling background of LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "invalidations": [
-        [334, 123, 439, 399],
-        [393, 123, 384, 404]
-      ]
-    }
-  ]
-}
-
diff --git a/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
deleted file mode 100644
index 5da95943..0000000
--- a/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/paint/text/vertical-upright-oblique-expected.png b/third_party/blink/web_tests/platform/win7/paint/text/vertical-upright-oblique-expected.png
deleted file mode 100644
index e9ea21b..0000000
--- a/third_party/blink/web_tests/platform/win7/paint/text/vertical-upright-oblique-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/blink/web_tests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png
deleted file mode 100644
index 0ed1262..0000000
--- a/third_party/blink/web_tests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirLTR-ubNone-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirLTR-ubNone-expected.png
deleted file mode 100644
index 0ac758e..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirLTR-ubNone-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirLTR-ubOverride-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirLTR-ubOverride-expected.png
deleted file mode 100644
index 4e2de0cd..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirLTR-ubOverride-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirRTL-ubNone-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirRTL-ubNone-expected.png
deleted file mode 100644
index 58e73e8..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirRTL-ubNone-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirRTL-ubOverride-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirRTL-ubOverride-expected.png
deleted file mode 100644
index 3807091..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/g-dirRTL-ubOverride-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorEnd-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorEnd-expected.png
deleted file mode 100644
index ff01925..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorEnd-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorMiddle-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorMiddle-expected.png
deleted file mode 100644
index 28dc8c2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorMiddle-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorStart-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorStart-expected.png
deleted file mode 100644
index 96b29acf4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirLTR-anchorStart-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorEnd-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorEnd-expected.png
deleted file mode 100644
index ff01925..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorEnd-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorMiddle-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorMiddle-expected.png
deleted file mode 100644
index 28dc8c2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorMiddle-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorStart-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorStart-expected.png
deleted file mode 100644
index 96b29acf4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirNone-anchorStart-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorEnd-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorEnd-expected.png
deleted file mode 100644
index 96b29acf4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorEnd-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorMiddle-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorMiddle-expected.png
deleted file mode 100644
index 28dc8c2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorMiddle-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorStart-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorStart-expected.png
deleted file mode 100644
index ff01925..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-dirRTL-anchorStart-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorEnd-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorEnd-expected.png
deleted file mode 100644
index ff01925..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorEnd-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorMiddle-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorMiddle-expected.png
deleted file mode 100644
index 28dc8c2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorMiddle-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorStart-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorStart-expected.png
deleted file mode 100644
index 96b29acf4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirLTR-anchorStart-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorEnd-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorEnd-expected.png
deleted file mode 100644
index 96b29acf4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorEnd-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorMiddle-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorMiddle-expected.png
deleted file mode 100644
index 28dc8c2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorMiddle-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorStart-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorStart-expected.png
deleted file mode 100644
index ff01925..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-inherited-dirRTL-anchorStart-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-no-markup-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-no-markup-expected.png
deleted file mode 100644
index 96b29acf4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-anchor-no-markup-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirLTR-ubNone-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirLTR-ubNone-expected.png
deleted file mode 100644
index 0ac758e..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirLTR-ubNone-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirLTR-ubOverride-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirLTR-ubOverride-expected.png
deleted file mode 100644
index 15abb60..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirLTR-ubOverride-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirRTL-ubNone-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirRTL-ubNone-expected.png
deleted file mode 100644
index 58e73e8..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirRTL-ubNone-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirRTL-ubOverride-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirRTL-ubOverride-expected.png
deleted file mode 100644
index e2fdce19..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/text-dirRTL-ubOverride-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubEmbed-in-rtl-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubEmbed-in-rtl-context-expected.png
deleted file mode 100644
index 1a6a2e2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubEmbed-in-rtl-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubNone-in-rtl-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubNone-in-rtl-context-expected.png
deleted file mode 100644
index cdfb4f9..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubNone-in-rtl-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-default-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-default-context-expected.png
deleted file mode 100644
index 434075f..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-default-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-ltr-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-ltr-context-expected.png
deleted file mode 100644
index 434075f..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-ltr-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-rtl-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-rtl-context-expected.png
deleted file mode 100644
index 78bea8c..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirLTR-ubOverride-in-rtl-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-default-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-default-context-expected.png
deleted file mode 100644
index 371bba4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-default-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-ltr-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-ltr-context-expected.png
deleted file mode 100644
index 371bba4..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-ltr-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-rtl-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-rtl-context-expected.png
deleted file mode 100644
index 47b1e39..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirNone-ubOverride-in-rtl-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubEmbed-in-default-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubEmbed-in-default-context-expected.png
deleted file mode 100644
index e212905..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubEmbed-in-default-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubEmbed-in-ltr-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubEmbed-in-ltr-context-expected.png
deleted file mode 100644
index e212905..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubEmbed-in-ltr-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubNone-in-default-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubNone-in-default-context-expected.png
deleted file mode 100644
index 080812b..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubNone-in-default-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubNone-in-ltr-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubNone-in-ltr-context-expected.png
deleted file mode 100644
index 080812b..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubNone-in-ltr-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-default-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-default-context-expected.png
deleted file mode 100644
index 887086d..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-default-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-ltr-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-ltr-context-expected.png
deleted file mode 100644
index 887086d..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-ltr-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-rtl-context-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-rtl-context-expected.png
deleted file mode 100644
index 5275587c..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-dirRTL-ubOverride-in-rtl-context-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-direction-ltr-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-direction-ltr-expected.png
deleted file mode 100644
index d54b033..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-direction-ltr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-direction-rtl-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-direction-rtl-expected.png
deleted file mode 100644
index f100c00..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-I18N/tspan-direction-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1-SE/text-intro-05-t-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1-SE/text-intro-05-t-expected.png
deleted file mode 100644
index 52ff966..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1-SE/text-intro-05-t-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/animate-elem-22-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/animate-elem-22-b-expected.png
deleted file mode 100644
index 162080f..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/animate-elem-22-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/filters-color-01-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/filters-color-01-b-expected.png
deleted file mode 100644
index d0cd577..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/filters-color-01-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
deleted file mode 100644
index 4ed4cef..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/masking-path-04-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/masking-path-04-b-expected.png
deleted file mode 100644
index e0f71168..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/masking-path-04-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/painting-render-01-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/painting-render-01-b-expected.png
deleted file mode 100644
index f7c6743..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/painting-render-01-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-align-08-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-align-08-b-expected.png
deleted file mode 100644
index 3cc6c82..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-align-08-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-fonts-01-t-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-fonts-01-t-expected.png
deleted file mode 100644
index b970889..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-fonts-01-t-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-01-t-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-01-t-expected.png
deleted file mode 100644
index ea5dfb64..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-01-t-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-03-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-03-b-expected.png
deleted file mode 100644
index 41141b2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-03-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-04-t-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-04-t-expected.png
deleted file mode 100644
index 5e8156e2..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-intro-04-t-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-text-08-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-text-08-b-expected.png
deleted file mode 100644
index f179ba8..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/W3C-SVG-1.1/text-text-08-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/as-background-image/svg-as-background-5-expected.png b/third_party/blink/web_tests/platform/win7/svg/as-background-image/svg-as-background-5-expected.png
deleted file mode 100644
index 0754cad..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/as-background-image/svg-as-background-5-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/carto.net/combobox-expected.png b/third_party/blink/web_tests/platform/win7/svg/carto.net/combobox-expected.png
deleted file mode 100644
index 231e4f5..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/carto.net/combobox-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/css/alignment-baseline-expected.png b/third_party/blink/web_tests/platform/win7/svg/css/alignment-baseline-expected.png
deleted file mode 100644
index c8ace945..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/css/alignment-baseline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/custom/svg-fonts-in-html-expected.png b/third_party/blink/web_tests/platform/win7/svg/custom/svg-fonts-in-html-expected.png
deleted file mode 100644
index 7dc3f53bc..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/custom/svg-fonts-in-html-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/custom/svg-fonts-in-text-controls-expected.txt b/third_party/blink/web_tests/platform/win7/svg/custom/svg-fonts-in-text-controls-expected.txt
deleted file mode 100644
index 895ea31..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/custom/svg-fonts-in-text-controls-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This tests that the width of textareas and inputs is correctly calculated based on the metrics of the SVG font.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-Textarea offsetWidth: 137
-Input offsetWidth: 146
diff --git a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-in-attr-expected.png b/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-in-attr-expected.png
deleted file mode 100644
index 519c78a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-in-attr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-operator-attr-expected.png b/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-operator-attr-expected.png
deleted file mode 100644
index 36b354a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-operator-attr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-radius-attr-expected.png b/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-radius-attr-expected.png
deleted file mode 100644
index 36b354a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-dom-radius-attr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-in-prop-expected.png b/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-in-prop-expected.png
deleted file mode 100644
index 519c78a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-in-prop-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-operator-prop-expected.png b/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-operator-prop-expected.png
deleted file mode 100644
index 36b354a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-operator-prop-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-radius-call-expected.png b/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-radius-call-expected.png
deleted file mode 100644
index 36b354a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/dynamic-updates/SVGFEMorphologyElement-svgdom-radius-call-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-expected.png
deleted file mode 100644
index 34b4be6..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-on-path-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-on-path-expected.png
deleted file mode 100644
index 5521c09a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-on-path-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-zoomed-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-zoomed-expected.png
deleted file mode 100644
index f9064244..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/bbox-with-glyph-overflow-zoomed-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/bidi-reorder-in-text-chunks-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/bidi-reorder-in-text-chunks-expected.png
deleted file mode 100644
index adbbc75..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/bidi-reorder-in-text-chunks-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/bidi-text-query-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/bidi-text-query-expected.png
deleted file mode 100644
index 5639007b..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/bidi-text-query-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/bidi-textlength-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/bidi-textlength-expected.png
deleted file mode 100644
index b53a098..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/bidi-textlength-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/bidi-tspans-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/bidi-tspans-expected.png
deleted file mode 100644
index 681f1568..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/bidi-tspans-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/surrogate-pair-queries-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/surrogate-pair-queries-expected.png
deleted file mode 100644
index 7081440..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/surrogate-pair-queries-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-fonts-01-t-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/text-selection-fonts-01-t-expected.png
deleted file mode 100644
index 7e9f37a..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-fonts-01-t-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-intro-05-t-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/text-selection-intro-05-t-expected.png
deleted file mode 100644
index 1b019294..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-intro-05-t-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-text-08-b-expected.png b/third_party/blink/web_tests/platform/win7/svg/text/text-selection-text-08-b-expected.png
deleted file mode 100644
index 193467b..0000000
--- a/third_party/blink/web_tests/platform/win7/svg/text/text-selection-text-08-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/tables/mozilla/bugs/bug2479-2-expected.png b/third_party/blink/web_tests/platform/win7/tables/mozilla/bugs/bug2479-2-expected.png
deleted file mode 100644
index ea29333..0000000
--- a/third_party/blink/web_tests/platform/win7/tables/mozilla/bugs/bug2479-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/blink/web_tests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
deleted file mode 100644
index 4a5bdf39..0000000
--- a/third_party/blink/web_tests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/transforms/2d/hindi-rotated-expected.png b/third_party/blink/web_tests/platform/win7/transforms/2d/hindi-rotated-expected.png
deleted file mode 100644
index 8cb90b73..0000000
--- a/third_party/blink/web_tests/platform/win7/transforms/2d/hindi-rotated-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/backface-visibility-interop/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/win7/virtual/backface-visibility-interop/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
deleted file mode 100644
index 5da95943..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/backface-visibility-interop/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png
deleted file mode 100644
index 4171496..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png
deleted file mode 100644
index ddf9b48..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png
deleted file mode 100644
index c17121de..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
deleted file mode 100644
index 30c4ce3..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png
deleted file mode 100644
index 3329fb7..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png
deleted file mode 100644
index 5606c3e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png
deleted file mode 100644
index bc69072..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month/month-appearance-basic-expected.png
deleted file mode 100644
index 084bc13..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
deleted file mode 100644
index 8330ab1..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/suggestion-picker/datetimelocal-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/suggestion-picker/datetimelocal-suggestion-picker-appearance-expected.png
deleted file mode 100644
index 7b280644..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/suggestion-picker/datetimelocal-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png
deleted file mode 100644
index 1a0f8403..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png
deleted file mode 100644
index 30a03d4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png
deleted file mode 100644
index c09b648..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/date/date-picker-month-year-selector-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/date/date-picker-month-year-selector-expected.png
deleted file mode 100644
index eb10f97..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/date/date-picker-month-year-selector-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/date/date-picker-open-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/date/date-picker-open-expected.png
deleted file mode 100644
index a3254dc2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/date/date-picker-open-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/datetimelocal-picker/datetimelocal-month-year-selector-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/datetimelocal-picker/datetimelocal-month-year-selector-expected.png
deleted file mode 100644
index 8a11229..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/datetimelocal-picker/datetimelocal-month-year-selector-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/datetimelocal-picker/datetimelocal-open-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/datetimelocal-picker/datetimelocal-open-expected.png
deleted file mode 100644
index 7cdf167..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/datetimelocal-picker/datetimelocal-open-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png
deleted file mode 100644
index 62c8fdd..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png
deleted file mode 100644
index b8dc95c8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png
deleted file mode 100644
index 879478c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/calendar-picker/date-picker-disabled-values-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
deleted file mode 100644
index dfb3ef8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png
deleted file mode 100644
index 01a6ad5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-disabled-values-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png
deleted file mode 100644
index 2edf349..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png
deleted file mode 100644
index 0d5854e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month-picker/month-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month/month-appearance-basic-expected.png
deleted file mode 100644
index 66e253a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png
deleted file mode 100644
index 4f49261..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png
deleted file mode 100644
index 12a10f90..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/suggestion-picker/month-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png
deleted file mode 100644
index b19ca8a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-es-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png
deleted file mode 100644
index 84ccc27..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/week-picker/week-picker-appearance-highlight-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https-expected.txt
deleted file mode 100644
index c4f0add2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL enumerateDevices has stable deviceIds across same-origin iframe assert_true: deviceIds stay the same when loaded in same origin expected true got false
-PASS enumerateDevices rotates deviceId across different-origin iframe
-FAIL enumerateDevices rotates deviceId after clearing site data assert_false: deviceIds are not kept after clearing site data expected false got true
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-background-clip-text-expected.png b/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-background-clip-text-expected.png
deleted file mode 100644
index 24ad71a0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-background-clip-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png b/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png
deleted file mode 100644
index c26d2bc..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-group-expected.png b/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-group-expected.png
deleted file mode 100644
index dc277d0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/color-profile-group-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/exif-orientation-css-expected.png b/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/exif-orientation-css-expected.png
deleted file mode 100644
index 58f00895..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/gpu-rasterization/images/exif-orientation-css-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png b/third_party/blink/web_tests/platform/win7/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png
deleted file mode 100644
index 9d6cc51..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png
deleted file mode 100644
index 2a74e98..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index 4c65b86..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634044394837.3 but got 1634044394837
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker-expected.txt
deleted file mode 100644
index d741fc4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-PASS Blob URLs work on importScripts
-PASS A revoked blob URL will fail
-FAIL Revoking a blob URL in an earlier script will not fail Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'blob:http://web-platform.test:8001/6f501756-4da2-4696-bb36-09b641f0b6aa' failed to load.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/blink/web_tests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png
deleted file mode 100644
index 0ed1262..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/prerender/external/wpt/speculation-rules/prerender/restriction-window-resize-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/prerender/external/wpt/speculation-rules/prerender/restriction-window-resize-expected.txt
deleted file mode 100644
index f0dc06a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/prerender/external/wpt/speculation-rules/prerender/restriction-window-resize-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL a prerendering page cannot resize its window by executing resizeTo. assert_equals: expected "PASS" but got "FAIL: Error: assert_equals: height for primary expected 599 but got 598"
-FAIL a prerendering page cannot resize its window by executing resizeBy. assert_equals: expected "PASS" but got "FAIL: Error: assert_equals: height for primary expected 599 but got 598"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/prerender/wpt_internal/prerender/local-storage-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/prerender/wpt_internal/prerender/local-storage-expected.txt
deleted file mode 100644
index f34d0662..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/prerender/wpt_internal/prerender/local-storage-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL prerendering page should be able to access local storage assert_equals: prerendering page should be able to write to local storage expected (string) "prerender_set" but got (object) null
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
deleted file mode 100644
index 19a3c67..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
deleted file mode 100644
index c19eea8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/select-popup/popup-menu-appearance-tall-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/select-popup/popup-menu-appearance-tall-expected.png
deleted file mode 100644
index 91c5f545..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/select-popup/popup-menu-appearance-tall-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-expected.png
deleted file mode 100644
index c2510f37..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-rtl-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-rtl-expected.png
deleted file mode 100644
index 48d989b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar-expected.png
deleted file mode 100644
index 9d9604b8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-expected.png
deleted file mode 100644
index 3043d65..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-expected.png
deleted file mode 100644
index 55e22b25..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl-expected.png
deleted file mode 100644
index db79f75..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png
deleted file mode 100644
index f5d6ff1..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/time-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/time-suggestion-picker-appearance-expected.png
deleted file mode 100644
index e99de3b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/time-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew-expected.png
deleted file mode 100644
index 54944f6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/week-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/week-suggestion-picker-appearance-expected.png
deleted file mode 100644
index f151250f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/scroll-unification/fast/forms/suggestion-picker/week-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/OWNERS b/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/OWNERS
deleted file mode 100644
index d0b8610..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-set noparent
-
-# Web-exposed API changes may require approval from blink API OWNERS.
-# See http://www.chromium.org/blink#new-features for details.
-file://third_party/blink/API_OWNERS
diff --git a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/feature-policy-features-platform-specific-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/feature-policy-features-platform-specific-expected.txt
deleted file mode 100644
index 453c0a5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/feature-policy-features-platform-specific-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This test documents Blink's web-exposed policy-controlled features.
-All changes to this list should go through Blink's feature review process: http://www.chromium.org/blink#new-features
-
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
deleted file mode 100644
index a346b23..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This test documents all interface attributes and methods on the global window object and element instances.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-[INTERFACES]
-interface Navigator
-interface Notification : EventTarget
-    getter image
-[NAMESPACES]
-[GLOBAL OBJECT]
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/storage-access-api/external/wpt/storage-access-api/requestStorageAccess.sub.window-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/storage-access-api/external/wpt/storage-access-api/requestStorageAccess.sub.window-expected.txt
deleted file mode 100644
index 599426e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/storage-access-api/external/wpt/storage-access-api/requestStorageAccess.sub.window-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This is a testharness.js-based test.
-PASS [top-level-context] document.requestStorageAccess() should be supported on the document interface
-PASS [top-level-context] document.requestStorageAccess() should be rejected by default with no user gesture
-PASS [top-level-context] document.requestStorageAccess() should be resolved when called properly with a user gesture
-PASS [cross-origin-frame] document.requestStorageAccess() should be supported on the document interface
-PASS [cross-origin-frame] document.requestStorageAccess() should be rejected by default with no user gesture
-PASS [same-origin-frame] document.requestStorageAccess() should be supported on the document interface
-PASS [same-origin-frame] document.requestStorageAccess() should be rejected by default with no user gesture
-PASS [nested-same-origin-frame] document.requestStorageAccess() should be supported on the document interface
-PASS [nested-same-origin-frame] document.requestStorageAccess() should be rejected by default with no user gesture
-PASS [nested-cross-origin-frame] document.requestStorageAccess() should be supported on the document interface
-PASS [nested-cross-origin-frame] document.requestStorageAccess() should be rejected by default with no user gesture
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/apply-start-width-after-skipped-text-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/apply-start-width-after-skipped-text-expected.png
deleted file mode 100644
index eee1e41..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/apply-start-width-after-skipped-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atomic-inline-before-ellipsis-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atomic-inline-before-ellipsis-expected.png
deleted file mode 100644
index 46dc1f1e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atomic-inline-before-ellipsis-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-multiple-renderers-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-multiple-renderers-expected.png
deleted file mode 100644
index a829b52..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-multiple-renderers-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-negative-spacing-features-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-negative-spacing-features-expected.png
deleted file mode 100644
index 5714d1ea..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-negative-spacing-features-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-pointtooffset-calls-cg-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-pointtooffset-calls-cg-expected.png
deleted file mode 100644
index cc01d0a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-pointtooffset-calls-cg-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-small-caps-punctuation-size-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-small-caps-punctuation-size-expected.png
deleted file mode 100644
index 5a102c9a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-small-caps-punctuation-size-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-spacing-features-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-spacing-features-expected.png
deleted file mode 100644
index 2fcafe8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/atsui-spacing-features-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/001-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/001-expected.png
deleted file mode 100644
index 0ae2197..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/002-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/002-expected.png
deleted file mode 100644
index 6e8626f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/003-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/003-expected.png
deleted file mode 100644
index b140e1e6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/003-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/004-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/004-expected.png
deleted file mode 100644
index 4846e57..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/004-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/005-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/005-expected.png
deleted file mode 100644
index 85a42fa8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/005-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/006-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/006-expected.png
deleted file mode 100644
index f72c1dc2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/006-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/007-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/007-expected.png
deleted file mode 100644
index 9fa2d053..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/007-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/008-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/008-expected.png
deleted file mode 100644
index 5fd9424..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/008-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/009-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/009-expected.png
deleted file mode 100644
index 9232715f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/009-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/011-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/011-expected.png
deleted file mode 100644
index 7ff6ab1..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/011-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/012-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/012-expected.png
deleted file mode 100644
index 0a74d79..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/012-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/013-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/013-expected.png
deleted file mode 100644
index baa384b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/013-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/014-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/014-expected.png
deleted file mode 100644
index 97eb34c5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/014-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/015-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/015-expected.png
deleted file mode 100644
index 0a13fab..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/015-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/generic-family-changes-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/generic-family-changes-expected.png
deleted file mode 100644
index 5cf98b3..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/generic-family-changes-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/generic-family-reset-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/generic-family-reset-expected.png
deleted file mode 100644
index 096b8d6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/basic/generic-family-reset-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-embedding-pop-and-push-same-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-embedding-pop-and-push-same-2-expected.png
deleted file mode 100644
index c3b6a57e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-embedding-pop-and-push-same-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-embedding-pop-and-push-same-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-embedding-pop-and-push-same-expected.png
deleted file mode 100644
index 698dd0f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-embedding-pop-and-push-same-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-explicit-embedding-past-end-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-explicit-embedding-past-end-expected.png
deleted file mode 100644
index f15c2f4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-explicit-embedding-past-end-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-img-alt-text-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-img-alt-text-expected.png
deleted file mode 100644
index 95cb509..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/bidi-img-alt-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/break-word-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/break-word-expected.png
deleted file mode 100644
index a1a82e9..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/break-word-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-boundaries-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-boundaries-expected.png
deleted file mode 100644
index 4f0e66f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-boundaries-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-empty-generated-string-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-empty-generated-string-expected.png
deleted file mode 100644
index 9727eed..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-empty-generated-string-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-preserve-nbsp-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-preserve-nbsp-expected.png
deleted file mode 100644
index 84724d2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/capitalize-preserve-nbsp-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-disabled-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-disabled-expected.png
deleted file mode 100644
index de026e6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-disabled-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-enabled-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-enabled-expected.png
deleted file mode 100644
index 622a426f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-enabled-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-enabled-rtl-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-enabled-rtl-expected.png
deleted file mode 100644
index 9a3c4e8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/caps-lock-indicator-enabled-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/cg-fallback-bolding-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/cg-fallback-bolding-expected.png
deleted file mode 100644
index f41db39..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/cg-fallback-bolding-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/cg-vs-atsui-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/cg-vs-atsui-expected.png
deleted file mode 100644
index d637c81..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/cg-vs-atsui-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/color-emoji-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/color-emoji-expected.png
deleted file mode 100644
index 1353811..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/color-emoji-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/colrv1-samples-visual-expected.png
deleted file mode 100644
index 4523e67..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/colrv1-samples-visual-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-path-with-no-subpixel-fonts-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-path-with-no-subpixel-fonts-expected.png
deleted file mode 100644
index f04ac326..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-path-with-no-subpixel-fonts-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-preferred-logical-widths-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-preferred-logical-widths-expected.png
deleted file mode 100644
index 71dc99b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-preferred-logical-widths-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-synthetic-bold-space-width-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-synthetic-bold-space-width-expected.png
deleted file mode 100644
index 6cef478..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-synthetic-bold-space-width-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-text-opacity-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-text-opacity-expected.png
deleted file mode 100644
index 62139ae..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/complex-text-opacity-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/decorations-with-text-combine-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/decorations-with-text-combine-expected.png
deleted file mode 100644
index 1dc648e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/decorations-with-text-combine-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-at-edge-of-ltr-text-in-rtl-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-at-edge-of-ltr-text-in-rtl-flow-expected.png
deleted file mode 100644
index fe02fd5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-at-edge-of-ltr-text-in-rtl-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-at-edge-of-rtl-text-in-ltr-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-at-edge-of-rtl-text-in-ltr-flow-expected.png
deleted file mode 100644
index 526c7f18..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-at-edge-of-rtl-text-in-ltr-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-in-absolute-block-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-in-absolute-block-expected.png
deleted file mode 100644
index 543feec..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-in-absolute-block-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-in-justified-text-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-in-justified-text-expected.png
deleted file mode 100644
index 48cde51..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-in-justified-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-expected.png
deleted file mode 100644
index db7ce983..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png
deleted file mode 100644
index 65ff0b2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-underline-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-underline-expected.png
deleted file mode 100644
index f58242e4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-underline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-expected.png
deleted file mode 100644
index fe02fd5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-leading-space-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-leading-space-expected.png
deleted file mode 100644
index ff53b08..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-leading-space-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png
deleted file mode 100644
index 861a076..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-underline-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-underline-expected.png
deleted file mode 100644
index 328f551d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-ltr-text-in-rtl-flow-underline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.png
deleted file mode 100644
index 73cf28d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-ltr-flow-underline-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-ltr-flow-underline-expected.png
deleted file mode 100644
index 23395dd..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-ltr-flow-underline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png
deleted file mode 100644
index 9fa77f1b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-rtl-flow-underline-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-rtl-flow-underline-expected.png
deleted file mode 100644
index b8cf23a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-mixed-text-in-rtl-flow-underline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-platform-font-change-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-platform-font-change-expected.png
deleted file mode 100644
index c82448a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-platform-font-change-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-expected.png
deleted file mode 100644
index 374aa4d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png
deleted file mode 100644
index 2b98bdbb..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-underline-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-underline-expected.png
deleted file mode 100644
index 14bc90b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-ltr-flow-underline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-expected.png
deleted file mode 100644
index 60cae1a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png
deleted file mode 100644
index f6e1097..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-underline-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-underline-expected.png
deleted file mode 100644
index 9bfd6d0f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-rtl-text-in-rtl-flow-underline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-with-list-marker-in-ltr-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-with-list-marker-in-ltr-flow-expected.png
deleted file mode 100644
index 4033a096..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-with-list-marker-in-ltr-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-with-list-marker-in-rtl-flow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-with-list-marker-in-rtl-flow-expected.png
deleted file mode 100644
index 107d7a3..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/ellipsis-with-list-marker-in-rtl-flow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoji-vertical-origin-visual-expected.png
deleted file mode 100644
index dd7c153..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoji-vertical-origin-visual-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoji-web-font-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoji-web-font-expected.png
deleted file mode 100644
index 0876660..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoji-web-font-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoticons-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoticons-expected.png
deleted file mode 100644
index 44658d0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emoticons-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-avoid-ruby-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-avoid-ruby-expected.png
deleted file mode 100644
index 4e50dc4a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-avoid-ruby-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-combined-text-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-combined-text-expected.png
deleted file mode 100644
index 47e0fd51..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-combined-text-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-complex-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-complex-expected.png
deleted file mode 100644
index 714ff04a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-complex-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-ellipsis-complextext-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-ellipsis-complextext-expected.png
deleted file mode 100644
index ac8fea9..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-ellipsis-complextext-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-overlap-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-overlap-expected.png
deleted file mode 100644
index 2256339..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/emphasis-overlap-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fake-italic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fake-italic-expected.png
deleted file mode 100644
index 83241aa..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fake-italic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fallback-for-custom-font-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fallback-for-custom-font-expected.png
deleted file mode 100644
index 722c514..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fallback-for-custom-font-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fallback-traits-fixup-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fallback-traits-fixup-expected.png
deleted file mode 100644
index 7d5c058d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/fallback-traits-fixup-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/001-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/001-expected.png
deleted file mode 100644
index 3b032d3..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/002-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/002-expected.png
deleted file mode 100644
index 4eb017f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/003-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/003-expected.png
deleted file mode 100644
index 1d87b96..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/firstline/003-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-ascent-mac-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-ascent-mac-expected.png
deleted file mode 100644
index d06b6bd..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-ascent-mac-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-fallback-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-fallback-expected.png
deleted file mode 100644
index eef28f4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-fallback-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-features/caps-casemapping-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-features/caps-casemapping-expected.txt
deleted file mode 100644
index ca0a2d7..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-features/caps-casemapping-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Synthetic small caps should produce the same width as manually uppercased, downscaled text.
-PASS Strings containing uppercased sharp S should not be truncated.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-format-support-color-cff2-expected.png
deleted file mode 100644
index 616e44f0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-format-support-color-cff2-vertical-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-format-support-color-cff2-vertical-expected.png
deleted file mode 100644
index c1fb0e3..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-format-support-color-cff2-vertical-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-initial-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-initial-expected.png
deleted file mode 100644
index 32343e6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-initial-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-kerning-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-kerning-expected.png
deleted file mode 100644
index e7f14474..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-kerning-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-size-adjust-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-size-adjust-expected.png
deleted file mode 100644
index 01d635ed1..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-size-adjust-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-smallcaps-layout-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-smallcaps-layout-expected.png
deleted file mode 100644
index 3d90574..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-smallcaps-layout-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-weight-600-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-weight-600-expected.png
deleted file mode 100644
index bb9b233..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-weight-600-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-weight-variant-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-weight-variant-expected.png
deleted file mode 100644
index 647ba69d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/font-weight-variant-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/format-control-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/format-control-expected.png
deleted file mode 100644
index 1536f2a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/format-control-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/hide-atomic-inlines-after-ellipsis-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/hide-atomic-inlines-after-ellipsis-expected.png
deleted file mode 100644
index b3ddae1..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/hide-atomic-inlines-after-ellipsis-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/in-rendered-text-rtl-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/in-rendered-text-rtl-expected.png
deleted file mode 100644
index 345378d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/in-rendered-text-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/001-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/001-expected.png
deleted file mode 100644
index 0d12fdd..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/002-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/002-expected.png
deleted file mode 100644
index 9e3b8d8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/003-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/003-expected.png
deleted file mode 100644
index a26f244..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/003-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/alef-connected-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/alef-connected-expected.png
deleted file mode 100644
index 8dbcd8d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/alef-connected-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/arabic-justify-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/arabic-justify-expected.png
deleted file mode 100644
index a68d811..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/arabic-justify-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-AN-after-L-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-AN-after-L-expected.png
deleted file mode 100644
index b8567eb8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-AN-after-L-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-AN-after-empty-run-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-AN-after-empty-run-expected.png
deleted file mode 100644
index ccc685e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-AN-after-empty-run-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-CS-after-AN-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-CS-after-AN-expected.png
deleted file mode 100644
index d82413a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-CS-after-AN-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-L2-run-reordering-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-L2-run-reordering-expected.png
deleted file mode 100644
index edef5bdd..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-L2-run-reordering-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-CSS-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-CSS-expected.png
deleted file mode 100644
index c5ede553..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-CSS-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-HTML-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-HTML-expected.png
deleted file mode 100644
index afe6474..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-HTML-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-formatting-characters-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-formatting-characters-expected.png
deleted file mode 100644
index 7e6d61e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-LDB-2-formatting-characters-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-control-chars-treated-as-ZWS-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-control-chars-treated-as-ZWS-expected.png
deleted file mode 100644
index 1628241d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-control-chars-treated-as-ZWS-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-european-terminators-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-european-terminators-expected.png
deleted file mode 100644
index 467b5e2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-european-terminators-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-explicit-embedding-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-explicit-embedding-expected.png
deleted file mode 100644
index 302affe76..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-explicit-embedding-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-ignored-for-first-child-inline-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-ignored-for-first-child-inline-expected.png
deleted file mode 100644
index 5771a7c2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-ignored-for-first-child-inline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-innertext-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-innertext-expected.png
deleted file mode 100644
index 1cfda92..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-innertext-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-layout-across-linebreak-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-layout-across-linebreak-expected.png
deleted file mode 100644
index e71339c5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-layout-across-linebreak-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-001-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-001-expected.png
deleted file mode 100644
index 65c7063..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-002-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-002-expected.png
deleted file mode 100644
index 5423685..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-003-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-003-expected.png
deleted file mode 100644
index 5423685..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-linebreak-003-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-mirror-he-ar-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-mirror-he-ar-expected.png
deleted file mode 100644
index 654afe5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-mirror-he-ar-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-neutral-directionality-paragraph-start-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-neutral-directionality-paragraph-start-expected.png
deleted file mode 100644
index 918a683..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-neutral-directionality-paragraph-start-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-neutral-run-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-neutral-run-expected.png
deleted file mode 100644
index 157427c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-neutral-run-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-override-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-override-expected.png
deleted file mode 100644
index 1ab79c7..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-override-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-word-spacing-rtl-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-word-spacing-rtl-expected.png
deleted file mode 100644
index c189e8b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bidi-word-spacing-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bold-bengali-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bold-bengali-expected.png
deleted file mode 100644
index 3a4f4ab0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/bold-bengali-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/complex-character-based-fallback-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/complex-character-based-fallback-expected.png
deleted file mode 100644
index 3fc1fa19..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/complex-character-based-fallback-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/danda-space-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/danda-space-expected.png
deleted file mode 100644
index f7a50968..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/danda-space-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hebrew-vowels-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hebrew-vowels-expected.png
deleted file mode 100644
index f4d7972..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hebrew-vowels-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hindi-spacing-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hindi-spacing-expected.png
deleted file mode 100644
index acc0a47..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hindi-spacing-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hindi-whitespace-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hindi-whitespace-expected.png
deleted file mode 100644
index 2fcb914..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/hindi-whitespace-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/plane2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/plane2-expected.png
deleted file mode 100644
index 8e3ec74..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/plane2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/rtl-negative-letter-spacing-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/rtl-negative-letter-spacing-expected.png
deleted file mode 100644
index a01fa405..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/rtl-negative-letter-spacing-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/rtl-white-space-pre-wrap-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/rtl-white-space-pre-wrap-expected.png
deleted file mode 100644
index 5a52841..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/rtl-white-space-pre-wrap-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/text-combine-image-test-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/text-combine-image-test-expected.png
deleted file mode 100644
index 74d195f8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/text-combine-image-test-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/thai-baht-space-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/thai-baht-space-expected.png
deleted file mode 100644
index 92fee0e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/thai-baht-space-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/unicode-bidi-plaintext-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/unicode-bidi-plaintext-expected.png
deleted file mode 100644
index 670c3ccb..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/unicode-bidi-plaintext-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/unicode-bidi-plaintext-in-textarea-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/unicode-bidi-plaintext-in-textarea-expected.png
deleted file mode 100644
index d0e86d6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/unicode-bidi-plaintext-in-textarea-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/vertical-text-glyph-test-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/vertical-text-glyph-test-expected.png
deleted file mode 100644
index 75eec55..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/vertical-text-glyph-test-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/vertical-text-metrics-test-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/vertical-text-metrics-test-expected.txt
deleted file mode 100644
index d253f60..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/vertical-text-metrics-test-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Simple text path
-
-string「あ、変っ!」。
-string「あ、変っ!」。
-string「あ、変っ!」。
-
-
-
-Complex text path
-
-string「あ、変っ!」。
-string「あ、変っ!」。
-string「あ、変っ!」。
-
-
-
-width=219
-width=32
-width=32
-width=219
-width=32
-width=32
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/wrap-CJK-001-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/wrap-CJK-001-expected.png
deleted file mode 100644
index a92eb47..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/international/wrap-CJK-001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-complex-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-complex-expected.png
deleted file mode 100644
index 43a13e8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-complex-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
deleted file mode 100644
index 9e8347a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-leading-expansion-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-simple-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-simple-expected.png
deleted file mode 100644
index 43a13e8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-simple-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-vertical-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-vertical-expected.png
deleted file mode 100644
index 17e8cb8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-ideograph-vertical-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-nbsp-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-nbsp-expected.png
deleted file mode 100644
index 3f66c21c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-nbsp-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-padding-distribution-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-padding-distribution-expected.png
deleted file mode 100644
index 1159692..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/justify-padding-distribution-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/large-text-composed-char-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/large-text-composed-char-expected.png
deleted file mode 100644
index 865e3093..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/large-text-composed-char-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-leading-and-trailing-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-leading-and-trailing-expected.png
deleted file mode 100644
index e2bbc47..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-leading-and-trailing-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-negative-opacity-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-negative-opacity-expected.png
deleted file mode 100644
index b94d481..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/letter-spacing-negative-opacity-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-breaks-after-white-space-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-breaks-after-white-space-expected.png
deleted file mode 100644
index 7ffb1e7..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-breaks-after-white-space-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-breaks-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-breaks-expected.png
deleted file mode 100644
index bcfc80de..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-breaks-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-initial-and-final-swashes-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-initial-and-final-swashes-expected.png
deleted file mode 100644
index 20ba5e2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/line-initial-and-final-swashes-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-after-breakable-char-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-after-breakable-char-expected.png
deleted file mode 100644
index 5a693b2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-after-breakable-char-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-before-surrogate-pair-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-before-surrogate-pair-expected.png
deleted file mode 100644
index a0d026a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-before-surrogate-pair-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-hang-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-hang-expected.png
deleted file mode 100644
index f846e9c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/midword-break-hang-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/orientation-sideways-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/orientation-sideways-expected.png
deleted file mode 100644
index 43a1d68..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/orientation-sideways-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-block-adjacent-float-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-block-adjacent-float-2-expected.png
deleted file mode 100644
index 236adb5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-block-adjacent-float-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-block-adjacent-float-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-block-adjacent-float-expected.png
deleted file mode 100644
index 705fa8d3..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-block-adjacent-float-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-2-expected.png
deleted file mode 100644
index 4ac4614..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-center-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-center-expected.png
deleted file mode 100644
index ffb27d2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-center-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-justify-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-justify-expected.png
deleted file mode 100644
index ffb27d2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-justify-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-left-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-left-expected.png
deleted file mode 100644
index ffb27d2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-left-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-right-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-right-expected.png
deleted file mode 100644
index ffb27d2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-align-right-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-expected.png
deleted file mode 100644
index ffb27d2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-ellipsis-in-inline-blocks-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-2-expected.png
deleted file mode 100644
index 355679b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-center-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-center-2-expected.png
deleted file mode 100644
index 06278d1..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-center-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-center-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-center-expected.png
deleted file mode 100644
index ba603ec0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-center-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-justify-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-justify-expected.png
deleted file mode 100644
index dfc0a84b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-justify-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-left-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-left-2-expected.png
deleted file mode 100644
index 9d83932a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-left-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-left-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-left-expected.png
deleted file mode 100644
index 94133f0e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-left-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-right-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-right-2-expected.png
deleted file mode 100644
index 3d666b2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-right-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-right-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-right-expected.png
deleted file mode 100644
index bb260c0d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-align-right-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-expected.png
deleted file mode 100644
index dfc0a84b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-mixed-ellipsis-in-inline-blocks-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-2-expected.png
deleted file mode 100644
index f79a849..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-center-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-center-expected.png
deleted file mode 100644
index fe59d7f36..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-center-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-justify-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-justify-expected.png
deleted file mode 100644
index fe59d7f36..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-justify-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-left-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-left-expected.png
deleted file mode 100644
index fe59d7f36..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-left-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-right-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-right-expected.png
deleted file mode 100644
index fe59d7f36..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-align-right-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-expected.png
deleted file mode 100644
index fe59d7f36..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/place-rtl-ellipsis-in-inline-blocks-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/reset-emptyRun-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/reset-emptyRun-expected.png
deleted file mode 100644
index 55be671..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/reset-emptyRun-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-kerning-and-ligatures-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-kerning-and-ligatures-expected.png
deleted file mode 100644
index f2e37c1..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-kerning-and-ligatures-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-partial-selection-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-partial-selection-expected.png
deleted file mode 100644
index 5fde12ba..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-partial-selection-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-rtl-override-selection-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-rtl-override-selection-expected.png
deleted file mode 100644
index 1433444..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/atsui-rtl-override-selection-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/complex-text-rtl-selection-repaint-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/complex-text-rtl-selection-repaint-expected.png
deleted file mode 100644
index 488f787..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/complex-text-rtl-selection-repaint-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/delete-hard-break-character-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/delete-hard-break-character-expected.png
deleted file mode 100644
index db2cbcb68cf..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/delete-hard-break-character-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/emphasis-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/emphasis-expected.png
deleted file mode 100644
index bbc8669a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/emphasis-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/flexbox-selection-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/flexbox-selection-expected.png
deleted file mode 100644
index 8459eb38..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/flexbox-selection-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/flexbox-selection-nested-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/flexbox-selection-nested-expected.png
deleted file mode 100644
index 6536b88..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/flexbox-selection-nested-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/justified-selection-at-edge-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/justified-selection-at-edge-expected.png
deleted file mode 100644
index 7e4277db..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/justified-selection-at-edge-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/justified-selection-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/justified-selection-expected.png
deleted file mode 100644
index 6d69fe72..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/justified-selection-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/khmer-selection-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/khmer-selection-expected.png
deleted file mode 100644
index 3669edc3..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/khmer-selection-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/mixed-directionality-selection-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/mixed-directionality-selection-expected.png
deleted file mode 100644
index e3fc3b2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/mixed-directionality-selection-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/pre-wrap-overflow-selection-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/pre-wrap-overflow-selection-expected.png
deleted file mode 100644
index 0417d588..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/pre-wrap-overflow-selection-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/rtl-caret-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/rtl-caret-expected.png
deleted file mode 100644
index d8685140..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/rtl-caret-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-1-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-1-expected.png
deleted file mode 100644
index 788039c4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-1-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-2-expected.png
deleted file mode 100644
index bb5920b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-3-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-3-expected.png
deleted file mode 100644
index 91abd50..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-3-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-1-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-1-expected.png
deleted file mode 100644
index ad62fb4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-1-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-2-expected.png
deleted file mode 100644
index bc35340..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-3-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-3-expected.png
deleted file mode 100644
index 0d0900ea..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-ligature-vertical-3-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-new-line-with-line-break-normal-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-new-line-with-line-break-normal-expected.png
deleted file mode 100644
index d94d37cc..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/select-new-line-with-line-break-normal-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-hard-linebreak-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-hard-linebreak-expected.png
deleted file mode 100644
index 4e1c629..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-hard-linebreak-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-multiple-runs-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-multiple-runs-expected.png
deleted file mode 100644
index 1638c79..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-multiple-runs-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-painted-separately-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-painted-separately-expected.png
deleted file mode 100644
index 85ce41b9..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-painted-separately-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-painting-hidpi-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-painting-hidpi-expected.png
deleted file mode 100644
index 9241b9e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-painting-hidpi-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-rect-line-height-too-big-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-rect-line-height-too-big-expected.png
deleted file mode 100644
index 3a2d1c8b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-rect-line-height-too-big-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-rect-line-height-too-small-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-rect-line-height-too-small-expected.png
deleted file mode 100644
index 964b90a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-rect-line-height-too-small-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-with-inline-padding-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-with-inline-padding-expected.png
deleted file mode 100644
index 1f1f7ea..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/selection-with-inline-padding-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/shaping-selection-rect-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/shaping-selection-rect-expected.png
deleted file mode 100644
index 9e65f514..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/shaping-selection-rect-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/should-use-atsui-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/should-use-atsui-expected.png
deleted file mode 100644
index f6771a6f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/selection/should-use-atsui-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/setData-dirty-lines-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/setData-dirty-lines-expected.png
deleted file mode 100644
index 92519cca..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/setData-dirty-lines-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shadow-no-blur-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shadow-no-blur-expected.png
deleted file mode 100644
index 461f900..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shadow-no-blur-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shadow-translucent-fill-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shadow-translucent-fill-expected.png
deleted file mode 100644
index b9dc97e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shadow-translucent-fill-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shaping/same-script-different-lang-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shaping/same-script-different-lang-expected.png
deleted file mode 100644
index f3f874f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shaping/same-script-different-lang-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shaping/shaping-script-order-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shaping/shaping-script-order-expected.png
deleted file mode 100644
index b8567eb8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/shaping/shaping-script-order-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/small-caps-turkish-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/small-caps-turkish-expected.png
deleted file mode 100644
index 120dd65..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/small-caps-turkish-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/soft-hyphen-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/soft-hyphen-2-expected.png
deleted file mode 100644
index 7360076..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/soft-hyphen-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/soft-hyphen-3-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/soft-hyphen-3-expected.png
deleted file mode 100644
index 5b0c0ccd..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/soft-hyphen-3-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/softHyphen-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/softHyphen-expected.png
deleted file mode 100644
index a418df7..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/softHyphen-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/splitText-dirty-lines-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/splitText-dirty-lines-expected.png
deleted file mode 100644
index 6710e533..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/splitText-dirty-lines-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/stroking-decorations-expected.png
deleted file mode 100644
index 851a9e2d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/stroking-decorations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/stroking-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/stroking-expected.png
deleted file mode 100644
index f8148fb2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/stroking-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-letter-spacing-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-letter-spacing-expected.png
deleted file mode 100644
index 0ae097c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-letter-spacing-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-shadow-no-default-color-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-shadow-no-default-color-expected.png
deleted file mode 100644
index 52e56d9..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-shadow-no-default-color-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-stroke-with-border-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-stroke-with-border-expected.png
deleted file mode 100644
index cd630c2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/text-stroke-with-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/trailing-white-space-2-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/trailing-white-space-2-expected.png
deleted file mode 100644
index 4f8a5d4..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/trailing-white-space-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/trailing-white-space-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/trailing-white-space-expected.png
deleted file mode 100644
index d3f3f9ed..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/trailing-white-space-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/unicode-fallback-font-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/unicode-fallback-font-expected.png
deleted file mode 100644
index 625f928..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/unicode-fallback-font-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/updateNewFont-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/updateNewFont-expected.png
deleted file mode 100644
index 2f47f6f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/updateNewFont-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/variable-fonts/cff2-variations-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
deleted file mode 100644
index 7bcb3ff..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/vertical-rl-rtl-linebreak-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/vertical-rl-rtl-linebreak-expected.png
deleted file mode 100644
index f4ec6bf..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/vertical-rl-rtl-linebreak-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/vertical-surrogate-pair-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/vertical-surrogate-pair-expected.png
deleted file mode 100644
index 9e09153b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/vertical-surrogate-pair-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-expected.png
deleted file mode 100644
index ef9f237..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-in-pre-crash-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-in-pre-crash-expected.png
deleted file mode 100644
index 7e150df..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-in-pre-crash-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-pre-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-pre-expected.png
deleted file mode 100644
index 22de0db8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-pre-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-styled-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-styled-expected.png
deleted file mode 100644
index 75d7f67..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/wbr-styled-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/webfont-synthetic-bold-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/webfont-synthetic-bold-expected.png
deleted file mode 100644
index 08aded5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/webfont-synthetic-bold-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/001-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/001-expected.png
deleted file mode 100644
index 329eaee..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/002-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/002-expected.png
deleted file mode 100644
index cf16327..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/003-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/003-expected.png
deleted file mode 100644
index cf16327..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/003-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/004-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/004-expected.png
deleted file mode 100644
index e7e183c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/004-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/005-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/005-expected.png
deleted file mode 100644
index 2bf5e48..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/005-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/007-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/007-expected.png
deleted file mode 100644
index 8b0fde6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/007-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/008-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/008-expected.png
deleted file mode 100644
index f4dc8cff..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/008-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/009-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/009-expected.png
deleted file mode 100644
index f2e12e7..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/009-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/010-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/010-expected.png
deleted file mode 100644
index e7e183c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/010-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/011-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/011-expected.png
deleted file mode 100644
index 2bf5e48..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/011-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/012-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/012-expected.png
deleted file mode 100644
index fca1addb..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/012-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/013-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/013-expected.png
deleted file mode 100644
index 620b2e0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/013-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/014-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/014-expected.png
deleted file mode 100644
index 2b3b381..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/014-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/015-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/015-expected.png
deleted file mode 100644
index e7e183c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/015-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/016-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/016-expected.png
deleted file mode 100644
index 2bf5e48..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/016-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/017-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/017-expected.png
deleted file mode 100644
index 59cec48..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/017-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/018-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/018-expected.png
deleted file mode 100644
index 70edebe8..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/018-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/019-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/019-expected.png
deleted file mode 100644
index 4389d087..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/019-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/020-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/020-expected.png
deleted file mode 100644
index 44056f0c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/020-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/021-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/021-expected.png
deleted file mode 100644
index b47f7cf5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/021-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/022-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/022-expected.png
deleted file mode 100644
index 52ad13db..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/022-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/023-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/023-expected.png
deleted file mode 100644
index 211259a..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/023-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/024-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/024-expected.png
deleted file mode 100644
index d51d387..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/024-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/025-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/025-expected.png
deleted file mode 100644
index b2287c39..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/025-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/026-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/026-expected.png
deleted file mode 100644
index 9d855769..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/026-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/027-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/027-expected.png
deleted file mode 100644
index 0f76ab2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/027-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/028-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/028-expected.png
deleted file mode 100644
index fb24ee2..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/028-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/029-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/029-expected.png
deleted file mode 100644
index 5024d1c..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/029-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/030-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/030-expected.png
deleted file mode 100644
index 37e074b..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/030-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/nbsp-mode-and-linewraps-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/nbsp-mode-and-linewraps-expected.png
deleted file mode 100644
index 1e6ad8f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/nbsp-mode-and-linewraps-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/normal-after-nowrap-breaking-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/normal-after-nowrap-breaking-expected.png
deleted file mode 100644
index 13c5811..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/normal-after-nowrap-breaking-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/nowrap-clear-float-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/nowrap-clear-float-expected.png
deleted file mode 100644
index fcfd8d5d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/nowrap-clear-float-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-newline-box-test-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-newline-box-test-expected.png
deleted file mode 100644
index 322b1223..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-newline-box-test-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-wrap-last-char-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-wrap-last-char-expected.png
deleted file mode 100644
index c720dca..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-wrap-last-char-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-wrap-line-test-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-wrap-line-test-expected.png
deleted file mode 100644
index db6d4e1e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/pre-wrap-line-test-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/span-in-word-space-causes-overflow-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/span-in-word-space-causes-overflow-expected.png
deleted file mode 100644
index 046634ec..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/span-in-word-space-causes-overflow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/tab-character-basics-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/tab-character-basics-expected.png
deleted file mode 100644
index 3b353c6..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/whitespace/tab-character-basics-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-expected.png
deleted file mode 100644
index 2889255..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-run-rounding-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-run-rounding-expected.png
deleted file mode 100644
index 9e2e644..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-run-rounding-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-soft-hyphen-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-soft-hyphen-expected.png
deleted file mode 100644
index 6823bb5..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-break-soft-hyphen-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-space-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-space-expected.png
deleted file mode 100644
index 8cc348f..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/word-space-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/zero-font-size-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/zero-font-size-expected.png
deleted file mode 100644
index 51d70dd..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/zero-font-size-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
deleted file mode 100644
index 10e225d..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
+++ /dev/null
@@ -1,382 +0,0 @@
-This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface Element: original interface defined
-PASS Partial interface Element: member names are unique
-PASS Partial interface HTMLElement: original interface defined
-PASS Partial interface HTMLElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface Range: original interface defined
-PASS Partial interface Range: member names are unique
-PASS Partial interface MouseEvent: original interface defined
-PASS Partial interface MouseEvent: member names are unique
-PASS Partial interface Element[2]: member names are unique
-PASS Partial interface Window[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Partial interface MouseEvent[2]: member names are unique
-PASS Partial interface UIEvent[2]: member names are unique
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface HTMLImageElement[2]: member names are unique
-PASS Partial interface Document[4]: member names are unique
-PASS Partial interface Window[3]: member names are unique
-PASS Text includes GeometryUtils: member names are unique
-PASS Element includes GeometryUtils: member names are unique
-PASS CSSPseudoElement includes GeometryUtils: member names are unique
-PASS Document includes GeometryUtils: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS CharacterData includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS CharacterData includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS Text includes Slottable: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS MediaQueryList interface: existence and properties of interface object
-PASS MediaQueryList interface object length
-PASS MediaQueryList interface object name
-PASS MediaQueryList interface: existence and properties of interface prototype object
-PASS MediaQueryList interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryList interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryList interface: attribute media
-PASS MediaQueryList interface: attribute matches
-PASS MediaQueryList interface: operation addListener(EventListener?)
-PASS MediaQueryList interface: operation removeListener(EventListener?)
-PASS MediaQueryList interface: attribute onchange
-PASS MediaQueryList must be primary interface of matchMedia("all")
-PASS Stringification of matchMedia("all")
-PASS MediaQueryList interface: matchMedia("all") must inherit property "media" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "matches" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "addListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling addListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "removeListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling removeListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "onchange" with the proper type
-PASS MediaQueryListEvent interface: existence and properties of interface object
-PASS MediaQueryListEvent interface object length
-PASS MediaQueryListEvent interface object name
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryListEvent interface: attribute media
-PASS MediaQueryListEvent interface: attribute matches
-PASS MediaQueryListEvent must be primary interface of new MediaQueryListEvent("change")
-PASS Stringification of new MediaQueryListEvent("change")
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "media" with the proper type
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "matches" with the proper type
-FAIL Screen interface: existence and properties of interface object assert_equals: prototype of self's property "Screen" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }"
-PASS Screen interface object length
-PASS Screen interface object name
-FAIL Screen interface: existence and properties of interface prototype object assert_equals: prototype of Screen.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
-PASS Screen interface: existence and properties of interface prototype object's "constructor" property
-PASS Screen interface: existence and properties of interface prototype object's @@unscopables property
-PASS Screen interface: attribute availWidth
-PASS Screen interface: attribute availHeight
-PASS Screen interface: attribute width
-PASS Screen interface: attribute height
-PASS Screen interface: attribute colorDepth
-PASS Screen interface: attribute pixelDepth
-PASS Screen must be primary interface of screen
-PASS Stringification of screen
-PASS Screen interface: screen must inherit property "availWidth" with the proper type
-PASS Screen interface: screen must inherit property "availHeight" with the proper type
-PASS Screen interface: screen must inherit property "width" with the proper type
-PASS Screen interface: screen must inherit property "height" with the proper type
-PASS Screen interface: screen must inherit property "colorDepth" with the proper type
-PASS Screen interface: screen must inherit property "pixelDepth" with the proper type
-FAIL CaretPosition interface: existence and properties of interface object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object length assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object name assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offsetNode assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offset assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: operation getClientRect() assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition must be primary interface of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL Stringification of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offsetNode" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CSSPseudoElement interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-PASS MouseEvent interface: attribute pageX
-PASS MouseEvent interface: attribute pageY
-PASS MouseEvent interface: attribute x
-PASS MouseEvent interface: attribute y
-PASS MouseEvent interface: attribute offsetX
-PASS MouseEvent interface: attribute offsetY
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageY" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type
-PASS HTMLElement interface: attribute offsetParent
-PASS HTMLElement interface: attribute offsetTop
-PASS HTMLElement interface: attribute offsetLeft
-PASS HTMLElement interface: attribute offsetWidth
-PASS HTMLElement interface: attribute offsetHeight
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS HTMLImageElement interface: attribute x
-PASS HTMLImageElement interface: attribute y
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "x" with the proper type
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "y" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Window interface: operation matchMedia(CSSOMString)
-PASS Window interface: attribute screen
-PASS Window interface: operation moveTo(long, long)
-PASS Window interface: operation moveBy(long, long)
-PASS Window interface: operation resizeTo(long, long)
-PASS Window interface: operation resizeBy(long, long)
-PASS Window interface: attribute innerWidth
-PASS Window interface: attribute innerHeight
-PASS Window interface: attribute scrollX
-PASS Window interface: attribute pageXOffset
-PASS Window interface: attribute scrollY
-PASS Window interface: attribute pageYOffset
-PASS Window interface: operation scroll(optional ScrollToOptions)
-PASS Window interface: operation scroll(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollTo(optional ScrollToOptions)
-PASS Window interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollBy(optional ScrollToOptions)
-PASS Window interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Window interface: attribute screenX
-PASS Window interface: attribute screenLeft
-PASS Window interface: attribute screenY
-PASS Window interface: attribute screenTop
-PASS Window interface: attribute outerWidth
-PASS Window interface: attribute outerHeight
-PASS Window interface: attribute devicePixelRatio
-PASS Window interface: window must inherit property "matchMedia(CSSOMString)" with the proper type
-PASS Window interface: calling matchMedia(CSSOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screen" with the proper type
-PASS Window interface: window must inherit property "moveTo(long, long)" with the proper type
-PASS Window interface: calling moveTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "moveBy(long, long)" with the proper type
-PASS Window interface: calling moveBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeTo(long, long)" with the proper type
-PASS Window interface: calling resizeTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeBy(long, long)" with the proper type
-PASS Window interface: calling resizeBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "innerWidth" with the proper type
-PASS Window interface: window must inherit property "innerHeight" with the proper type
-PASS Window interface: window must inherit property "scrollX" with the proper type
-PASS Window interface: window must inherit property "pageXOffset" with the proper type
-PASS Window interface: window must inherit property "scrollY" with the proper type
-PASS Window interface: window must inherit property "pageYOffset" with the proper type
-PASS Window interface: window must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scroll(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scroll(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollTo(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollTo(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollBy(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollBy(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screenX" with the proper type
-PASS Window interface: window must inherit property "screenLeft" with the proper type
-PASS Window interface: window must inherit property "screenY" with the proper type
-PASS Window interface: window must inherit property "screenTop" with the proper type
-PASS Window interface: window must inherit property "outerWidth" with the proper type
-PASS Window interface: window must inherit property "outerHeight" with the proper type
-PASS Window interface: window must inherit property "devicePixelRatio" with the proper type
-PASS Document interface: operation elementFromPoint(double, double)
-PASS Document interface: operation elementsFromPoint(double, double)
-FAIL Document interface: operation caretPositionFromPoint(double, double) assert_own_property: interface prototype object missing non-static operation expected property "caretPositionFromPoint" missing
-PASS Document interface: attribute scrollingElement
-FAIL Document interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Document interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Document interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Document interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Document interface: document must inherit property "elementFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementFromPoint(double, double) on document with too few arguments must throw TypeError
-PASS Document interface: document must inherit property "elementsFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementsFromPoint(double, double) on document with too few arguments must throw TypeError
-FAIL Document interface: document must inherit property "caretPositionFromPoint(double, double)" with the proper type assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-FAIL Document interface: calling caretPositionFromPoint(double, double) on document with too few arguments must throw TypeError assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-PASS Document interface: document must inherit property "scrollingElement" with the proper type
-FAIL Document interface: document must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: calling getBoxQuads(optional BoxQuadOptions) on document with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: document must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Element interface: operation getClientRects()
-PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
-PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
-PASS Element interface: operation scroll(optional ScrollToOptions)
-PASS Element interface: operation scroll(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollTo(optional ScrollToOptions)
-PASS Element interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollBy(optional ScrollToOptions)
-PASS Element interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Element interface: attribute scrollTop
-PASS Element interface: attribute scrollLeft
-PASS Element interface: attribute scrollWidth
-PASS Element interface: attribute scrollHeight
-PASS Element interface: attribute clientTop
-PASS Element interface: attribute clientLeft
-PASS Element interface: attribute clientWidth
-PASS Element interface: attribute clientHeight
-FAIL Element interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Element interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Element interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Text interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Text interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Text interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-FAIL Text interface: document.createTextNode("x") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: calling getBoxQuads(optional BoxQuadOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Range interface: operation getClientRects()
-PASS Range interface: operation getBoundingClientRect()
-PASS Range interface: new Range() must inherit property "getClientRects()" with the proper type
-PASS Range interface: new Range() must inherit property "getBoundingClientRect()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/threaded/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/threaded/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt
deleted file mode 100644
index c882308..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/threaded/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-This is a testharness.js-based test.
-FAIL KeyframeEffect.getKeyframes() returns no frames for various kinds of empty enimations assert_equals: number of frames with empty @keyframes expected 0 but got 2
-PASS KeyframeEffect.getKeyframes() returns expected frames for a simple animation
-PASS KeyframeEffect.getKeyframes() returns frames with expected easing values, when the easing comes from animation-timing-function on the element
-PASS KeyframeEffect.getKeyframes() returns frames with expected easing values, when the easing is specified on each keyframe
-PASS KeyframeEffect.getKeyframes() returns frames with expected easing values, when the easing is specified on some keyframes
-PASS KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is set on the effect using animation-composition on the element
-FAIL KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on each keyframe assert_equals: value of 'composite' on ComputedKeyframe #0 expected "replace" but got "auto"
-FAIL KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on some keyframes assert_equals: value of 'composite' on ComputedKeyframe #0 expected "add" but got "auto"
-PASS KeyframeEffect.getKeyframes() returns expected frames for a simple animation that specifies a single shorthand property
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with a 0% keyframe and no 100% keyframe
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with a 100% keyframe and no 0% keyframe
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with no 0% or 100% keyframe but with a 50% keyframe
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with a partially complete 100% keyframe (because the !important rule is ignored)
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with different properties on different keyframes, all with the same easing function
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with different properties on different keyframes, with a different easing function on each
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time, and all with the same easing function
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different easing functions
-PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different but equivalent easing functions
-FAIL KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different composite operations assert_equals: Number of keyframes should match expected 3 but got 2
-FAIL KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different easing functions and composite operations assert_equals: Number of keyframes should match expected 4 but got 3
-PASS KeyframeEffect.getKeyframes() returns expected frames for overlapping keyframes
-FAIL KeyframeEffect.getKeyframes() returns expected values for animations with filter properties and missing keyframes assert_equals: value for 'filter' on Keyframe #1 should match expected "blur(5px) sepia(60%) saturate(30%)" but got "blur(5px) sepia(0.6) saturate(0.3)"
-PASS KeyframeEffect.getKeyframes() returns expected values for animation with drop-shadow of filter property
-PASS KeyframeEffect.getKeyframes() returns expected values for animations with text-shadow properties and missing keyframes
-PASS KeyframeEffect.getKeyframes() returns expected values for animations with background-size properties and missing keyframes
-PASS KeyframeEffect.getKeyframes() returns expected values for animations with CSS variables as keyframe values
-PASS KeyframeEffect.getKeyframes() returns expected values for animations with CSS variables as keyframe values in a shorthand property
-PASS KeyframeEffect.getKeyframes() returns expected values for animations with a CSS variable which is overriden by the value in keyframe
-PASS KeyframeEffect.getKeyframes() returns expected values for animations with only custom property in a keyframe
-PASS KeyframeEffect.getKeyframes() reflects changes to @keyframes rules
-FAIL KeyframeEffect.getKeyframes() returns expected values for animations with implicit values and a non-default timingfunction specified for 0% and 100% assert_array_equals: properties on Keyframe #0 should match lengths differ, expected array ["composite", "computedOffset", "easing", "offset"] length 4, got ["composite", "computedOffset", "easing", "left", "offset"] length 5
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.png b/third_party/blink/web_tests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
deleted file mode 100644
index 4d8d2d0..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/reference/sticky-anchor-position-invalid-ref.html b/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/reference/sticky-anchor-position-invalid-ref.html
new file mode 100644
index 0000000..3a48755
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/reference/sticky-anchor-position-invalid-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>Anchor queries in sticky positioning is invalid</title>
+<style>
+#scroll-container {
+  width: 200px;
+  height: 200px;
+  overflow-y: scroll;
+}
+
+#scroller {
+  height: 400px;
+}
+
+#sticky {
+  position: sticky;
+  height: 150px;
+  background: green;
+}
+</style>
+<div id="scroll-container">
+  <div id="scroller">
+    <div id="sticky">
+    </div>
+  </div>
+</div>
+<script>
+document.getElementById("scroll-container").scrollTop = 50;
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/sticky-anchor-position-invalid.html b/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/sticky-anchor-position-invalid.html
new file mode 100644
index 0000000..81615d1
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/sticky-anchor-position-invalid.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>Anchor queries in sticky positioning is invalid</title>
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<link rel="help" href="https://tabatkins.github.io/specs/css-anchor-position/#queries">
+<link rel="match" href="reference/sticky-anchor-position-invalid-ref.html">
+<style>
+#scroll-container {
+  width: 200px;
+  height: 200px;
+  overflow-y: scroll;
+}
+
+#scroller {
+  height: 400px;
+}
+
+#sticky {
+  position: sticky;
+  height: 150px;
+  background: green;
+  top: anchor(--invalid top); /* should be invalid and treated as auto */
+}
+</style>
+<div id="scroll-container">
+  <div id="scroller">
+    <div id="sticky">
+    </div>
+  </div>
+</div>
+<script>
+document.getElementById("scroll-container").scrollTop = 50;
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendwithdata.html b/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendwithdata.html
index 950a887..3e0aff1 100644
--- a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendwithdata.html
+++ b/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendwithdata.html
@@ -1,5 +1,6 @@
 <!DOCTYPE html>
 <head>
+<meta charset="utf-8">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/common/utils.js"></script>
@@ -7,26 +8,41 @@
 </head>
 <body>
 <script>
-    promise_test(async t => {
-      const uuid = token();
-      // Random string to test url encoding in beacon.
-      const data = "s1=#&s2=AB ab 12 áəb&s3=\uD800\uDFFF&s4=\0\\\r\n";
+  // Test empty data.
+  beaconSendDataTest("POST", BeaconDataType.String, "",
+                     /*expectEmpty=*/true, "Empty data is not sent.");
+  beaconSendDataTest("POST", BeaconDataType.ArrayBuffer, "",
+                     /*expectEmpty=*/true, "Empty data is not sent.");
+  beaconSendDataTest("POST", BeaconDataType.FormData, "",
+                     /*expectEmpty=*/false, "Empty form payload is sent.");
+  beaconSendDataTest("POST", BeaconDataType.URLSearchParams, "testkey=",
+                     /*expectEmpty=*/false, "Empty query is sent.");
 
-      const base_url = `${location.protocol}//${location.host}`;
-      const beacon_endpoint = `${base_url}/wpt_internal/pending_beacon/resources/set_beacon_data.py?uuid=${uuid}`;
-      let beacon = new PendingBeacon(beacon_endpoint, {method: "GET"});
+  // Test small payload.
+  beaconSendDataTest("POST", BeaconDataType.String, generateSequentialData(0, 1024),
+                     /*expectEmpty=*/false, "Encoded and sent in POST request.");
+  beaconSendDataTest("POST", BeaconDataType.ArrayBuffer, generateSequentialData(0, 1024),
+                     /*expectEmpty=*/false, "Encoded and sent in POST request.");
+  // Skip CRLF chracters which will be normalzied by FormData.
+  beaconSendDataTest("POST", BeaconDataType.FormData, generateSequentialData(0, 1024, "\n\r"),
+                     /*expectEmpty=*/false, "Encoded and sent in POST request.");
+  // Skip reserved URI characters.
+  beaconSendDataTest("POST", BeaconDataType.URLSearchParams,
+                     "testkey="+generateSequentialData(0, 1024, ";,/?:@&=+$"),
+                     /*expectEmpty=*/false, "Encoded and sent in POST request.");
 
-      beacon.setData(data);
-      beacon.sendNow();
-      // Wait for the beacon to have sent.
-      await wait(1000);
+  // TODO(crbug.com/1293679): Test large payload.
 
-      let beacon_data = await getBeaconData(uuid);
-      // PendingBeacon uses application/x-www-form-urlencoded serializer, which encodes space as '+'
-      // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
-      let expected_data = encodeURIComponent(data).replace(/%20/g, "+");
-      assert_equals(beacon_data, expected_data);
-    }, "Verify that beacon data is encoded and sent in GET request.");
+  // Test GET request.
+  beaconSendDataTest("GET", BeaconDataType.String, generateSequentialData(0, 1024),
+                     /*expectEmpty=*/true, "setData() doesn't work for GET request.");
+  beaconSendDataTest("GET", BeaconDataType.ArrayBuffer, generateSequentialData(0, 1024),
+                     /*expectEmpty=*/true, "setData() doesn't work for GET request.");
+  beaconSendDataTest("GET", BeaconDataType.FormData, generateSequentialData(0, 1024, "\n\r"),
+                     /*expectEmpty=*/true, "setData() doesn't work for GET request.");
+  beaconSendDataTest("GET", BeaconDataType.URLSearchParams,
+                     "testkey="+generateSequentialData(0, 1024, ";,/?:@&=+$"),
+                     /*expectEmpty=*/true, "setData() doesn't work for GET request.");
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/pending_beacon-helper.js b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/pending_beacon-helper.js
index 6466d939..f2b6b9e42 100644
--- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/pending_beacon-helper.js
+++ b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/pending_beacon-helper.js
@@ -1,3 +1,53 @@
+'use strict';
+
+function parallelPromiseTest(func, description) {
+  async_test((t) => {
+    Promise.resolve(func(t)).then(() => t.done()).catch(t.step_func((e) => {
+      throw e;
+    }));
+  }, description);
+}
+
+/** @enum {string} */
+const BeaconDataType = {
+  String: 'String',
+  ArrayBuffer: 'ArrayBuffer',
+  FormData: 'FormData',
+  URLSearchParams: 'URLSearchParams',
+};
+
+// Creates beacon data of the given `dataType` from `data`.
+// @param {string} data - A string representation of the beacon data. Note that
+//     it cannot contain UTF-16 surrogates for all `BeaconDataType` except BLOB.
+// @param {BeaconDataType} dataType - must be one of `BeaconDataType`.
+function makeBeaconData(data, dataType) {
+  switch (dataType) {
+    case BeaconDataType.String:
+      return data;
+    case BeaconDataType.ArrayBuffer:
+      return new TextEncoder().encode(data).buffer;
+    case BeaconDataType.FormData:
+      const formData = new FormData();
+      formData.append('payload', data);
+      return formData;
+    case BeaconDataType.URLSearchParams:
+      return new URLSearchParams(data);
+    default:
+      throw Error(`Unsupported beacon dataType: ${dataType}`);
+  }
+}
+
+// Create a string of `end`-`begin` characters, with characters starting from
+// UTF-16 code unit `begin` to `end`-1.
+function generateSequentialData(begin, end, skip) {
+  const codeUnits = Array(end - begin).fill().map((el, i) => i + begin);
+  if (skip) {
+    return String.fromCharCode(
+        ...codeUnits.filter(c => !skip.includes(String.fromCharCode(c))));
+  }
+  return String.fromCharCode(...codeUnits);
+}
+
 function wait(ms) {
   return new Promise(resolve => step_timeout(resolve, ms));
 }
@@ -15,3 +65,34 @@
   const data = await res.text();
   return data;
 }
+
+// Retrieve beacon data for `uuid`, and perform percent-decoding.
+async function getPercentDecodedBeaconData(uuid) {
+  let data = await getBeaconData(uuid);
+  // application/x-www-form-urlencoded serializer encodes space as '+'
+  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
+  data = data.replace(/\+/g, '%20');
+  return decodeURIComponent(data);
+}
+
+function beaconSendDataTest(
+    method, dataType, testData, expectEmpty, description) {
+  parallelPromiseTest(async t => {
+    const uuid = token();
+    const baseUrl = `${location.protocol}//${location.host}`;
+    const url = `${
+        baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_data.py?uuid=${
+        uuid}`;
+    let beacon = new PendingBeacon(url, {method: method});
+
+    beacon.setData(makeBeaconData(testData, dataType));
+    beacon.sendNow();
+    // Wait for the beacon to have sent.
+    await wait(1000);
+
+    const sentData = dataType === BeaconDataType.URLSearchParams ?
+        await getPercentDecodedBeaconData(uuid) :
+        await getBeaconData(uuid);
+    assert_equals(sentData, expectEmpty ? '<NO-DATA>' : testData);
+  }, `Beacon data of type "${dataType}": ${description}`);
+}
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_data.py b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_data.py
index 7da8a9715..7c5bcbca 100644
--- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_data.py
+++ b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_data.py
@@ -11,8 +11,12 @@
         response.status = 400
         return 'Must provide a UUID to store beacon data'
     uuid = request.GET.first(b'uuid')
-    # We want raw text input for 'data' from url instead of byte-encoded one.
-    data = re.search(r'data=(.+)$', request.url_parts.query).groups()[0]
+    if b'multipart/form-data' in request.headers.get(b'Content-Type', b''):
+        data = request.POST.first(b'payload')
+    elif request.body:
+        data = request.body
+    else:
+        data = '<NO-DATA>'
 
     with request.server.stash.lock:
         request.server.stash.put(key=uuid, value=data, path='beacondata')
diff --git a/third_party/ots/README.chromium b/third_party/ots/README.chromium
index 23f4083e3..79b4c16 100644
--- a/third_party/ots/README.chromium
+++ b/third_party/ots/README.chromium
@@ -1,6 +1,6 @@
 Name: OTS (OpenType Sanitizer)
 URL: https://github.com/khaledhosny/ots.git
-Version: ee537ac096667eed6559124164c3e8482646fd77
+Version: 46bea9879127d0ff1c6601b078e2ce98e83fcd33
 Security Critical: yes
 License: BSD
 
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 736268ee..144e9142 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -167,6 +167,7 @@
       'lacros-amd64-generic-binary-size-rel': 'chromeos_amd64-generic_lacros_rel_reclient',
       'lacros-amd64-generic-rel': 'chromeos_amd64-generic_lacros_rel_reclient',
       'lacros-arm-generic-rel': 'chromeos_arm-generic_lacros_rel_reclient',
+      'lacros-arm64-generic-rel': 'chromeos_arm64-generic_lacros_rel_reclient',
       'linux-ash-chromium-generator-rel': 'chromeos_with_codecs_release_bot',
       'linux-cfm-rel': 'linux_cfm_release_bot_reclient',
       'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot_reclient',
@@ -313,11 +314,9 @@
 
     'chromium.fyi': {
       'Afl Upload Linux ASan': 'afl_asan_shared_release_bot',
-      # Keep in sync with android-pie-arm64-rel, but with reclient.
+      # TODO(b/234807316): Remove after renaming the builders.
       'Build Perf Android': 'android_release_trybot_arm64_webview_monochrome_expectations_fastbuild_reclient',
-      # Keep in sync with linux-rel, but with reclient.
       'Build Perf Linux': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage_do_typecheck_reclient',
-      # Keep in sync with win10_chromium_x64_rel_ng, but with reclient.
       'Build Perf Windows': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage_reclient',
       'CFI Linux CF (reclient shadow)': 'cfi_full_cfi_icall_cfi_diag_recover_release_static_reclient',
       'Comparison Android (reclient)': {
@@ -387,6 +386,12 @@
       'android-code-coverage': 'gpu_tests_android_release_bot_minimal_symbols_arm64_fastbuild_java_coverage_reclient',
       'android-code-coverage-native': 'gpu_tests_android_release_bot_no_symbols_arm64_fastbuild_native_coverage_reclient',
       'android-fieldtrial-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient',
+      # Keep in sync with android-pie-arm64-rel, but with reclient.
+      'build-perf-android': 'android_release_trybot_arm64_webview_monochrome_expectations_fastbuild_reclient',
+      # Keep in sync with linux-rel, but with reclient.
+      'build-perf-linux': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage_do_typecheck_reclient',
+      # Keep in sync with win10_chromium_x64_rel_ng, but with reclient.
+      'build-perf-windows': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage_reclient',
       'chromeos-amd64-generic-rel (goma cache silo)': 'chromeos_amd64-generic_use_fake_dbus_clients',
       # TODO(crbug.com/1235218): remove after the migration.
       'chromeos-amd64-generic-rel (reclient compare)': 'chromeos_amd64-generic-vm_use_fake_dbus_clients_reclient',
@@ -1038,6 +1043,7 @@
       'gpu-fyi-try-chromeos-zork-exp': 'gpu_tests_chromeos_zork_release_trybot',
       'lacros-amd64-generic-rel': 'chromeos_amd64-generic_lacros_rel_dchecks',
       'lacros-arm-generic-rel': 'chromeos_arm-generic_lacros_rel_dchecks',
+      'lacros-arm64-generic-rel': 'chromeos_arm64-generic_lacros_rel_dchecks',
       'linux-cfm-rel': 'linux_cfm_release_trybot',
       'linux-chromeos-annotator-rel': 'chromeos_with_codecs_release_trybot_code_coverage',
       'linux-chromeos-compile-dbg': 'chromeos_with_codecs_debug_bot',
@@ -2110,6 +2116,14 @@
       'chromeos_arm64-generic-crostoolchain', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto',
     ],
 
+    'chromeos_arm64-generic_lacros_rel_dchecks': [
+      'chromeos_arm64-generic-crostoolchain', 'lacros', 'release', 'dcheck_always_on',
+    ],
+
+    'chromeos_arm64-generic_lacros_rel_reclient': [
+      'chromeos_arm64-generic-crostoolchain_reclient', 'lacros', 'release',
+    ],
+
     'chromeos_asan_lsan_fuzzer_v8_heap_release_bot_reclient': [
       'chromeos', 'asan', 'lsan', 'fuzzer', 'v8_heap', 'release_bot_reclient',
     ],
@@ -3789,6 +3803,10 @@
       'mixins': ['chromeos_device', 'arm64-generic-crostoolchain',]
     },
 
+    'chromeos_arm64-generic-crostoolchain_reclient': {
+      'mixins': ['chromeos_device_reclient', 'arm64-generic-crostoolchain',]
+    },
+
     'chromeos_codecs': {
       'mixins': ['ffmpeg_branding_chromeos', 'proprietary_codecs'],
     },
diff --git a/tools/mb/mb_config_expectations/chromium.chromiumos.json b/tools/mb/mb_config_expectations/chromium.chromiumos.json
index abdfa8f..b5e0466 100644
--- a/tools/mb/mb_config_expectations/chromium.chromiumos.json
+++ b/tools/mb/mb_config_expectations/chromium.chromiumos.json
@@ -156,6 +156,18 @@
       "use_remoteexec": true
     }
   },
+  "lacros-arm64-generic-rel": {
+    "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
+    "gn_args": {
+      "chromeos_is_browser_only": true,
+      "dcheck_always_on": false,
+      "is_chromeos_device": true,
+      "is_debug": false,
+      "ozone_platform_headless": true,
+      "target_os": "chromeos",
+      "use_remoteexec": true
+    }
+  },
   "linux-ash-chromium-generator-rel": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 7a76d5d..42b9c658 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -713,6 +713,54 @@
       "use_remoteexec": true
     }
   },
+  "build-perf-android": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "disable_android_lint": true,
+      "fail_on_android_expectations": true,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "skip_secondary_abi_for_cq": true,
+      "strip_debug_info": true,
+      "symbol_level": 0,
+      "system_webview_package_name": "com.google.android.apps.chrome",
+      "target_cpu": "arm64",
+      "target_os": "android",
+      "use_errorprone_java_compiler": false,
+      "use_remoteexec": true
+    }
+  },
+  "build-perf-linux": {
+    "gn_args": {
+      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
+      "dcheck_always_on": true,
+      "devtools_skip_typecheck": false,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "symbol_level": 0,
+      "use_clang_coverage": true,
+      "use_dummy_lastchange": true,
+      "use_remoteexec": true
+    }
+  },
+  "build-perf-windows": {
+    "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
+    }
+  },
   "chromeos-amd64-generic-rel (goma cache silo)": {
     "args_file": "//build/args/chromeos/amd64-generic.gni",
     "gn_args": {
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
index f5ea9d0..c590070 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
@@ -199,6 +199,18 @@
       "use_goma": true
     }
   },
+  "lacros-arm64-generic-rel": {
+    "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
+    "gn_args": {
+      "chromeos_is_browser_only": true,
+      "dcheck_always_on": true,
+      "is_chromeos_device": true,
+      "is_debug": false,
+      "ozone_platform_headless": true,
+      "target_os": "chromeos",
+      "use_goma": true
+    }
+  },
   "linux-cfm-rel": {
     "gn_args": {
       "dcheck_always_on": true,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index bd8483b2..ef44abc 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -52612,6 +52612,11 @@
   <int value="5" label="Http Error"/>
 </enum>
 
+<enum name="KioskBrowserWindowType">
+  <int value="0" label="Settings Page"/>
+  <int value="1" label="Other, immediately closed"/>
+</enum>
+
 <enum name="KioskLaunchError">
   <int value="0" label="No error"/>
   <int value="1" label="Has pending launch"/>
@@ -52638,6 +52643,12 @@
   <int value="3" label="Consumer manual launch"/>
 </enum>
 
+<enum name="KioskLowDiskSeverity">
+  <int value="0" label="None"/>
+  <int value="1" label="Medium severity"/>
+  <int value="2" label="High severity"/>
+</enum>
+
 <enum name="KioskNextHomeBridgeAction">
   <int value="0" label="List apps"/>
   <int value="1" label="Launch app"/>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml
index cf62e90f..5cde9b2 100644
--- a/tools/metrics/histograms/metadata/arc/histograms.xml
+++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -1736,7 +1736,7 @@
 </histogram>
 
 <histogram name="Arc.Runtime.Performance.Generic.Jankiness" units="%"
-    expires_after="2022-11-06">
+    expires_after="2023-01-08">
   <owner>camurcu@google.com</owner>
   <owner>khmel@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 6f95a0a..554a3d37 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="Compositing.Browser.GPUMemoryForTilingsInKb" units="Kb"
-    expires_after="2022-11-09">
+    expires_after="2023-01-08">
   <owner>pdr@chromium.org</owner>
   <owner>paint-dev@chromium.org</owner>
   <owner>sky@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml
index d3264ba..e709675 100644
--- a/tools/metrics/histograms/metadata/content/histograms.xml
+++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -988,6 +988,24 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.Feed.SessionDuration" units="ms"
+    expires_after="2022-10-01">
+  <owner>edchin@google.com</owner>
+  <owner>sczs@chromium.org</owner>
+  <owner>feed@chromium.org</owner>
+  <summary>
+    The amount of time a user spends in the feed in a single session. A session
+    is measured only by user interactions or user scrolling events in the feed.
+    Two events are considered as being within the same session if they are at
+    most 5 minutes apart from each other. A series of events is likely to
+    constitute a single session. A user opening the feed but having no
+    interaction and not scrolling is not considered a session. A user tapping an
+    article then quickly returning to the feed is considered within the same
+    session. The time between sessions by definition will be longer than 5
+    minutes.
+  </summary>
+</histogram>
+
 <histogram name="ContentSuggestions.Feed.Task.DelayTime" units="ms"
     expires_after="2020-10-01">
   <owner>carlosk@chromium.org</owner>
@@ -1008,6 +1026,28 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.Feed.TimeBetweenInteractions" units="ms"
+    expires_after="2022-10-01">
+  <owner>edchin@google.com</owner>
+  <owner>sczs@chromium.org</owner>
+  <owner>feed@chromium.org</owner>
+  <summary>
+    The amount of time between user interactions or user scrolling in the feed.
+  </summary>
+</histogram>
+
+<histogram name="ContentSuggestions.Feed.TimeBetweenSessions" units="ms"
+    expires_after="2022-10-01">
+  <owner>edchin@google.com</owner>
+  <owner>sczs@chromium.org</owner>
+  <owner>feed@chromium.org</owner>
+  <summary>
+    The amount of time between user feed sessions, as defined in
+    |ContentSuggestions.Feed.SessionDuration|. This is by definition longer than
+    5 minutes.
+  </summary>
+</histogram>
+
 <histogram name="ContentSuggestions.Feed.TimeSpentInFeed" units="ms"
     expires_after="2023-03-01">
   <owner>carlosk@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/cros_ml/histograms.xml b/tools/metrics/histograms/metadata/cros_ml/histograms.xml
index c99afc2..7376732 100644
--- a/tools/metrics/histograms/metadata/cros_ml/histograms.xml
+++ b/tools/metrics/histograms/metadata/cros_ml/histograms.xml
@@ -155,7 +155,7 @@
 </histogram>
 
 <histogram name="MachineLearningService.NumWorkerProcess" units="count"
-    expires_after="2022-11-08">
+    expires_after="2023-01-08">
   <owner>alanlxl@chromium.org</owner>
   <owner>amoylan@chromium.org</owner>
   <owner>honglinyu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index 6adef83..51f8b92a 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -1597,7 +1597,7 @@
 </histogram>
 
 <histogram name="Media.AudioRendererAudioGlitches" enum="AudioGlitchResult"
-    expires_after="2023-01-01">
+    expires_after="2023-01-08">
   <owner>henrika@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
@@ -1640,7 +1640,7 @@
 </histogram>
 
 <histogram name="Media.AudioRendererMissedDeadline" units="%"
-    expires_after="2023-01-01">
+    expires_after="2023-01-08">
   <owner>dalecurtis@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 2bd2fa0..1d27c0a 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -7135,6 +7135,17 @@
   </summary>
 </histogram>
 
+<histogram name="Kiosk.NewBrowserWindow" enum="KioskBrowserWindowType"
+    expires_after="2023-07-01">
+  <owner>pbond@chromium.org</owner>
+  <owner>chromeos-kiosk-eng@google.com</owner>
+  <summary>
+    ChromeOS only. Records a new browser window type once a new browser window
+    is attempted to be shown in a kiosk session. Currently distinguishes only
+    settings page from others, which get closed immediately.
+  </summary>
+</histogram>
+
 <histogram name="Kiosk.SecondaryApps.InstallSuccessful" enum="BooleanYesNo"
     expires_after="2022-10-01">
   <owner>yixie@chromium.org</owner>
@@ -7155,6 +7166,27 @@
   </summary>
 </histogram>
 
+<histogram name="Kiosk.Session.LowDiskHighestSeverity"
+    enum="KioskLowDiskSeverity" expires_after="2023-07-01">
+  <owner>pbond@chromium.org</owner>
+  <owner>chromeos-kiosk-eng@chromium.org</owner>
+  <summary>
+    ChromeOS only. Records the highest severity of low disk notification of a
+    kiosk session. Logged on every kiosk session start, even if there was no
+    notification during the last session.
+  </summary>
+</histogram>
+
+<histogram name="Kiosk.Session.LowDiskSeverity" enum="KioskLowDiskSeverity"
+    expires_after="2023-07-01">
+  <owner>pbond@chromium.org</owner>
+  <owner>chromeos-kiosk-eng@chromium.org</owner>
+  <summary>
+    ChromeOS only. Records low disk notifications being issued. Logged once a
+    low disk notification is supposed to be shown.
+  </summary>
+</histogram>
+
 <histogram name="Kiosk.Session.NetworkDrops" units="network drops"
     expires_after="2023-06-01">
   <owner>pbond@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml
index 46d95d0..ed1c5c1b 100644
--- a/tools/metrics/histograms/metadata/security/histograms.xml
+++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -211,7 +211,7 @@
 </histogram>
 
 <histogram name="Security.PageInfo.AboutThisSiteLanguageSupported"
-    enum="Boolean" expires_after="M106">
+    enum="Boolean" expires_after="M109">
   <owner>dullweber@chromium.org</owner>
   <owner>olesiamarukhno@chromium.org</owner>
   <summary>
@@ -231,7 +231,7 @@
 </histogram>
 
 <histogram name="Security.PageInfo.AdPersonalizationRowShown" enum="Boolean"
-    expires_after="M106">
+    expires_after="M109">
   <owner>dullweber@chromium.org</owner>
   <owner>sauski@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml
index 22b4b8ca..38ba2c0 100644
--- a/tools/metrics/histograms/metadata/startup/histograms.xml
+++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -68,7 +68,7 @@
 
 <histogram
     name="Startup.Android.Cold.FirstNavigationCommitOccurredPreForeground"
-    enum="Boolean" expires_after="2022-11-06">
+    enum="Boolean" expires_after="2023-01-08">
   <owner>blundell@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/v8/histograms.xml b/tools/metrics/histograms/metadata/v8/histograms.xml
index 2b4f064..dabe242b 100644
--- a/tools/metrics/histograms/metadata/v8/histograms.xml
+++ b/tools/metrics/histograms/metadata/v8/histograms.xml
@@ -1914,7 +1914,7 @@
 </histogram>
 
 <histogram name="V8.WasmModuleCodeSizeBaselineMiB" units="MB"
-    expires_after="2022-11-06">
+    expires_after="2023-01-08">
   <owner>ecmziegler@chromium.org</owner>
   <owner>adamk@chromium.org</owner>
   <owner>clemensb@chromium.org</owner>
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index ce5070e..08b3a17 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -1277,7 +1277,7 @@
         False,
     },
     'chromeos-amd64-generic-lacros-builder-perf': {
-        'additional_compile_targets': ['chrome', 'lacros_version_metadata'],
+        'additional_compile_targets': ['chrome'],
         'tests': [
             {
                 'name': 'resource_sizes_lacros_chrome',
@@ -1300,7 +1300,7 @@
         False,
     },
     'chromeos-arm-generic-lacros-builder-perf': {
-        'additional_compile_targets': ['chrome', 'lacros_version_metadata'],
+        'additional_compile_targets': ['chrome'],
         'tests': [
             {
                 'name': 'resource_sizes_lacros_chrome',
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index c54703a..c6aca82 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "543c64f0b18b9204d9d4b6204598a24ed66a1636",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/20b95850d84373133774c7d5df2fbb3c72a6b9dc/trace_processor_shell.exe"
+            "hash": "35d71a5ec1d6a8280aa8a87f34f1933e65ce42fb",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/16cf103dc64ba20ab554e6a6e1b4d79f469332eb/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "36209732f3066a36998c64bfacaea70a4e3aaaf2",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/da38394c89d9a32213450440e43b9449bb243309/trace_processor_shell"
+            "hash": "6967f4979c17be5fc625f0e114b41dc1e15a3b40",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/16cf103dc64ba20ab554e6a6e1b4d79f469332eb/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
             "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "2903b32cf89cabae0f83e2c890fae73d52442476",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/da38394c89d9a32213450440e43b9449bb243309/trace_processor_shell"
+            "hash": "ee9db168e96229cf412b325859bc62d57d929f9a",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/16cf103dc64ba20ab554e6a6e1b4d79f469332eb/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/events/fuchsia/fakes/pointer_event_utility.cc b/ui/events/fuchsia/fakes/pointer_event_utility.cc
index 59d8bcf..9896361 100644
--- a/ui/events/fuchsia/fakes/pointer_event_utility.cc
+++ b/ui/events/fuchsia/fakes/pointer_event_utility.cc
@@ -100,7 +100,9 @@
     uint32_t id,
     std::array<float, 2> position,
     std::vector<uint8_t> pressed_buttons,
-    std::array<int64_t, 2> scroll) {
+    std::array<int64_t, 2> scroll,
+    std::array<int64_t, 2> scroll_in_physical_pixel,
+    bool is_precision_scroll) {
   sample_ = absl::make_optional<fup::MousePointerSample>();
   sample_->set_device_id(id);
   if (!pressed_buttons.empty()) {
@@ -113,6 +115,13 @@
   if (scroll[1] != 0) {
     sample_->set_scroll_v(scroll[1]);
   }
+  if (scroll_in_physical_pixel[0] != 0) {
+    sample_->set_scroll_h_physical_pixel(scroll_in_physical_pixel[0]);
+  }
+  if (scroll_in_physical_pixel[1] != 0) {
+    sample_->set_scroll_v_physical_pixel(scroll_in_physical_pixel[1]);
+  }
+  sample_->set_is_precision_scroll(is_precision_scroll);
   return *this;
 }
 
diff --git a/ui/events/fuchsia/fakes/pointer_event_utility.h b/ui/events/fuchsia/fakes/pointer_event_utility.h
index 627e2d8..8d690b7 100644
--- a/ui/events/fuchsia/fakes/pointer_event_utility.h
+++ b/ui/events/fuchsia/fakes/pointer_event_utility.h
@@ -53,7 +53,9 @@
   MouseEventBuilder& AddSample(uint32_t id,
                                std::array<float, 2> position,
                                std::vector<uint8_t> pressed_buttons,
-                               std::array<int64_t, 2> scroll);
+                               std::array<int64_t, 2> scroll,
+                               std::array<int64_t, 2> scroll_in_physical_pixel,
+                               bool is_precision_scroll);
   MouseEventBuilder& AddViewParameters(
       std::array<std::array<float, 2>, 2> view,
       std::array<std::array<float, 2>, 2> viewport,
diff --git a/ui/events/fuchsia/pointer_events_handler.cc b/ui/events/fuchsia/pointer_events_handler.cc
index c26a72e..a6d4ec2 100644
--- a/ui/events/fuchsia/pointer_events_handler.cc
+++ b/ui/events/fuchsia/pointer_events_handler.cc
@@ -233,20 +233,43 @@
   if (event_type == ET_MOUSEWHEEL) {
     // TODO(fxbug.dev/92938): Maybe also support ctrl+wheel event here.
 
-    // Fuchsia reports wheel rotated ticks, multiple |kWheelDelta| for pixel
-    // offset.
-    const int offset_x = sample.has_scroll_h()
-                             ? static_cast<int>(sample.scroll_h()) * kWheelDelta
-                             : 0;
-    const int offset_y = sample.has_scroll_v()
-                             ? static_cast<int>(sample.scroll_v()) * kWheelDelta
-                             : 0;
+    const int tick_x_120ths =
+        sample.has_scroll_h()
+            ? static_cast<int>(sample.scroll_h()) * kWheelDelta
+            : 0;
+    const int tick_y_120ths =
+        sample.has_scroll_v()
+            ? static_cast<int>(sample.scroll_v()) * kWheelDelta
+            : 0;
 
-    // TODO(fxbug.dev/85388): If mouse wheel has by detent(tick) scroll offset,
-    // we can fill them into |tick_120ths|.
+    // Fuchsia reports suggested scroll pixel in physical, but for old version,
+    // Fuchsia reports wheel rotated ticks need to multiple |kWheelDelta| for
+    // pixel offset.
+    const float offset_x =
+        sample.has_scroll_h_physical_pixel()
+            ? static_cast<float>(sample.scroll_h_physical_pixel())
+            : static_cast<float>(tick_x_120ths);
+    const float offset_y =
+        sample.has_scroll_v_physical_pixel()
+            ? static_cast<float>(sample.scroll_v_physical_pixel())
+            : static_cast<float>(tick_y_120ths);
+
+    if (sample.has_is_precision_scroll() && sample.is_precision_scroll()) {
+      // For precision scroll device, mostly are touchpads for now, need to use
+      // ScrollEvent instead of MouseWheelEvent to prevent animation
+      // interpolation in smooth scrolling.
+      // Because we only support touchpad as precision scroll device now,
+      // finger_count is 2. Maybe need to use different number when we support
+      // precision wheel mouse.
+      return std::make_unique<ScrollEvent>(
+          ui::ET_SCROLL, location, root_location, timestamp,
+          pressed_buttons_flags, offset_x, offset_y, offset_x, offset_y,
+          /*finger_count=*/2);
+    }
     return std::make_unique<MouseWheelEvent>(
-        gfx::Vector2d(offset_x, offset_y), location, root_location, timestamp,
-        pressed_buttons_flags, changed_buttons_flags);
+        gfx::Vector2d(static_cast<int>(offset_x), static_cast<int>(offset_y)),
+        location, root_location, timestamp, pressed_buttons_flags,
+        changed_buttons_flags, gfx::Vector2d(tick_x_120ths, tick_y_120ths));
   }
   return std::make_unique<MouseEvent>(event_type, location, root_location,
                                       timestamp, pressed_buttons_flags,
diff --git a/ui/events/fuchsia/pointer_events_handler_unittest.cc b/ui/events/fuchsia/pointer_events_handler_unittest.cc
index e6f4ddb..ac85321 100644
--- a/ui/events/fuchsia/pointer_events_handler_unittest.cc
+++ b/ui/events/fuchsia/pointer_events_handler_unittest.cc
@@ -38,6 +38,11 @@
                                              .interaction_id = 2u};
 constexpr uint32_t kMouseDeviceId = 123;
 
+constexpr std::array<int64_t, 2> kNoScrollDelta = {0, 0};
+constexpr std::array<int64_t, 2> kNoScrollInPhysicalPixelDelta = {0, 0};
+const bool kNotPrecisionScroll = false;
+const bool kPrecisionScroll = true;
+
 // Fixture to exercise the implementation for fuchsia.ui.pointer.TouchSource and
 // fuchsia.ui.pointer.MouseSource.
 class PointerEventsHandlerTest : public ::testing::Test {
@@ -90,7 +95,8 @@
       MouseEventBuilder()
           .AddTime(1111789u)
           .AddViewParameters(kRect, kRect, kIdentity)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 0})
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, kNoScrollDelta,
+                     kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
           .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
           .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(mouse_events));
@@ -139,7 +145,9 @@
       MouseEventBuilder()
           .AddTime(1111789u)
           .AddViewParameters(kRect, kRect, kIdentity)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/}, {0, 0})
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/},
+                     kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                     kNotPrecisionScroll)
           .AddMouseDeviceInfo(kMouseDeviceId,
                               {2 /*first button id*/, 0 /*second button id*/,
                                1 /*third button id*/})
@@ -154,11 +162,12 @@
 
   // Keep Fuchsia button press -> Chrome ET_MOUSE_DRAGGED and
   // EF_RIGHT_MOUSE_BUTTON
-  events =
-      MouseEventBuilder()
-          .AddTime(1111789u)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/}, {0, 0})
-          .BuildAsVector();
+  events = MouseEventBuilder()
+               .AddTime(1111789u)
+               .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/},
+                          kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                          kNotPrecisionScroll)
+               .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
   RunLoopUntilIdle();
 
@@ -170,7 +179,8 @@
   // Release Fuchsia button -> Chrome ET_MOUSE_RELEASED
   events = MouseEventBuilder()
                .AddTime(1111789u)
-               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 0})
+               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, kNoScrollDelta,
+                          kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
                .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
   RunLoopUntilIdle();
@@ -183,7 +193,8 @@
   // Release Fuchsia button -> Chrome ET_MOUSE_MOVED
   events = MouseEventBuilder()
                .AddTime(1111789u)
-               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 0})
+               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, kNoScrollDelta,
+                          kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
                .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
   RunLoopUntilIdle();
@@ -207,7 +218,8 @@
       MouseEventBuilder()
           .AddTime(1111789u)
           .AddViewParameters(kRect, kRect, kIdentity)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 0})
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, kNoScrollDelta,
+                     kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
           .AddMouseDeviceInfo(kMouseDeviceId, {2, 0, 1})
           .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
@@ -222,7 +234,8 @@
   // EF_LEFT_MOUSE_BUTTON
   events = MouseEventBuilder()
                .AddTime(1111789u)
-               .AddSample(kMouseDeviceId, {10.f, 10.f}, {2}, {0, 0})
+               .AddSample(kMouseDeviceId, {10.f, 10.f}, {2}, kNoScrollDelta,
+                          kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
                .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
   RunLoopUntilIdle();
@@ -249,7 +262,8 @@
       MouseEventBuilder()
           .AddTime(1111789u)
           .AddViewParameters(kRect, kRect, kIdentity)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0, 1}, {0, 0})
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0, 1}, kNoScrollDelta,
+                     kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
           .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
           .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
@@ -276,38 +290,50 @@
   events.push_back(MouseEventBuilder()
                        .AddTime(1111789u)
                        .AddViewParameters(kRect, kRect, kIdentity)
-                       .AddSample(kMouseDeviceId, {10.f, 10.f}, {0, 1}, {0, 0})
+                       .AddSample(kMouseDeviceId, {10.f, 10.f}, {0, 1},
+                                  kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                                  kNotPrecisionScroll)
                        .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
                        .Build());
   // drag with left, right button pressing.
   events.push_back(MouseEventBuilder()
                        .AddTime(1111790u)
                        .AddViewParameters(kRect, kRect, kIdentity)
-                       .AddSample(kMouseDeviceId, {11.f, 10.f}, {0, 1}, {0, 0})
+                       .AddSample(kMouseDeviceId, {11.f, 10.f}, {0, 1},
+                                  kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                                  kNotPrecisionScroll)
                        .Build());
   // right button up.
   events.push_back(MouseEventBuilder()
                        .AddTime(1111791u)
                        .AddViewParameters(kRect, kRect, kIdentity)
-                       .AddSample(kMouseDeviceId, {11.f, 10.f}, {0}, {0, 0})
+                       .AddSample(kMouseDeviceId, {11.f, 10.f}, {0},
+                                  kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                                  kNotPrecisionScroll)
                        .Build());
   // drag with left button pressing.
   events.push_back(MouseEventBuilder()
                        .AddTime(1111792u)
                        .AddViewParameters(kRect, kRect, kIdentity)
-                       .AddSample(kMouseDeviceId, {11.f, 11.f}, {0}, {0, 0})
+                       .AddSample(kMouseDeviceId, {11.f, 11.f}, {0},
+                                  kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                                  kNotPrecisionScroll)
                        .Build());
   // left button up.
   events.push_back(MouseEventBuilder()
                        .AddTime(11117913u)
                        .AddViewParameters(kRect, kRect, kIdentity)
-                       .AddSample(kMouseDeviceId, {11.f, 11.f}, {}, {0, 0})
+                       .AddSample(kMouseDeviceId, {11.f, 11.f}, {},
+                                  kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                                  kNotPrecisionScroll)
                        .Build());
   // mouse move.
   events.push_back(MouseEventBuilder()
                        .AddTime(1111794u)
                        .AddViewParameters(kRect, kRect, kIdentity)
-                       .AddSample(kMouseDeviceId, {12.f, 11.f}, {}, {0, 0})
+                       .AddSample(kMouseDeviceId, {12.f, 11.f}, {},
+                                  kNoScrollDelta, kNoScrollInPhysicalPixelDelta,
+                                  kNotPrecisionScroll)
                        .Build());
 
   mouse_source_->ScheduleCallback(std::move(events));
@@ -346,7 +372,8 @@
       MouseEventBuilder()
           .AddTime(1111789u)
           .AddViewParameters(kRect, kRect, kIdentity)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 1})
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 1},
+                     kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
           .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
           .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
@@ -363,7 +390,8 @@
   events = MouseEventBuilder()
                .AddTime(1111789u)
                .AddViewParameters(kRect, kRect, kIdentity)
-               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {1, 0})
+               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {1, 0},
+                          kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
                .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
                .BuildAsVector();
   mouse_source_->ScheduleCallback(std::move(events));
@@ -377,6 +405,100 @@
   mouse_events.clear();
 }
 
+TEST_F(PointerEventsHandlerTest, MouseWheelEventDeltaInPhysicalPixel) {
+  std::vector<MouseWheelEvent> mouse_events;
+  pointer_handler_->StartWatching(
+      base::BindLambdaForTesting([&mouse_events](Event* event) {
+        ASSERT_EQ(event->type(), ET_MOUSEWHEEL);
+        mouse_events.push_back(*event->AsMouseWheelEvent());
+      }));
+  RunLoopUntilIdle();  // Server gets watch call.
+
+  // receive a vertical scroll
+  std::vector<fup::MouseEvent> events =
+      MouseEventBuilder()
+          .AddTime(1111789u)
+          .AddViewParameters(kRect, kRect, kIdentity)
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 1}, {0, 100},
+                     kNotPrecisionScroll)
+          .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
+          .BuildAsVector();
+  mouse_source_->ScheduleCallback(std::move(events));
+  RunLoopUntilIdle();
+
+  ASSERT_EQ(mouse_events.size(), 1u);
+  EXPECT_EQ(mouse_events[0].type(), ET_MOUSEWHEEL);
+  EXPECT_EQ(mouse_events[0].flags(), EF_NONE);
+  EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->x_offset(), 0);
+  EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->y_offset(), 100);
+  mouse_events.clear();
+
+  // receive a horizontal scroll
+  events = MouseEventBuilder()
+               .AddTime(1111789u)
+               .AddViewParameters(kRect, kRect, kIdentity)
+               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {1, 0}, {100, 0},
+                          kNotPrecisionScroll)
+               .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
+               .BuildAsVector();
+  mouse_source_->ScheduleCallback(std::move(events));
+  RunLoopUntilIdle();
+
+  ASSERT_EQ(mouse_events.size(), 1u);
+  EXPECT_EQ(mouse_events[0].type(), ET_MOUSEWHEEL);
+  EXPECT_EQ(mouse_events[0].flags(), EF_NONE);
+  EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->x_offset(), 100);
+  EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->y_offset(), 0);
+  mouse_events.clear();
+}
+
+TEST_F(PointerEventsHandlerTest, ScrollEventDeltaInPhysicalPixel) {
+  std::vector<ScrollEvent> mouse_events;
+  pointer_handler_->StartWatching(
+      base::BindLambdaForTesting([&mouse_events](Event* event) {
+        ASSERT_EQ(event->type(), ET_SCROLL);
+        mouse_events.push_back(*event->AsScrollEvent());
+      }));
+  RunLoopUntilIdle();  // Server gets watch call.
+
+  // receive a vertical scroll
+  std::vector<fup::MouseEvent> events =
+      MouseEventBuilder()
+          .AddTime(1111789u)
+          .AddViewParameters(kRect, kRect, kIdentity)
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 1}, {0, 100},
+                     kPrecisionScroll)
+          .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
+          .BuildAsVector();
+  mouse_source_->ScheduleCallback(std::move(events));
+  RunLoopUntilIdle();
+
+  ASSERT_EQ(mouse_events.size(), 1u);
+  EXPECT_EQ(mouse_events[0].type(), ET_SCROLL);
+  EXPECT_EQ(mouse_events[0].flags(), EF_NONE);
+  EXPECT_EQ(mouse_events[0].AsScrollEvent()->x_offset(), 0);
+  EXPECT_EQ(mouse_events[0].AsScrollEvent()->y_offset(), 100);
+  mouse_events.clear();
+
+  // receive a horizontal scroll
+  events = MouseEventBuilder()
+               .AddTime(1111789u)
+               .AddViewParameters(kRect, kRect, kIdentity)
+               .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {1, 0}, {100, 0},
+                          kPrecisionScroll)
+               .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
+               .BuildAsVector();
+  mouse_source_->ScheduleCallback(std::move(events));
+  RunLoopUntilIdle();
+
+  ASSERT_EQ(mouse_events.size(), 1u);
+  EXPECT_EQ(mouse_events[0].type(), ET_SCROLL);
+  EXPECT_EQ(mouse_events[0].flags(), EF_NONE);
+  EXPECT_EQ(mouse_events[0].AsScrollEvent()->x_offset(), 100);
+  EXPECT_EQ(mouse_events[0].AsScrollEvent()->y_offset(), 0);
+  mouse_events.clear();
+}
+
 TEST_F(PointerEventsHandlerTest, MouseWheelEventWithButtonPressed) {
   std::vector<std::unique_ptr<Event>> mouse_events;
   pointer_handler_->StartWatching(
@@ -399,7 +521,8 @@
       MouseEventBuilder()
           .AddTime(1111000u)
           .AddViewParameters(kRect, kRect, kIdentity)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 0})
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, kNoScrollDelta,
+                     kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
           .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
           .BuildAsVector();
 
@@ -407,7 +530,9 @@
   events.push_back(MouseEventBuilder()
                        .AddTime(1111789u)
                        .AddViewParameters(kRect, kRect, kIdentity)
-                       .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 1})
+                       .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 1},
+                                  kNoScrollInPhysicalPixelDelta,
+                                  kNotPrecisionScroll)
                        .Build());
   mouse_source_->ScheduleCallback(std::move(events));
 
@@ -446,7 +571,8 @@
       MouseEventBuilder()
           .AddTime(1111000u)
           .AddViewParameters(kRect, kRect, kIdentity)
-          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 1})
+          .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 1},
+                     kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll)
           .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
           .BuildAsVector();
 
diff --git a/ui/file_manager/file_manager/foreground/css/file_types.css b/ui/file_manager/file_manager/foreground/css/file_types.css
index 8a794b8..8604836 100644
--- a/ui/file_manager/file_manager/foreground/css/file_types.css
+++ b/ui/file_manager/file_manager/foreground/css/file_types.css
@@ -445,6 +445,15 @@
   -webkit-mask-image: url(../images/volumes/linux_files.svg);
 }
 
+[file-type-icon='bruschetta'] {
+  -webkit-mask-image: url(../images/volumes/linux_files.svg);
+}
+
+.tree-row > .file-row > [root-type-icon='bruschetta'],
+.tree-row > .file-row > [volume-type-icon='bruschetta'] {
+  -webkit-mask-image: url(../images/volumes/linux_files.svg);
+}
+
 [file-type-icon='android_files'] {
   -webkit-mask-image: url(../images/volumes/android.svg);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index 3d36f25d..714b293 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -1199,6 +1199,8 @@
     ":file_selection",
     ":spinner_controller",
     "ui:list_container",
+    "//ui/file_manager/file_manager/common/js:metrics",
+    "//ui/file_manager/file_manager/common/js:volume_manager_types",
   ]
 }
 
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js
index b8fe535c..01f0930 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_contents.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -863,8 +863,6 @@
       this.onScanError_(error);
     }
 
-    metrics.startInterval('DirectoryListLoad');
-
     // TODO(hidehiko,mtomasz): this scan method must be called at most once.
     // Remove such a limitation.
     this.scanner_ = this.scannerFactory_();
@@ -976,21 +974,6 @@
       // Call callback first, so isScanning() returns false in the event
       // handlers.
       callback();
-      // TODO(crbug.com/1290197): Currently we only care about the load time for
-      // local files, filter out all the other root types.
-      if (this.getDirectoryEntry()) {
-        const locationInfo = this.context_.volumeManager.getLocationInfo(
-            /** @type {!Entry} */ (this.getDirectoryEntry()));
-        if (locationInfo &&
-            (locationInfo.rootType === VolumeManagerCommon.RootType.MY_FILES ||
-             locationInfo.rootType ===
-                 VolumeManagerCommon.RootType.DOWNLOADS)) {
-          metrics.recordDirectoryListLoadWithTolerance(
-              'DirectoryListLoad', this.getFileListLength(),
-              VolumeManagerCommon.RootType.MY_FILES, [10, 100, 1000],
-              /*tolerance=*/ 0.2);
-        }
-      }
       dispatchSimpleEvent(this, 'scan-completed');
     });
   }
diff --git a/ui/file_manager/file_manager/foreground/js/scan_controller.js b/ui/file_manager/file_manager/foreground/js/scan_controller.js
index cfefd32..e8f4f03 100644
--- a/ui/file_manager/file_manager/foreground/js/scan_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/scan_controller.js
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {metrics} from '../../common/js/metrics.js';
+import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
+
 import {DirectoryModel} from './directory_model.js';
 import {FileSelectionHandler} from './file_selection.js';
 import {SpinnerController} from './spinner_controller.js';
@@ -76,6 +79,8 @@
           'scan-started', this.directoryModel_.getCurrentDirName());
     }
 
+    metrics.startInterval('DirectoryListLoad');
+
     this.listContainer_.startBatchUpdates();
     this.scanInProgress_ = true;
 
@@ -113,6 +118,20 @@
 
     this.scanInProgress_ = false;
     this.listContainer_.endBatchUpdates();
+
+    // TODO(crbug.com/1290197): Currently we only care about the load time for
+    // local files, filter out all the other root types.
+    if (this.directoryModel_.getCurrentDirEntry()) {
+      const volumeInfo = this.directoryModel_.getCurrentVolumeInfo();
+      if (volumeInfo &&
+          (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DOWNLOADS ||
+           volumeInfo.volumeType === VolumeManagerCommon.VolumeType.MY_FILES)) {
+        metrics.recordDirectoryListLoadWithTolerance(
+            'DirectoryListLoad', this.directoryModel_.getFileList().length,
+            VolumeManagerCommon.RootType.MY_FILES, [10, 100, 1000],
+            /*tolerance=*/ 0.2);
+      }
+    }
   }
 
   /**
diff --git a/ui/gfx/display_color_spaces.cc b/ui/gfx/display_color_spaces.cc
index 0a3556fd..48e13ef 100644
--- a/ui/gfx/display_color_spaces.cc
+++ b/ui/gfx/display_color_spaces.cc
@@ -6,6 +6,7 @@
 
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "third_party/skia/include/core/SkColorSpace.h"
 
 namespace gfx {
 
@@ -120,6 +121,12 @@
          GetOutputColorSpace(ContentColorUsage::kHDR, true).IsHDR();
 }
 
+SkColorSpacePrimaries DisplayColorSpaces::GetPrimaries() const {
+  // TODO(https://crbug.com/1274220): Store this directly, rather than inferring
+  // it from the raster color space.
+  return GetRasterColorSpace().GetColorSpacePrimaries();
+}
+
 ColorSpace DisplayColorSpaces::GetScreenInfoColorSpace() const {
   return GetOutputColorSpace(ContentColorUsage::kHDR, false /* needs_alpha */);
 }
diff --git a/ui/gfx/display_color_spaces.h b/ui/gfx/display_color_spaces.h
index 7a7fbd7..5253f9cb 100644
--- a/ui/gfx/display_color_spaces.h
+++ b/ui/gfx/display_color_spaces.h
@@ -112,6 +112,9 @@
   // Return true if the HDR color spaces are, indeed, HDR.
   bool SupportsHDR() const;
 
+  // Return the primaries that define the color gamut of the display.
+  SkColorSpacePrimaries GetPrimaries() const;
+
   // Output as a vector of strings. This is a helper function for printing in
   // about:gpu. All output vectors will be the same length. Each entry will be
   // the configuration name, its buffer format, and its color space.
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 0cf9d20e..c9415dc 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -124,6 +124,7 @@
     "controls/button/radio_button.h",
     "controls/button/toggle_button.h",
     "controls/combobox/combobox.h",
+    "controls/combobox/combobox_menu_model.h",
     "controls/combobox/combobox_util.h",
     "controls/dot_indicator.h",
     "controls/editable_combobox/editable_combobox.h",
@@ -350,6 +351,7 @@
     "controls/button/radio_button.cc",
     "controls/button/toggle_button.cc",
     "controls/combobox/combobox.cc",
+    "controls/combobox/combobox_menu_model.cc",
     "controls/combobox/combobox_util.cc",
     "controls/combobox/empty_combobox_model.cc",
     "controls/combobox/empty_combobox_model.h",
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc
index 1320936..a15714f8 100644
--- a/ui/views/controls/combobox/combobox.cc
+++ b/ui/views/controls/combobox/combobox.cc
@@ -18,7 +18,6 @@
 #include "ui/base/ime/input_method.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/models/image_model.h"
-#include "ui/base/models/menu_model.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/color/color_id.h"
 #include "ui/color/color_provider.h"
@@ -33,6 +32,7 @@
 #include "ui/views/background.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/button_controller.h"
+#include "ui/views/controls/combobox/combobox_menu_model.h"
 #include "ui/views/controls/combobox/combobox_util.h"
 #include "ui/views/controls/combobox/empty_combobox_model.h"
 #include "ui/views/controls/focus_ring.h"
@@ -141,100 +141,6 @@
 
 }  // namespace
 
-// Adapts a ui::ComboboxModel to a ui::MenuModel.
-class Combobox::ComboboxMenuModel : public ui::MenuModel {
- public:
-  ComboboxMenuModel(Combobox* owner, ui::ComboboxModel* model)
-      : owner_(owner), model_(model) {}
-  ComboboxMenuModel(const ComboboxMenuModel&) = delete;
-  ComboboxMenuModel& operator&(const ComboboxMenuModel&) = delete;
-  ~ComboboxMenuModel() override = default;
-
- private:
-  bool UseCheckmarks() const {
-    return MenuConfig::instance().check_selected_combobox_item;
-  }
-
-  // Overridden from MenuModel:
-  bool HasIcons() const override {
-    for (int i = 0; i < GetItemCount(); ++i) {
-      if (!GetIconAt(i).IsEmpty())
-        return true;
-    }
-    return false;
-  }
-
-  int GetItemCount() const override { return model_->GetItemCount(); }
-
-  ItemType GetTypeAt(int index) const override {
-    if (model_->IsItemSeparatorAt(index))
-      return TYPE_SEPARATOR;
-    return UseCheckmarks() ? TYPE_CHECK : TYPE_COMMAND;
-  }
-
-  ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override {
-    return ui::NORMAL_SEPARATOR;
-  }
-
-  int GetCommandIdAt(int index) const override {
-    // Define the id of the first item in the menu (since it needs to be > 0)
-    constexpr int kFirstMenuItemId = 1000;
-    return index + kFirstMenuItemId;
-  }
-
-  std::u16string GetLabelAt(int index) const override {
-    // Inserting the Unicode formatting characters if necessary so that the
-    // text is displayed correctly in right-to-left UIs.
-    std::u16string text = model_->GetDropDownTextAt(index);
-    base::i18n::AdjustStringForLocaleDirection(&text);
-    return text;
-  }
-
-  std::u16string GetSecondaryLabelAt(int index) const override {
-    std::u16string text = model_->GetDropDownSecondaryTextAt(index);
-    base::i18n::AdjustStringForLocaleDirection(&text);
-    return text;
-  }
-
-  bool IsItemDynamicAt(int index) const override { return true; }
-
-  const gfx::FontList* GetLabelFontListAt(int index) const override {
-    return &owner_->GetFontList();
-  }
-
-  bool GetAcceleratorAt(int index,
-                        ui::Accelerator* accelerator) const override {
-    return false;
-  }
-
-  bool IsItemCheckedAt(int index) const override {
-    return UseCheckmarks() && index == owner_->selected_index_;
-  }
-
-  int GetGroupIdAt(int index) const override { return -1; }
-
-  ui::ImageModel GetIconAt(int index) const override {
-    return model_->GetDropDownIconAt(index);
-  }
-
-  ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override {
-    return nullptr;
-  }
-
-  bool IsEnabledAt(int index) const override {
-    return model_->IsItemEnabledAt(index);
-  }
-
-  void ActivatedAt(int index) override { owner_->MenuSelectionAt(index); }
-
-  void ActivatedAt(int index, int event_flags) override { ActivatedAt(index); }
-
-  MenuModel* GetSubmenuModelAt(int index) const override { return nullptr; }
-
-  raw_ptr<Combobox> owner_;           // Weak. Owns this.
-  raw_ptr<ui::ComboboxModel> model_;  // Weak.
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 // Combobox, public:
 
diff --git a/ui/views/controls/combobox/combobox.h b/ui/views/controls/combobox/combobox.h
index 032a5d8..6f1049cc 100644
--- a/ui/views/controls/combobox/combobox.h
+++ b/ui/views/controls/combobox/combobox.h
@@ -14,6 +14,7 @@
 #include "base/time/time.h"
 #include "ui/base/models/combobox_model.h"
 #include "ui/base/models/combobox_model_observer.h"
+#include "ui/base/models/menu_model.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/prefix_delegate.h"
 #include "ui/views/metadata/view_factory.h"
@@ -71,12 +72,20 @@
     callback_ = std::move(callback);
   }
 
+  // Set menu model.
+  void SetMenuModel(std::unique_ptr<ui::MenuModel> menu_model) {
+    menu_model_ = std::move(menu_model);
+  }
+
   // Gets/Sets the selected index.
   int GetSelectedIndex() const { return selected_index_; }
   void SetSelectedIndex(int index);
   [[nodiscard]] base::CallbackListSubscription AddSelectedIndexChangedCallback(
       views::PropertyChangedCallback callback);
 
+  // Called when there has been a selection from the menu.
+  void MenuSelectionAt(int index);
+
   // Looks for the first occurrence of |value| in |model()|. If found, selects
   // the found index and returns true. Otherwise simply noops and returns false.
   bool SelectValue(const std::u16string& value);
@@ -151,8 +160,6 @@
  private:
   friend class test::ComboboxTestApi;
 
-  class ComboboxMenuModel;
-
   // Updates the border according to the current node_data.
   void UpdateBorder();
 
@@ -171,9 +178,6 @@
   // Cleans up after the menu as closed
   void OnMenuClosed(Button::ButtonState original_button_state);
 
-  // Called when there has been a selection from the menu.
-  void MenuSelectionAt(int index);
-
   // Called when the selection is changed by the user.
   void OnPerformAction();
 
diff --git a/ui/views/controls/combobox/combobox_menu_model.cc b/ui/views/controls/combobox/combobox_menu_model.cc
new file mode 100644
index 0000000..72e9017b
--- /dev/null
+++ b/ui/views/controls/combobox/combobox_menu_model.cc
@@ -0,0 +1,104 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/controls/combobox/combobox_menu_model.h"
+
+ComboboxMenuModel::ComboboxMenuModel(views::Combobox* owner,
+                                     ui::ComboboxModel* model)
+    : owner_(owner), model_(model) {}
+
+ComboboxMenuModel::~ComboboxMenuModel() = default;
+
+bool ComboboxMenuModel::UseCheckmarks() const {
+  return views::MenuConfig::instance().check_selected_combobox_item;
+}
+
+// Overridden from MenuModel:
+bool ComboboxMenuModel::HasIcons() const {
+  for (int i = 0; i < GetItemCount(); ++i) {
+    if (!GetIconAt(i).IsEmpty())
+      return true;
+  }
+  return false;
+}
+
+int ComboboxMenuModel::GetItemCount() const {
+  return model_->GetItemCount();
+}
+
+ui::MenuModel::ItemType ComboboxMenuModel::GetTypeAt(int index) const {
+  if (model_->IsItemSeparatorAt(index))
+    return TYPE_SEPARATOR;
+  return UseCheckmarks() ? TYPE_CHECK : TYPE_COMMAND;
+}
+
+ui::MenuSeparatorType ComboboxMenuModel::GetSeparatorTypeAt(int index) const {
+  return ui::NORMAL_SEPARATOR;
+}
+
+int ComboboxMenuModel::GetCommandIdAt(int index) const {
+  // Define the id of the first item in the menu (since it needs to be > 0)
+  constexpr int kFirstMenuItemId = 1000;
+  return index + kFirstMenuItemId;
+}
+
+std::u16string ComboboxMenuModel::GetLabelAt(int index) const {
+  // Inserting the Unicode formatting characters if necessary so that the
+  // text is displayed correctly in right-to-left UIs.
+  std::u16string text = model_->GetDropDownTextAt(index);
+  base::i18n::AdjustStringForLocaleDirection(&text);
+  return text;
+}
+
+std::u16string ComboboxMenuModel::GetSecondaryLabelAt(int index) const {
+  std::u16string text = model_->GetDropDownSecondaryTextAt(index);
+  base::i18n::AdjustStringForLocaleDirection(&text);
+  return text;
+}
+
+bool ComboboxMenuModel::IsItemDynamicAt(int index) const {
+  return true;
+}
+
+const gfx::FontList* ComboboxMenuModel::GetLabelFontListAt(int index) const {
+  return &owner_->GetFontList();
+}
+
+bool ComboboxMenuModel::GetAcceleratorAt(int index,
+                                         ui::Accelerator* accelerator) const {
+  return false;
+}
+
+bool ComboboxMenuModel::IsItemCheckedAt(int index) const {
+  return UseCheckmarks() && index == owner_->GetSelectedIndex();
+}
+
+int ComboboxMenuModel::GetGroupIdAt(int index) const {
+  return -1;
+}
+
+ui::ImageModel ComboboxMenuModel::GetIconAt(int index) const {
+  return model_->GetDropDownIconAt(index);
+}
+
+ui::ButtonMenuItemModel* ComboboxMenuModel::GetButtonMenuItemAt(
+    int index) const {
+  return nullptr;
+}
+
+bool ComboboxMenuModel::IsEnabledAt(int index) const {
+  return model_->IsItemEnabledAt(index);
+}
+
+void ComboboxMenuModel::ActivatedAt(int index) {
+  owner_->MenuSelectionAt(index);
+}
+
+void ComboboxMenuModel::ActivatedAt(int index, int event_flags) {
+  ActivatedAt(index);
+}
+
+ui::MenuModel* ComboboxMenuModel::GetSubmenuModelAt(int index) const {
+  return nullptr;
+}
diff --git a/ui/views/controls/combobox/combobox_menu_model.h b/ui/views/controls/combobox/combobox_menu_model.h
new file mode 100644
index 0000000..45bc883
--- /dev/null
+++ b/ui/views/controls/combobox/combobox_menu_model.h
@@ -0,0 +1,53 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_CONTROLS_COMBOBOX_COMBOBOX_MENU_MODEL_H_
+#define UI_VIEWS_CONTROLS_COMBOBOX_COMBOBOX_MENU_MODEL_H_
+
+#include "base/i18n/rtl.h"
+#include "ui/base/models/combobox_model.h"
+#include "ui/base/models/image_model.h"
+#include "ui/base/models/menu_model.h"
+#include "ui/views/controls/combobox/combobox.h"
+#include "ui/views/controls/menu/menu_config.h"
+
+// Adapts a ui::ComboboxModel to a ui::MenuModel.
+class VIEWS_EXPORT ComboboxMenuModel : public ui::MenuModel {
+ public:
+  ComboboxMenuModel(views::Combobox* owner, ui::ComboboxModel* model);
+  ComboboxMenuModel(const ComboboxMenuModel&) = delete;
+  ComboboxMenuModel& operator&(const ComboboxMenuModel&) = delete;
+  ~ComboboxMenuModel() override;
+
+ protected:
+  ui::ComboboxModel* GetModel() const { return model_; }
+
+ private:
+  bool UseCheckmarks() const;
+
+  // Overridden from MenuModel:
+  bool HasIcons() const override;
+  int GetItemCount() const override;
+  ui::MenuModel::ItemType GetTypeAt(int index) const override;
+  ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override;
+  int GetCommandIdAt(int index) const override;
+  std::u16string GetLabelAt(int index) const override;
+  std::u16string GetSecondaryLabelAt(int index) const override;
+  bool IsItemDynamicAt(int index) const override;
+  const gfx::FontList* GetLabelFontListAt(int index) const override;
+  bool GetAcceleratorAt(int index, ui::Accelerator* accelerator) const override;
+  bool IsItemCheckedAt(int index) const override;
+  int GetGroupIdAt(int index) const override;
+  ui::ImageModel GetIconAt(int index) const override;
+  ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override;
+  bool IsEnabledAt(int index) const override;
+  void ActivatedAt(int index) override;
+  void ActivatedAt(int index, int event_flags) override;
+  ui::MenuModel* GetSubmenuModelAt(int index) const override;
+
+  raw_ptr<views::Combobox> owner_;    // Weak. Owns this.
+  raw_ptr<ui::ComboboxModel> model_;  // Weak.
+};
+
+#endif  // UI_VIEWS_CONTROLS_COMBOBOX_COMBOBOX_MENU_MODEL_H_
diff --git a/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts b/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts
index 0ae46e7..4cad350 100644
--- a/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts
+++ b/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts
@@ -30,7 +30,7 @@
     return false;
   }
   const hrefURL = new URL(href);
-  const params = new URLSearchParams(window.location.search);
+  const params = new URLSearchParams(hrefURL.search);
   params.set('version', new Date().getTime().toString());
   const newHref = `${hrefURL.origin}${hrefURL.pathname}?${params.toString()}`;
   colorCssNode.setAttribute('href', newHref);