diff --git a/DEPS b/DEPS
index 6b9624e..784a58b 100644
--- a/DEPS
+++ b/DEPS
@@ -181,7 +181,7 @@
   # luci-go CIPD package version.
   # Make sure the revision is uploaded by infra-packagers builder.
   # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console
-  'luci_go': 'git_revision:6cbe3f56e9f00b8f65eae21f01838a8b58191a47',
+  'luci_go': 'git_revision:1a022d3a4c50be4207ee93451255d71896416596',
 
   # This can be overridden, e.g. with custom_vars, to build clang from HEAD
   # instead of downloading the prebuilt pinned revision.
@@ -200,7 +200,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '65fb101861aba547ebc04b39a6147aa3982d4e5f',
+  'skia_revision': '3df719619f0a21d51dd19d0e5850623fe0a61d69',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -212,7 +212,7 @@
   # 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': 'c2a74cbb8ee1b1076c6e28f6aae2e8f8de283f28',
+  'angle_revision': '084b862ba31bd6134158aa8c5c4fb86d926982a5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -563,7 +563,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'a4d2f5ac0acfe1af18eefc7df9349c1547f1b4ce',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '77c77dc0f8ac9da6d3a1e127df40049924cdb18b',
       'condition': 'checkout_ios',
   },
 
@@ -919,7 +919,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '260eb0f662b4b173c66e9dc892328f982185e83c',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b35dd76cd5f6a1f2e34810d995f6d98df9033527',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1274,7 +1274,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + 'b5ac6d34a14cc938258a938ebe3604a93776f7fa',
+    Var('chromium_git') + '/openscreen' + '@' + '185795f02ceb4300e1caef49b5b7052c8d453dc9',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '97cfe495bb7a3853266b646d1c79e169387f9c7a',
@@ -1369,7 +1369,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/aemu/linux-amd64',
-              'version': 'qDJOg4W2RuPZ92H6d33I9kLLWjqfYuMr_gFsPRodSQAC'
+              'version': 'xP-64hTow-Hi_OEgw5l-GAguP8htsWKyhoX-a9Fj9KcC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1535,7 +1535,7 @@
     Var('chromium_git') + '/external/github.com/SeleniumHQ/selenium/py.git' + '@' + 'd0045ec570c1a77612db35d1e92f05e1d27b4d53',
 
   'src/third_party/webgl/src':
-    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '1a111c2adcb4898655aacaca018d6e275172760b',
+    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '3e3f152617996e4a175fd0b597a1936824b371f3',
 
   'src/third_party/webgpu-cts/src':
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'a8196844ac6228fea3560b82d29e01fed2fbf13a',
@@ -1551,7 +1551,7 @@
   },
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '19526a69c763d26f4699f14dd33681db8976a1b1',
+    Var('webrtc_git') + '/src.git' + '@' + '3f77eb468fc4a9a7f5e2751d3d3cbbda38e95082',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1623,7 +1623,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@60b0ce5c4a445cc2fa83866f55671e8ca4ba70ce',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c983c977f266a143f7b4eaa1e0e20942a4d3756b',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/WATCHLISTS b/WATCHLISTS
index 5f8cbc8..a1d5df165 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1472,7 +1472,8 @@
                   '^chrome/browser/ui/omnibox/|'\
                   '^chrome/browser/ui/.*/location_bar/|'\
                   '^chrome/browser/ui/.*/omnibox/|'\
-                  '^components/omnibox/'
+                  '^components/omnibox/|'\
+                  '^components/search_engines/'
     },
     'optimization_guide': {
       'filepath': 'optimization_guide|'\
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc
index d948b67..5ebf8840 100644
--- a/ash/login/ui/lock_contents_view.cc
+++ b/ash/login/ui/lock_contents_view.cc
@@ -2059,8 +2059,12 @@
     return;
 
   // Show gaia signin if this is login and the user has failed too many times.
+  // Do not show on secondary login screen – even though it has type kLogin – as
+  // there is no OOBE there.
   if (screen_type_ == LockScreen::ScreenType::kLogin &&
-      unlock_attempt_ >= kLoginAttemptsBeforeGaiaDialog) {
+      unlock_attempt_ >= kLoginAttemptsBeforeGaiaDialog &&
+      Shell::Get()->session_controller()->GetSessionState() !=
+          session_manager::SessionState::LOGIN_SECONDARY) {
     Shell::Get()->login_screen_controller()->ShowGaiaSignin(
         big_view->auth_user()->current_user().basic_user_info.account_id);
     return;
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc
index f0302fe..cb28624 100644
--- a/ash/login/ui/login_auth_user_view.cc
+++ b/ash/login/ui/login_auth_user_view.cc
@@ -1070,17 +1070,20 @@
     button_message =
         l10n_util::GetStringUTF16(IDS_ASH_LOCK_SCREEN_VERIFY_ACCOUNT_MESSAGE);
   }
-  auto online_sign_in_message = std::make_unique<SystemLabelButton>(
+  bool is_login_secondary =
+      Shell::Get()->session_controller()->GetSessionState() ==
+      session_manager::SessionState::LOGIN_SECONDARY;
+  auto online_sign_in_button = std::make_unique<SystemLabelButton>(
       base::BindRepeating(&LoginAuthUserView::OnOnlineSignInMessageTap,
                           base::Unretained(this)),
       button_message, SystemLabelButton::DisplayType::ALERT_WITH_ICON,
       /*multiline*/ false);
-  online_sign_in_message_ = online_sign_in_message.get();
+  // Disable online sign-in on secondary login screen as there is no OOBE there.
+  online_sign_in_button->SetEnabled(!is_login_secondary);
+  online_sign_in_message_ = online_sign_in_button.get();
 
   bool shown_because_of_multiprofile_policy =
-      !user.is_multiprofile_allowed &&
-      Shell::Get()->session_controller()->GetSessionState() ==
-          session_manager::SessionState::LOGIN_SECONDARY;
+      !user.is_multiprofile_allowed && is_login_secondary;
   auto disabled_auth_message = std::make_unique<DisabledAuthMessageView>(
       shown_because_of_multiprofile_policy, user.multiprofile_policy);
   disabled_auth_message_ = disabled_auth_message.get();
@@ -1104,7 +1107,7 @@
       login_views_utils::WrapViewForPreferredSize(std::move(password_view));
   auto wrapped_online_sign_in_message_view =
       login_views_utils::WrapViewForPreferredSize(
-          std::move(online_sign_in_message));
+          std::move(online_sign_in_button));
   auto wrapped_disabled_auth_message_view =
       login_views_utils::WrapViewForPreferredSize(
           std::move(disabled_auth_message));
diff --git a/base/BUILD.gn b/base/BUILD.gn
index f638c9c..5830912 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1806,8 +1806,6 @@
         "allocator/partition_allocator/partition_root.h",
         "allocator/partition_allocator/partition_stats.cc",
         "allocator/partition_allocator/partition_stats.h",
-        "allocator/partition_allocator/partition_tag.h",
-        "allocator/partition_allocator/partition_tag_bitmap.h",
         "allocator/partition_allocator/partition_tls.h",
         "allocator/partition_allocator/pcscan.cc",
         "allocator/partition_allocator/pcscan.h",
@@ -3867,7 +3865,6 @@
     ]
 
     sources = [
-      "test/android/javatests/src/org/chromium/base/test/BaseActivityTestRule.java",
       "test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java",
       "test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java",
       "test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java",
diff --git a/base/allocator/partition_allocator/checked_ptr_support.h b/base/allocator/partition_allocator/checked_ptr_support.h
index 16661f0c..526c2a6 100644
--- a/base/allocator/partition_allocator/checked_ptr_support.h
+++ b/base/allocator/partition_allocator/checked_ptr_support.h
@@ -5,19 +5,6 @@
 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_CHECKED_PTR_SUPPORT_H_
 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_CHECKED_PTR_SUPPORT_H_
 
-#define ENABLE_TAG_FOR_CHECKED_PTR2 0
-#define ENABLE_TAG_FOR_MTE_CHECKED_PTR 0
-#define ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR 0
-
 #define ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR 0
 
-static_assert(!ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR ||
-                  !ENABLE_TAG_FOR_CHECKED_PTR2,
-              "ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR and "
-              "ENABLE_TAG_FOR_CHECKED_PTR2 aren't compatible and can't be both "
-              "used at the same time");
-
-// This is a sub-variant of ENABLE_TAG_FOR_MTE_CHECKED_PTR
-#define MTE_CHECKED_PTR_SET_TAG_AT_FREE 1
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_CHECKED_PTR_SUPPORT_H_
diff --git a/base/allocator/partition_allocator/partition_alloc-inl.h b/base/allocator/partition_allocator/partition_alloc-inl.h
index f4dbe7a8..6a78cdf 100644
--- a/base/allocator/partition_allocator/partition_alloc-inl.h
+++ b/base/allocator/partition_allocator/partition_alloc-inl.h
@@ -9,7 +9,6 @@
 
 #include "base/allocator/partition_allocator/partition_cookie.h"
 #include "base/allocator/partition_allocator/partition_ref_count.h"
-#include "base/allocator/partition_allocator/partition_tag.h"
 #include "base/allocator/partition_allocator/random.h"
 #include "build/build_config.h"
 
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc
index 256dbd6..de7eeaf1 100644
--- a/base/allocator/partition_allocator/partition_alloc.cc
+++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -23,14 +23,6 @@
 
 namespace base {
 
-#if ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-namespace internal {
-BASE_EXPORT PartitionTagWrapper g_checked_ptr_single_tag = {{},
-                                                            kFixedTagValue,
-                                                            {}};
-}
-#endif
-
 void PartitionAllocGlobalInit(OomFunction on_out_of_memory) {
   // This is from page_allocator_constants.h and doesn't really fit here, but
   // there isn't a centralized initialization function in page_allocator.cc, so
@@ -63,11 +55,7 @@
       "maximum direct mapped allocation");
 
   // Check that some of our zanier calculations worked out as expected.
-#if ENABLE_TAG_FOR_MTE_CHECKED_PTR
-  static_assert(kSmallestBucket >= kAlignment, "generic smallest bucket");
-#else
   static_assert(kSmallestBucket == kAlignment, "generic smallest bucket");
-#endif
   static_assert(kMaxBucketed == 983040, "generic max bucketed");
   STATIC_ASSERT_OR_PA_CHECK(
       MaxSystemPagesPerSlotSpan() < (1 << 8),
@@ -135,7 +123,7 @@
       internal::PartitionAllocGetSlotSpanForSizeQuery<internal::ThreadSafe>(
           ptr);
   auto* root = PartitionRoot<internal::ThreadSafe>::FromSlotSpan(slot_span);
-  // The only allocations that don't use tag/ref-count are allocated outside of
+  // The only allocations that don't use ref-count are allocated outside of
   // GigaCage, hence we'd never get here in the `allow_extras = false` case.
   PA_DCHECK(root->allow_extras);
   ptr = root->AdjustPointerForExtrasSubtract(ptr);
diff --git a/base/allocator/partition_allocator/partition_alloc.h b/base/allocator/partition_allocator/partition_alloc.h
index d9ee79155..ebf5446 100644
--- a/base/allocator/partition_allocator/partition_alloc.h
+++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -42,7 +42,6 @@
 #include "base/allocator/partition_allocator/partition_ref_count.h"
 #include "base/allocator/partition_allocator/partition_root.h"
 #include "base/allocator/partition_allocator/partition_stats.h"
-#include "base/allocator/partition_allocator/partition_tag.h"
 #include "base/allocator/partition_allocator/pcscan.h"
 #include "base/allocator/partition_allocator/thread_cache.h"
 #include "base/base_export.h"
diff --git a/base/allocator/partition_allocator/partition_alloc_constants.h b/base/allocator/partition_allocator/partition_alloc_constants.h
index c147394..726a321 100644
--- a/base/allocator/partition_allocator/partition_alloc_constants.h
+++ b/base/allocator/partition_allocator/partition_alloc_constants.h
@@ -117,7 +117,6 @@
 //     | Guard page (4 KiB)    |
 //     | Metadata page (4 KiB) |
 //     | Guard pages (8 KiB)   |
-//     | TagBitmap             |
 //     | QuarantineBitmaps     |
 //     | Slot span             |
 //     | Slot span             |
@@ -126,7 +125,6 @@
 //     | Guard pages (16 KiB)  |
 //     +-----------------------+
 //
-// TagBitmap is only present when ENABLE_TAG_FOR_MTE_CHECKED_PTR is defined.
 // QuarantineBitmaps are inserted for partitions that may have PCScan enabled.
 //
 // Each slot span is a contiguous range of one or more `PartitionPage`s. Note
@@ -224,13 +222,8 @@
 //
 // In practice, this means 8 bytes alignment on 32 bit architectures, and 16
 // bytes on 64 bit ones.
-#if ENABLE_TAG_FOR_MTE_CHECKED_PTR
-// MTECheckedPtr requires 16B-alignment because kBytesPerPartitionTag is 16.
-static const size_t kMinBucketedOrder = 5;
-#else
 static const size_t kMinBucketedOrder =
     kAlignment == 16 ? 5 : 4;  // 2^(order - 1), that is 16 or 8.
-#endif
 // The largest bucketed order is 1 << (20 - 1), storing [512 KiB, 1 MiB):
 static const size_t kMaxBucketedOrder = 20;
 static const size_t kNumBucketedOrders =
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index e262fb4..a11f3c79 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -20,8 +20,6 @@
 #include "base/allocator/partition_allocator/partition_alloc_features.h"
 #include "base/allocator/partition_allocator/partition_page.h"
 #include "base/allocator/partition_allocator/partition_ref_count.h"
-#include "base/allocator/partition_allocator/partition_tag.h"
-#include "base/allocator/partition_allocator/partition_tag_bitmap.h"
 #include "base/bits.h"
 #include "base/logging.h"
 #include "base/rand_util.h"
@@ -138,13 +136,11 @@
 
 const size_t kTestAllocSize = 16;
 #if !DCHECK_IS_ON()
-const size_t kPointerOffset = kInSlotTagBufferSize + kInSlotRefCountBufferSize;
-const size_t kExtraAllocSize = kInSlotTagBufferSize + kInSlotRefCountBufferSize;
+const size_t kPointerOffset = kInSlotRefCountBufferSize;
+const size_t kExtraAllocSize = kInSlotRefCountBufferSize;
 #else
-const size_t kPointerOffset =
-    kCookieSize + kInSlotTagBufferSize + kInSlotRefCountBufferSize;
-const size_t kExtraAllocSize =
-    kCookieSize * 2 + kInSlotTagBufferSize + kInSlotRefCountBufferSize;
+const size_t kPointerOffset = kCookieSize + kInSlotRefCountBufferSize;
+const size_t kExtraAllocSize = kCookieSize * 2 + kInSlotRefCountBufferSize;
 #endif
 const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize;
 
@@ -448,7 +444,7 @@
   EXPECT_EQ(kPointerOffset,
             reinterpret_cast<size_t>(ptr) & PartitionPageOffsetMask());
   // Check that the offset appears to include a guard page.
-  EXPECT_EQ(PartitionPageSize() + kPointerOffset + ReservedTagBitmapSize(),
+  EXPECT_EQ(PartitionPageSize() + kPointerOffset,
             reinterpret_cast<size_t>(ptr) & kSuperPageOffsetMask);
 
   allocator.root()->Free(ptr);
@@ -651,8 +647,7 @@
   size_t num_pages_per_slot_span = GetNumPagesPerSlotSpan(kTestAllocSize);
   // 1 super page has 2 guard partition pages.
   size_t num_slot_spans_needed =
-      (NumPartitionPagesPerSuperPage() - NumPartitionPagesPerTagBitmap() - 2) /
-      num_pages_per_slot_span;
+      (NumPartitionPagesPerSuperPage() - 2) / num_pages_per_slot_span;
 
   // We need one more slot span in order to cross super page boundary.
   ++num_slot_spans_needed;
@@ -674,8 +669,7 @@
           reinterpret_cast<uintptr_t>(storage_ptr) & kSuperPageOffsetMask;
       EXPECT_FALSE(second_super_page_base == first_super_page_base);
       // Check that we allocated a guard page for the second page.
-      EXPECT_EQ(PartitionPageSize() + ReservedTagBitmapSize(),
-                second_super_page_offset);
+      EXPECT_EQ(PartitionPageSize(), second_super_page_offset);
     }
   }
   for (i = 0; i < num_slot_spans_needed; ++i)
@@ -1289,8 +1283,7 @@
   // The -2 is because the first and last partition pages in a super page are
   // guard pages.
   size_t num_slot_span_needed =
-      (NumPartitionPagesPerSuperPage() - NumPartitionPagesPerTagBitmap() - 2) /
-      num_pages_per_slot_span;
+      (NumPartitionPagesPerSuperPage() - 2) / num_pages_per_slot_span;
   size_t num_partition_pages_needed =
       num_slot_span_needed * num_pages_per_slot_span;
 
@@ -1305,9 +1298,9 @@
 
   char* page_base =
       reinterpret_cast<char*>(SlotSpan::ToPointer(first_super_page_pages[0]));
-  EXPECT_EQ(PartitionPageSize() + ReservedTagBitmapSize(),
+  EXPECT_EQ(PartitionPageSize(),
             reinterpret_cast<uintptr_t>(page_base) & kSuperPageOffsetMask);
-  page_base -= PartitionPageSize() - ReservedTagBitmapSize();
+  page_base -= PartitionPageSize();
   // Map a single system page either side of the mapping for our allocations,
   // with the goal of tripping up alignment of the next mapping.
   void* map1 = AllocPages(
@@ -1327,9 +1320,9 @@
 
   page_base =
       reinterpret_cast<char*>(SlotSpan::ToPointer(second_super_page_pages[0]));
-  EXPECT_EQ(PartitionPageSize() + ReservedTagBitmapSize(),
+  EXPECT_EQ(PartitionPageSize(),
             reinterpret_cast<uintptr_t>(page_base) & kSuperPageOffsetMask);
-  page_base -= PartitionPageSize() - ReservedTagBitmapSize();
+  page_base -= PartitionPageSize();
   // Map a single system page either side of the mapping for our allocations,
   // with the goal of tripping up alignment of the next mapping.
   map1 = AllocPages(page_base - PageAllocationGranularity(),
@@ -2412,12 +2405,12 @@
     // cookie.
     expected_alignment = std::min(expected_alignment, kCookieSize);
 #endif
-#if ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR
-    // When ENABLE_TAG_FOR_CHECKED_PTR2, a kInSlotTagBufferSize is added before
-    // rounding up the allocation size. The returned pointer points after the
-    // partition tag.
-    expected_alignment = std::min(
-        {expected_alignment, kInSlotTagBufferSize + kInSlotRefCountBufferSize});
+#if ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR
+    // When ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR is on, kInSlotRefCountBufferSize
+    // is added before rounding up the allocation size. The returned pointer
+    // points after the ref-count.
+    expected_alignment =
+        std::min({expected_alignment, kInSlotRefCountBufferSize});
 #endif
     for (int index = 0; index < 3; index++) {
       void* ptr = allocator.root()->Alloc(size, "");
@@ -2474,80 +2467,6 @@
   }
 }
 
-#if ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_MTE_CHECKED_PTR || \
-    ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-
-TEST_F(PartitionAllocTest, TagBasic) {
-  size_t alloc_size = 64 - kExtraAllocSize;
-  void* ptr1 = allocator.root()->Alloc(alloc_size, type_name);
-  void* ptr2 = allocator.root()->Alloc(alloc_size, type_name);
-  void* ptr3 = allocator.root()->Alloc(alloc_size, type_name);
-  EXPECT_TRUE(ptr1);
-  EXPECT_TRUE(ptr2);
-  EXPECT_TRUE(ptr3);
-
-  auto* slot_span = SlotSpan::FromPointer(
-      allocator.root()->AdjustPointerForExtrasSubtract(ptr1));
-  EXPECT_TRUE(slot_span);
-
-  char* char_ptr1 = reinterpret_cast<char*>(ptr1);
-  char* char_ptr2 = reinterpret_cast<char*>(ptr2);
-  char* char_ptr3 = reinterpret_cast<char*>(ptr3);
-  EXPECT_LT(kTestAllocSize, slot_span->bucket->slot_size);
-  EXPECT_EQ(char_ptr1 + slot_span->bucket->slot_size, char_ptr2);
-  EXPECT_EQ(char_ptr2 + slot_span->bucket->slot_size, char_ptr3);
-
-#if !ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-  constexpr PartitionTag kTag1 = static_cast<PartitionTag>(0xBADA);
-  constexpr PartitionTag kTag2 = static_cast<PartitionTag>(0xDB8A);
-  constexpr PartitionTag kTag3 = static_cast<PartitionTag>(0xA3C4);
-#else
-  // The in-memory tag will always be kFixedTagValue no matter what we set.
-  constexpr PartitionTag kTag1 = static_cast<PartitionTag>(kFixedTagValue);
-  constexpr PartitionTag kTag2 = static_cast<PartitionTag>(kFixedTagValue);
-  constexpr PartitionTag kTag3 = static_cast<PartitionTag>(kFixedTagValue);
-#endif
-  PartitionTagSetValue(ptr1, slot_span->bucket->slot_size, kTag1);
-  PartitionTagSetValue(ptr2, slot_span->bucket->slot_size, kTag2);
-  PartitionTagSetValue(ptr3, slot_span->bucket->slot_size, kTag3);
-
-  memset(ptr1, 0, alloc_size);
-  memset(ptr2, 0, alloc_size);
-  memset(ptr3, 0, alloc_size);
-
-  EXPECT_EQ(kTag1, PartitionTagGetValue(ptr1));
-  EXPECT_EQ(kTag2, PartitionTagGetValue(ptr2));
-  EXPECT_EQ(kTag3, PartitionTagGetValue(ptr3));
-
-  EXPECT_TRUE(!memchr(ptr1, static_cast<uint8_t>(kTag1), alloc_size));
-  EXPECT_TRUE(!memchr(ptr2, static_cast<uint8_t>(kTag2), alloc_size));
-  if (sizeof(PartitionTag) > 1) {
-    EXPECT_TRUE(!memchr(ptr1, static_cast<uint8_t>(kTag1 >> 8), alloc_size));
-    EXPECT_TRUE(!memchr(ptr2, static_cast<uint8_t>(kTag2 >> 8), alloc_size));
-  }
-
-  allocator.root()->Free(ptr1);
-  EXPECT_EQ(kTag2, PartitionTagGetValue(ptr2));
-
-  size_t request_size = slot_span->bucket->slot_size - kExtraAllocSize;
-  void* new_ptr2 = allocator.root()->Realloc(ptr2, request_size, type_name);
-  EXPECT_EQ(ptr2, new_ptr2);
-  EXPECT_EQ(kTag3, PartitionTagGetValue(ptr3));
-
-  // Add 1B to ensure the object is rellocated to a larger slot.
-  request_size = slot_span->bucket->slot_size - kExtraAllocSize + 1;
-  new_ptr2 = allocator.root()->Realloc(ptr2, request_size, type_name);
-  EXPECT_TRUE(new_ptr2);
-  EXPECT_NE(ptr2, new_ptr2);
-
-  allocator.root()->Free(new_ptr2);
-
-  EXPECT_EQ(kTag3, PartitionTagGetValue(ptr3));
-  allocator.root()->Free(ptr3);
-}
-
-#endif
-
 // Test that the optimized `GetSlotOffset` implementation produces valid
 // results.
 TEST_F(PartitionAllocTest, OptimizedGetSlotOffset) {
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc
index bc0c289..08c045e 100644
--- a/base/allocator/partition_allocator/partition_bucket.cc
+++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -17,8 +17,6 @@
 #include "base/allocator/partition_allocator/partition_direct_map_extent.h"
 #include "base/allocator/partition_allocator/partition_oom.h"
 #include "base/allocator/partition_allocator/partition_page.h"
-#include "base/allocator/partition_allocator/partition_tag.h"
-#include "base/allocator/partition_allocator/partition_tag_bitmap.h"
 #include "base/bits.h"
 #include "base/check.h"
 #include "build/build_config.h"
@@ -41,8 +39,9 @@
 
   char* ptr = nullptr;
   // Allocate from GigaCage, if enabled. However, the exception to this is when
-  // tags aren't allowed, as CheckedPtr assumes that everything inside GigaCage
-  // uses tags (specifically, inside the GigaCage's normal bucket pool).
+  // ref-count isn't allowed, as CheckedPtr assumes that everything inside
+  // GigaCage uses ref-count (specifically, inside the GigaCage's normal bucket
+  // pool).
   if (root->UsesGigaCage()) {
     ptr = internal::AddressPoolManager::GetInstance()->Alloc(
         GetDirectMapPool(), nullptr, reserved_size);
@@ -230,31 +229,6 @@
     root->next_partition_page += slot_span_reserved_size;
     root->IncreaseCommittedPages(slot_span_committed_size);
 
-#if ENABLE_TAG_FOR_MTE_CHECKED_PTR
-    PA_DCHECK(root->next_tag_bitmap_page);
-    char* next_tag_bitmap_page = reinterpret_cast<char*>(
-        bits::Align(reinterpret_cast<uintptr_t>(
-                        PartitionTagPointer(root->next_partition_page)),
-                    SystemPageSize()));
-    if (root->next_tag_bitmap_page < next_tag_bitmap_page) {
-#if DCHECK_IS_ON()
-      char* super_page = reinterpret_cast<char*>(
-          reinterpret_cast<uintptr_t>(ret) & kSuperPageBaseMask);
-      char* tag_bitmap = super_page + PartitionPageSize();
-      PA_DCHECK(next_tag_bitmap_page <= tag_bitmap + ActualTagBitmapSize());
-      PA_DCHECK(next_tag_bitmap_page > tag_bitmap);
-#endif
-      SetSystemPagesAccess(root->next_tag_bitmap_page,
-                           next_tag_bitmap_page - root->next_tag_bitmap_page,
-                           PageReadWrite);
-      root->next_tag_bitmap_page = next_tag_bitmap_page;
-    }
-#if MTE_CHECKED_PTR_SET_TAG_AT_FREE
-    // TODO(tasak): Consider initializing each slot with a different tag.
-    PartitionTagSetValue(ret, slot_span_reserved_size,
-                         root->GetNewPartitionTag());
-#endif
-#endif
     return ret;
   }
 
@@ -265,8 +239,9 @@
   char* requested_address = root->next_super_page;
   char* super_page = nullptr;
   // Allocate from GigaCage, if enabled. However, the exception to this is when
-  // tags aren't allowed, as CheckedPtr assumes that everything inside GigaCage
-  // uses tags (specifically, inside the GigaCage's normal bucket pool).
+  // ref-count isn't allowed, as CheckedPtr assumes that everything inside
+  // GigaCage uses ref-count (specifically, inside the GigaCage's normal bucket
+  // pool).
   if (root->UsesGigaCage()) {
     super_page = AddressPoolManager::GetInstance()->Alloc(
         GetNormalBucketPool(), requested_address, kSuperPageSize);
@@ -287,10 +262,7 @@
   //
   // TODO(ajwong): Introduce a DCHECK.
   root->next_super_page = super_page + kSuperPageSize;
-  // TODO(tasak): Consider starting the bitmap right after metadata to save
-  // space.
-  char* tag_bitmap = super_page + PartitionPageSize();
-  char* quarantine_bitmaps = tag_bitmap + ReservedTagBitmapSize();
+  char* quarantine_bitmaps = super_page + PartitionPageSize();
   size_t quarantine_bitmaps_reserved_size = 0;
   size_t quarantine_bitmaps_size_to_commit = 0;
   if (root->scannable) {
@@ -329,26 +301,6 @@
   SetSystemPagesAccess(super_page + (SystemPageSize() * 2),
                        PartitionPageSize() - (SystemPageSize() * 2),
                        PageInaccessible);
-#if ENABLE_TAG_FOR_MTE_CHECKED_PTR
-  // Make the first |slot_span_reserved_size| region of the tag bitmap
-  // accessible. The rest of the region is set to inaccessible.
-  char* next_tag_bitmap_page = reinterpret_cast<char*>(
-      bits::Align(reinterpret_cast<uintptr_t>(
-                      PartitionTagPointer(root->next_partition_page)),
-                  SystemPageSize()));
-  PA_DCHECK(next_tag_bitmap_page <= tag_bitmap + ActualTagBitmapSize());
-  PA_DCHECK(next_tag_bitmap_page > tag_bitmap);
-  // |ret| points at the end of the tag bitmap.
-  PA_DCHECK(next_tag_bitmap_page <= ret);
-  SetSystemPagesAccess(next_tag_bitmap_page, ret - next_tag_bitmap_page,
-                       PageInaccessible);
-#if MTE_CHECKED_PTR_SET_TAG_AT_FREE
-  // TODO(tasak): Consider initializing each slot with a different tag.
-  PartitionTagSetValue(ret, slot_span_reserved_size,
-                       root->GetNewPartitionTag());
-#endif
-  root->next_tag_bitmap_page = next_tag_bitmap_page;
-#endif
 
   // If PCScan is used, keep the quarantine bitmap committed, just release the
   // unused part of partition page, if any. If PCScan isn't used, release the
@@ -541,7 +493,7 @@
     } else {
       PA_DCHECK(slot_span->is_full());
       // If we get here, we found a full slot span. Skip over it too, and also
-      // tag it as full (via a negative value). We need it tagged so that
+      // mark it as full (via a negative value). We need it marked so that
       // free'ing can tell, and move it back into the active list.
       slot_span->num_allocated_slots = -slot_span->num_allocated_slots;
       ++num_full_slot_spans;
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h
index 61df972..8231285 100644
--- a/base/allocator/partition_allocator/partition_page.h
+++ b/base/allocator/partition_allocator/partition_page.h
@@ -15,7 +15,6 @@
 #include "base/allocator/partition_allocator/partition_alloc_forward.h"
 #include "base/allocator/partition_allocator/partition_bucket.h"
 #include "base/allocator/partition_allocator/partition_freelist_entry.h"
-#include "base/allocator/partition_allocator/partition_tag_bitmap.h"
 #include "base/allocator/partition_allocator/random.h"
 #include "base/check_op.h"
 #include "base/thread_annotations.h"
@@ -252,15 +251,15 @@
     char* super_page_base) {
   PA_DCHECK(
       !(reinterpret_cast<uintptr_t>(super_page_base) % kSuperPageAlignment));
-  return reinterpret_cast<QuarantineBitmap*>(
-      super_page_base + PartitionPageSize() + ReservedTagBitmapSize());
+  return reinterpret_cast<QuarantineBitmap*>(super_page_base +
+                                             PartitionPageSize());
 }
 
 ALWAYS_INLINE char* SuperPagePayloadBegin(char* super_page_base,
                                           bool with_pcscan) {
   PA_DCHECK(
       !(reinterpret_cast<uintptr_t>(super_page_base) % kSuperPageAlignment));
-  return super_page_base + PartitionPageSize() + ReservedTagBitmapSize() +
+  return super_page_base + PartitionPageSize() +
          (with_pcscan ? ReservedQuarantineBitmapsSize() : 0);
 }
 
diff --git a/base/allocator/partition_allocator/partition_root.cc b/base/allocator/partition_allocator/partition_root.cc
index 782c827f..f0a6b91 100644
--- a/base/allocator/partition_allocator/partition_root.cc
+++ b/base/allocator/partition_allocator/partition_root.cc
@@ -366,17 +366,15 @@
     internal::PartitionAddressSpace::Init();
 #endif
 
-  // If alignment needs to be enforced, disallow adding cookies and/or tags at
-  // the beginning of the slot.
+  // If alignment needs to be enforced, disallow adding a cookie and/or
+  // ref-count at the beginning of the slot.
   allow_extras = (opts.alignment != PartitionOptions::Alignment::kAlignedAlloc);
 
   size_t size = 0, offset = 0;
   if (allow_extras) {
-    size += internal::kPartitionTagSizeAdjustment;
     size += internal::kPartitionCookieSizeAdjustment;
     size += internal::kPartitionRefCountSizeAdjustment;
 
-    offset += internal::kPartitionTagOffsetAdjustment;
     offset += internal::kPartitionCookieOffsetAdjustment;
     offset += internal::kPartitionRefCountOffsetAdjustment;
   }
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h
index 4144046b..a924775f 100644
--- a/base/allocator/partition_allocator/partition_root.h
+++ b/base/allocator/partition_allocator/partition_root.h
@@ -45,7 +45,6 @@
 #include "base/allocator/partition_allocator/partition_oom.h"
 #include "base/allocator/partition_allocator/partition_page.h"
 #include "base/allocator/partition_allocator/partition_stats.h"
-#include "base/allocator/partition_allocator/partition_tag.h"
 #include "base/allocator/partition_allocator/pcscan.h"
 #include "base/allocator/partition_allocator/thread_cache.h"
 #include "base/bits.h"
@@ -91,10 +90,10 @@
 
     // In addition to the above alignment enforcement, this option allows using
     // AlignedAlloc() which can align at a larger boundary.  This option comes
-    // at a cost of disallowing cookies on Debug builds and tags/ref-counts for
+    // at a cost of disallowing cookies on Debug builds and ref-count for
     // CheckedPtr. It also causes all allocations to go outside of GigaCage, so
-    // that CheckedPtr can easily tell if a pointer comes with a tag/ref-count
-    // or not.
+    // that CheckedPtr can easily tell if a pointer comes with a ref-count or
+    // not.
     kAlignedAlloc,
   };
 
@@ -137,23 +136,13 @@
   // Flags accessed on fast paths.
   bool with_thread_cache = false;
   const bool is_thread_safe = thread_safe;
-  // TODO(bartekn): Consider size of added extras (cookies and/or tag, or
-  // nothing) instead of true|false, so that we can just add or subtract the
-  // size instead of having an if branch on the hot paths.
-  bool allow_extras;
   bool scannable = false;
   bool initialized = false;
 
+  bool allow_extras;
   uint32_t extras_size;
   uint32_t extras_offset;
 
-#if ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_MTE_CHECKED_PTR
-  internal::PartitionTag current_partition_tag = 0;
-#endif
-#if ENABLE_TAG_FOR_MTE_CHECKED_PTR
-  char* next_tag_bitmap_page = nullptr;
-#endif
-
   // Bookkeeping.
   // - total_size_of_super_pages - total virtual address space for normal bucket
   //     super pages
@@ -291,17 +280,6 @@
     return total_size_of_committed_pages.load(std::memory_order_relaxed);
   }
 
-  ALWAYS_INLINE internal::PartitionTag GetNewPartitionTag() {
-#if ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_MTE_CHECKED_PTR
-    auto tag = ++current_partition_tag;
-    tag += !tag;  // Avoid 0.
-    current_partition_tag = tag;
-    return tag;
-#else
-    return 0;
-#endif
-  }
-
   bool UsesGigaCage() const {
     return features::IsPartitionAllocGigaCageEnabled() && allow_extras;
   }
@@ -612,11 +590,11 @@
     void* ptr,
     SlotSpan* slot_span) {
   // The thread cache is added "in the middle" of the main allocator, that is:
-  // - After all the cookie/tag/ref-count management
+  // - After all the cookie/ref-count management
   // - Before the "raw" allocator.
   //
   // On the deallocation side:
-  // 1. Check cookies/tags/ref-count, adjust the pointer
+  // 1. Check cookies/ref-count, adjust the pointer
   // 2. Deallocation
   //   a. Return to the thread cache if possible. If it succeeds, return.
   //   b. Otherwise, call the "raw" allocator <-- Locking
@@ -624,17 +602,17 @@
   PA_DCHECK(slot_span);
   PA_DCHECK(IsValidSlotSpan(slot_span));
 
-  // |ptr| points after the tag and the cookie.
+  // |ptr| points after the ref-count and the cookie.
   //
   // Layout inside the slot:
-  //  <--------extras------->                  <-extras->
-  //  <----------------utilized_slot_size--------------->
-  //                        <----usable_size--->
-  //  |[tag/refcnt]|[cookie]|...data...|[empty]|[cookie]|[unused]|
-  //                        ^
-  //                       ptr
+  //  <------extras----->                  <-extras->
+  //  <--------------utilized_slot_size------------->
+  //                    <----usable_size--->
+  //  |[refcnt]|[cookie]|...data...|[empty]|[cookie]|[unused]|
+  //                    ^
+  //                   ptr
   //
-  // Note: tag, ref-count and cookie can be 0-sized.
+  // Note: ref-count and cookies can be 0-sized.
   //
   // For more context, see the other "Layout inside the slot" comment below.
 #if ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR || DCHECK_IS_ON() || \
@@ -654,19 +632,6 @@
 #endif
 
     if (!slot_span->bucket->is_direct_mapped()) {
-      // PartitionTagIncrementValue and PartitionTagClearValue require that the
-      // size is tag_bitmap::kBytesPerPartitionTag-aligned (currently 16
-      // bytes-aligned) when MTECheckedPtr is enabled. However,
-      // utilized_slot_size may not be aligned for single-slot slot spans. So we
-      // need the bucket's slot_size.
-      size_t slot_size_with_no_extras =
-          AdjustSizeForExtrasSubtract(slot_span->bucket->slot_size);
-#if ENABLE_TAG_FOR_MTE_CHECKED_PTR && MTE_CHECKED_PTR_SET_TAG_AT_FREE
-      internal::PartitionTagIncrementValue(ptr, slot_size_with_no_extras);
-#else
-      internal::PartitionTagClearValue(ptr, slot_size_with_no_extras);
-#endif
-
 #if ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR
       internal::PartitionRefCount* ref_count =
           internal::PartitionRefCountPointerNoOffset(ptr);
@@ -803,9 +768,9 @@
   return size;
 }
 
-// Gets the size of the allocated slot that contains |ptr|, adjusted for cookie
-// and tag (if any). CAUTION! For direct-mapped allocation, |ptr| has to be
-// within the first partition page.
+// Gets the size of the allocated slot that contains |ptr|, adjusted for the
+// cookie and ref-count (if any). CAUTION! For direct-mapped allocation, |ptr|
+// has to be within the first partition page.
 template <bool thread_safe>
 ALWAYS_INLINE size_t PartitionRoot<thread_safe>::GetSize(void* ptr) const {
   ptr = AdjustPointerForExtrasSubtract(ptr);
@@ -875,7 +840,7 @@
     int flags,
     size_t requested_size) {
   // The thread cache is added "in the middle" of the main allocator, that is:
-  // - After all the cookie/tag management
+  // - After all the cookie/ref-count management
   // - Before the "raw" allocator.
   //
   // That is, the general allocation flow is:
@@ -883,7 +848,7 @@
   // 2. Allocation:
   //   a. Call to the thread cache, if it succeeds, go to step 3.
   //   b. Otherwise, call the "raw" allocator <-- Locking
-  // 3. Handle cookies/tags, zero allocation if required
+  // 3. Handle cookies/ref-count, zero allocation if required
   size_t raw_size = AdjustSizeForExtrasAdd(requested_size);
   PA_CHECK(raw_size >= requested_size);  // check for overflows
 
@@ -948,13 +913,13 @@
     return nullptr;
 
   // Layout inside the slot:
-  //  |[tag/refcnt]|[cookie]|...data...|[empty]|[cookie]|[unused]|
-  //                        <---(a)---->
-  //                        <-------(b)-------->
-  //  <---------(c)--------->                  <--(c)--->
-  //  <---------------(d)-------------->   +   <--(d)--->
-  //  <-----------------------(e)----------------------->
-  //  <---------------------------(f)---------------------------->
+  //  |[refcnt]|[cookie]|...data...|[empty]|[cookie]|[unused]|
+  //                    <---(a)---->
+  //                    <-------(b)-------->
+  //  <-------(c)------->                  <--(c)--->
+  //  <-------------(d)------------>   +   <--(d)--->
+  //  <---------------------(e)--------------------->
+  //  <-------------------------(f)-------------------------->
   //   (a) requested_size
   //   (b) usable_size
   //   (c) extras
@@ -962,8 +927,8 @@
   //   (e) utilized_slot_size
   //   (f) slot_size
   //
-  // - The tag/ref-count may or may not exist in the slot, depending on
-  //   CheckedPtr implementation.
+  // - Ref-count may or may not exist in the slot, depending on CheckedPtr
+  //   implementation.
   // - Cookies exist only when DCHECK is on.
   // - Think of raw_size as the minimum size required internally to satisfy
   //   the allocation request (i.e. requested_size + extras)
@@ -978,7 +943,7 @@
   //   we have no other choice than putting the cookie at the very end of the
   //   slot, thus creating the "empty" space.
   size_t usable_size = AdjustSizeForExtrasSubtract(utilized_slot_size);
-  // The value given to the application is just after the tag and cookie.
+  // The value given to the application is just after the ref-count and cookie.
   ret = AdjustPointerForExtrasAdd(ret);
 
 #if DCHECK_IS_ON()
@@ -1003,19 +968,6 @@
 
   bool is_direct_mapped = raw_size > kMaxBucketed;
   if (allow_extras && !is_direct_mapped) {
-    // Do not set tag for MTECheckedPtr in the set-tag-at-free case.
-    // It is set only at Free() time and at slot span allocation time.
-#if !ENABLE_TAG_FOR_MTE_CHECKED_PTR || !MTE_CHECKED_PTR_SET_TAG_AT_FREE
-    // PartitionTagSetValue requires that the size is
-    // tag_bitmap::kBytesPerPartitionTag-aligned (currently 16 bytes-aligned)
-    // when MTECheckedPtr is enabled. However, utilized_slot_size may not be
-    // aligned for single-slot slot spans. So we need the bucket's slot_size.
-    size_t slot_size_with_no_extras =
-        AdjustSizeForExtrasSubtract(buckets[bucket_index].slot_size);
-    internal::PartitionTagSetValue(ret, slot_size_with_no_extras,
-                                   GetNewPartitionTag());
-#endif  // !ENABLE_TAG_FOR_MTE_CHECKED_PTR || !MTE_CHECKED_PTR_SET_TAG_AT_FREE
-
 #if ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR
     internal::PartitionRefCountPointerNoOffset(ret)->Init();
 #endif  // ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR
@@ -1041,7 +993,7 @@
     size_t alignment,
     size_t size) {
   // Aligned allocation support relies on the natural alignment guarantees of
-  // PartitionAlloc. Since cookies and tags are layered on top of
+  // PartitionAlloc. Since cookies and ref-count are layered on top of
   // PartitionAlloc, they change the guarantees. As a consequence, forbid both.
   PA_DCHECK(!allow_extras);
 
diff --git a/base/allocator/partition_allocator/partition_tag.h b/base/allocator/partition_allocator/partition_tag.h
deleted file mode 100644
index 1acc603..0000000
--- a/base/allocator/partition_allocator/partition_tag.h
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright (c) 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 BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_H_
-#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_H_
-
-#include <string.h>
-
-#include "base/allocator/partition_allocator/checked_ptr_support.h"
-#include "base/allocator/partition_allocator/partition_alloc_constants.h"
-#include "base/allocator/partition_allocator/partition_cookie.h"
-#include "base/allocator/partition_allocator/partition_tag_bitmap.h"
-#include "base/base_export.h"
-#include "base/notreached.h"
-#include "build/build_config.h"
-
-namespace base {
-
-namespace internal {
-
-#if ENABLE_TAG_FOR_CHECKED_PTR2
-
-// Use 16 bits for the partition tag.
-// TODO(tasak): add a description about the partition tag.
-using PartitionTag = uint8_t;
-
-// Allocate extra space for the partition tag to satisfy the alignment
-// requirement.
-static constexpr size_t kInSlotTagBufferSize = base::kAlignment;
-static_assert(sizeof(PartitionTag) <= kInSlotTagBufferSize,
-              "PartitionTag should fit into the in-slot buffer.");
-
-#if DCHECK_IS_ON()
-// The layout inside the slot is |tag|cookie|object|(empty)|cookie|.
-static constexpr size_t kPartitionTagOffset =
-    kInSlotTagBufferSize + kCookieSize;
-#else
-// The layout inside the slot is |tag|object|(empty)|.
-static constexpr size_t kPartitionTagOffset = kInSlotTagBufferSize;
-#endif
-
-ALWAYS_INLINE PartitionTag* PartitionTagPointer(void* ptr) {
-  return reinterpret_cast<PartitionTag*>(reinterpret_cast<char*>(ptr) -
-                                         kPartitionTagOffset);
-}
-
-ALWAYS_INLINE void PartitionTagSetValue(void* ptr, size_t, PartitionTag value) {
-  *PartitionTagPointer(ptr) = value;
-}
-
-ALWAYS_INLINE PartitionTag PartitionTagGetValue(void* ptr) {
-  return *PartitionTagPointer(ptr);
-}
-
-ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t) {
-  PA_DCHECK(PartitionTagGetValue(ptr));
-  *PartitionTagPointer(ptr) = 0;
-}
-
-#elif ENABLE_TAG_FOR_MTE_CHECKED_PTR
-
-// Use 8 bits for the partition tag.
-// TODO(tasak): add a description about the partition tag.
-using PartitionTag = uint8_t;
-
-static_assert(
-    sizeof(PartitionTag) == tag_bitmap::kPartitionTagSize,
-    "sizeof(PartitionTag) must be equal to bitmap::kPartitionTagSize.");
-
-static constexpr size_t kInSlotTagBufferSize = 0;
-
-ALWAYS_INLINE PartitionTag* PartitionTagPointer(void* ptr) {
-  // See the comment explaining the layout in partition_tag_bitmap.h.
-  uintptr_t pointer_as_uintptr = reinterpret_cast<uintptr_t>(ptr);
-  uintptr_t bitmap_base =
-      (pointer_as_uintptr & kSuperPageBaseMask) + PartitionPageSize();
-  uintptr_t offset =
-      (pointer_as_uintptr & kSuperPageOffsetMask) - PartitionPageSize();
-  // Not to depend on partition_address_space.h and PartitionAllocGigaCage
-  // feature, use "offset" to see whether the given ptr is_direct_mapped or not.
-  // DirectMap object should cause this PA_DCHECK's failure, as tags aren't
-  // currently supported there.
-  PA_DCHECK(offset >= ReservedTagBitmapSize());
-  size_t bitmap_offset = (offset - ReservedTagBitmapSize()) >>
-                         tag_bitmap::kBytesPerPartitionTagShift
-                             << tag_bitmap::kPartitionTagSizeShift;
-  return reinterpret_cast<PartitionTag* const>(bitmap_base + bitmap_offset);
-}
-
-ALWAYS_INLINE void PartitionTagSetValue(void* ptr,
-                                        size_t size,
-                                        PartitionTag value) {
-  PA_DCHECK((size % tag_bitmap::kBytesPerPartitionTag) == 0);
-  size_t tag_count = size >> tag_bitmap::kBytesPerPartitionTagShift;
-  PartitionTag* tag_ptr = PartitionTagPointer(ptr);
-  if (sizeof(PartitionTag) == 1) {
-    memset(tag_ptr, value, tag_count);
-  } else {
-    while (tag_count-- > 0)
-      *tag_ptr++ = value;
-  }
-}
-
-ALWAYS_INLINE PartitionTag PartitionTagGetValue(void* ptr) {
-  return *PartitionTagPointer(ptr);
-}
-
-ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t size) {
-  size_t tag_region_size = size >> tag_bitmap::kBytesPerPartitionTagShift
-                                       << tag_bitmap::kPartitionTagSizeShift;
-  PA_DCHECK(!memchr(PartitionTagPointer(ptr), 0, tag_region_size));
-  memset(PartitionTagPointer(ptr), 0, tag_region_size);
-}
-
-ALWAYS_INLINE void PartitionTagIncrementValue(void* ptr, size_t size) {
-  PartitionTag tag = PartitionTagGetValue(ptr);
-  PartitionTag new_tag = tag;
-  ++new_tag;
-  new_tag += !new_tag;  // Avoid 0.
-#if DCHECK_IS_ON()
-  // This verifies that tags for the entire slot have the same value and that
-  // |size| doesn't exceed the slot size.
-  size_t tag_count = size >> tag_bitmap::kBytesPerPartitionTagShift;
-  PartitionTag* tag_ptr = PartitionTagPointer(ptr);
-  while (tag_count-- > 0) {
-    PA_DCHECK(tag == *tag_ptr);
-    tag_ptr++;
-  }
-#endif
-  PartitionTagSetValue(ptr, size, new_tag);
-}
-
-#elif ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-
-using PartitionTag = uint8_t;
-
-static constexpr PartitionTag kFixedTagValue = 0xAD;
-
-struct PartitionTagWrapper {
-  // Add padding before and after the tag, to avoid cacheline false sharing.
-  // Assume cacheline is 64B.
-  uint8_t unused1[64];
-  PartitionTag partition_tag;
-  uint8_t unused2[64];
-};
-extern BASE_EXPORT PartitionTagWrapper g_checked_ptr_single_tag;
-
-static constexpr size_t kInSlotTagBufferSize = 0;
-
-ALWAYS_INLINE PartitionTag* PartitionTagPointer(void*) {
-  return &g_checked_ptr_single_tag.partition_tag;
-}
-
-ALWAYS_INLINE void PartitionTagSetValue(void*, size_t, PartitionTag) {}
-
-ALWAYS_INLINE PartitionTag PartitionTagGetValue(void* ptr) {
-  return *PartitionTagPointer(ptr);
-}
-
-ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t) {}
-
-#else  // !ENABLE_TAG_FOR_CHECKED_PTR2 && !ENABLE_TAG_FOR_MTE_CHECKED_PTR &&
-       // !ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-
-using PartitionTag = uint8_t;
-
-static constexpr size_t kInSlotTagBufferSize = 0;
-
-ALWAYS_INLINE PartitionTag* PartitionTagPointer(void* ptr) {
-  NOTREACHED();
-  return nullptr;
-}
-
-ALWAYS_INLINE void PartitionTagSetValue(void*, size_t, PartitionTag) {}
-
-ALWAYS_INLINE PartitionTag PartitionTagGetValue(void*) {
-  return 0;
-}
-
-ALWAYS_INLINE void PartitionTagClearValue(void* ptr, size_t) {}
-
-#endif  // !ENABLE_TAG_FOR_CHECKED_PTR2 && !ENABLE_TAG_FOR_MTE_CHECKED_PTR &&
-        // !ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-
-constexpr size_t kPartitionTagSizeAdjustment = kInSlotTagBufferSize;
-constexpr size_t kPartitionTagOffsetAdjustment = kInSlotTagBufferSize;
-
-}  // namespace internal
-}  // namespace base
-
-#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_H_
diff --git a/base/allocator/partition_allocator/partition_tag_bitmap.h b/base/allocator/partition_allocator/partition_tag_bitmap.h
deleted file mode 100644
index c0ff8dd..0000000
--- a/base/allocator/partition_allocator/partition_tag_bitmap.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 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 BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_BITMAP_H_
-#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_BITMAP_H_
-
-#include "base/allocator/partition_allocator/checked_ptr_support.h"
-#include "base/allocator/partition_allocator/page_allocator_constants.h"
-#include "base/allocator/partition_allocator/partition_alloc_constants.h"
-
-namespace base {
-
-namespace internal {
-
-#if ENABLE_TAG_FOR_MTE_CHECKED_PTR
-
-// Normal bucket layout
-// +----------------+ super_page_base
-// | PartitionPage  |
-// | (Meta+Guard)   |
-// +----------------+ super_page_base + PartitionPageSize() (=bitmap_base)
-// |  TagBitmap     |
-// ....
-// +- - - - - - - - + bitmap_base + kActualTagBitmapSize
-// | guard pages(*) | (kActualTagBitmapSize is SystemPageSize()-aligned.)
-// +----------------+ bitmap_base + kReservedTagBitmapSize
-// |   Slot Span    | (kReservedTagBitmapSize is PartitionPageSize()-aligned.)
-// ....
-// ....
-// +----------------+
-// |   Slot Span    |
-// ....
-// ....
-// +----------------+
-// | PartitionPage  |
-// |  (GuardPage)   |
-// +----------------+ super_page_base + kSuperPageSize
-// (*) If kActualTagBitmapSize < kReservedTagBitmapSize, the
-// unused pages are guard pages. This depends on sizeof(PartitionTag).
-// TODO(tasak): Consider guaranteeing guard pages after the tag bitmap, if
-// needed.
-
-namespace tag_bitmap {
-// kPartitionTagSize should be equal to sizeof(PartitionTag).
-// PartitionTag is defined in partition_tag.h and static_assert there
-// checks the condition.
-static constexpr size_t kPartitionTagSizeShift = 0;
-static constexpr size_t kPartitionTagSize = 1U << kPartitionTagSizeShift;
-
-static constexpr size_t kBytesPerPartitionTagShift = 4;
-// One partition tag is assigned per |kBytesPerPartitionTag| bytes in the slot
-// spans.
-//  +-----------+ 0
-//  |           |  ====> 1 partition tag
-//  +-----------+ kBytesPerPartitionTag
-//  |           |  ====> 1 partition tag
-//  +-----------+ 2*kBytesPerPartitionTag
-// ...
-//  +-----------+ slot_size
-static constexpr size_t kBytesPerPartitionTag = 1U
-                                                << kBytesPerPartitionTagShift;
-static_assert(
-    kMinBucketedOrder >= kBytesPerPartitionTagShift + 1,
-    "MTECheckedPtr requires kBytesPerPartitionTagShift-bytes alignment.");
-
-static constexpr size_t kBytesPerPartitionTagRatio =
-    kBytesPerPartitionTag / kPartitionTagSize;
-
-static_assert(kBytesPerPartitionTag > 0,
-              "kBytesPerPartitionTag should be larger than 0");
-static_assert(
-    kBytesPerPartitionTag % kPartitionTagSize == 0,
-    "kBytesPerPartitionTag should be multiples of sizeof(PartitionTag).");
-
-constexpr size_t CeilCountOfUnits(size_t size, size_t unit_size) {
-  return (size + unit_size - 1) / unit_size;
-}
-
-}  // namespace tag_bitmap
-
-// kTagBitmapSize is calculated in the following way:
-// (1) kSuperPageSize - 2 * PartitionPageSize() = kTagBitmapSize +
-// SlotSpanSize()
-// (2) kTagBitmapSize >= SlotSpanSize() / kBytesPerPartitionTag *
-// sizeof(PartitionTag)
-//--
-// (1)' SlotSpanSize() = kSuperPageSize - 2 * PartitionPageSize() -
-// kTagBitmapSize
-// (2)' SlotSpanSize() <= kTagBitmapSize * Y
-// (3)' Y = kBytesPerPartitionTag / sizeof(PartitionTag) =
-// kBytesPerPartitionTagRatio
-//
-//   kTagBitmapSize * Y >= kSuperPageSize - 2 * PartitionPageSize() -
-//   kTagBitmapSize (1 + Y) * kTagBimapSize >= kSuperPageSize - 2 *
-//   PartitionPageSize()
-// Finally,
-//   kTagBitmapSize >= (kSuperPageSize - 2 * PartitionPageSize()) / (1 + Y)
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-NumPartitionPagesPerTagBitmap() {
-  return tag_bitmap::CeilCountOfUnits(
-      kSuperPageSize / PartitionPageSize() - 2,
-      tag_bitmap::kBytesPerPartitionTagRatio + 1);
-}
-
-// To make guard pages between the tag bitmap and the slot span, calculate the
-// number of SystemPages of TagBitmap. If kNumSystemPagesPerTagBitmap *
-// SystemPageSize() < kTagBitmapSize, guard pages will be created. (c.f. no
-// guard pages if sizeof(PartitionTag) == 2.)
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-NumSystemPagesPerTagBitmap() {
-  return tag_bitmap::CeilCountOfUnits(
-      kSuperPageSize / SystemPageSize() -
-          2 * PartitionPageSize() / SystemPageSize(),
-      tag_bitmap::kBytesPerPartitionTagRatio + 1);
-}
-
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-ActualTagBitmapSize() {
-  return NumSystemPagesPerTagBitmap() * SystemPageSize();
-}
-
-// PartitionPageSize-aligned tag bitmap size.
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-ReservedTagBitmapSize() {
-  return PartitionPageSize() * NumPartitionPagesPerTagBitmap();
-}
-
-#if PAGE_ALLOCATOR_CONSTANTS_ARE_CONSTEXPR
-static_assert(ActualTagBitmapSize() <= ReservedTagBitmapSize(),
-              "kActualTagBitmapSize should be smaller than or equal to "
-              "kReservedTagBitmapSize.");
-static_assert(ReservedTagBitmapSize() - ActualTagBitmapSize() <
-                  PartitionPageSize(),
-              "Unused space in the tag bitmap should be smaller than "
-              "PartitionPageSize()");
-
-// The region available for slot spans is the reminder of the super page, after
-// taking away the first and last partition page (for metadata and guard pages)
-// and partition pages reserved for the tag bitmap.
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-SlotSpansSize() {
-  return kSuperPageSize - 2 * PartitionPageSize() - ReservedTagBitmapSize();
-}
-
-static_assert(ActualTagBitmapSize() * tag_bitmap::kBytesPerPartitionTagRatio >=
-                  SlotSpansSize(),
-              "bitmap is large enough to cover slot spans");
-static_assert((ActualTagBitmapSize() - PartitionPageSize()) *
-                      tag_bitmap::kBytesPerPartitionTagRatio <
-                  SlotSpansSize(),
-              "any smaller bitmap wouldn't suffice to cover slots spans");
-#endif
-
-#else  // !ENABLE_TAG_FOR_MTE_CHECKED_PTR
-
-constexpr ALWAYS_INLINE size_t NumPartitionPagesPerTagBitmap() {
-  return 0;
-}
-
-constexpr ALWAYS_INLINE size_t ActualTagBitmapSize() {
-  return 0;
-}
-
-constexpr ALWAYS_INLINE size_t ReservedTagBitmapSize() {
-  return 0;
-}
-
-#endif
-
-}  // namespace internal
-}  // namespace base
-
-#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_BITMAP_H_
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h
index 9f75bd97..10805e7 100644
--- a/base/allocator/partition_allocator/thread_cache.h
+++ b/base/allocator/partition_allocator/thread_cache.h
@@ -142,7 +142,8 @@
   // Tries to allocate memory from the cache.
   // Returns nullptr for failure.
   //
-  // Has the same behavior as RawAlloc(), that is: no cookie nor tag handling.
+  // Has the same behavior as RawAlloc(), that is: no cookie nor ref-count
+  // handling.
   ALWAYS_INLINE void* GetFromCache(size_t bucket_index);
 
   // Asks this cache to trigger |Purge()| at a later point. Can be called from
diff --git a/base/android/java/src/org/chromium/base/RadioUtils.java b/base/android/java/src/org/chromium/base/RadioUtils.java
index 1ca65b8..ee9f990 100644
--- a/base/android/java/src/org/chromium/base/RadioUtils.java
+++ b/base/android/java/src/org/chromium/base/RadioUtils.java
@@ -88,7 +88,7 @@
 
     /**
      * Return current cell signal level.
-     * @return Signal level from 0 (no signal) to 4 (good signal).
+     * @return Signal level from 0 (no signal) to 4 (good signal) or -1 in case of error.
      */
     @CalledByNative
     @TargetApi(Build.VERSION_CODES.P)
@@ -109,4 +109,23 @@
         }
         return level;
     }
+
+    /**
+     * Return current cell data activity.
+     * @return 0 - none, 1 - in, 2 - out, 3 - in/out, 4 - dormant, or -1 in case of error.
+     */
+    @CalledByNative
+    @TargetApi(Build.VERSION_CODES.P)
+    private static int getCellDataActivity() {
+        assert isSupported();
+        TelephonyManager telephonyManager =
+                (TelephonyManager) ContextUtils.getApplicationContext().getSystemService(
+                        Context.TELEPHONY_SERVICE);
+        try {
+            return telephonyManager.getDataActivity();
+        } catch (java.lang.SecurityException e) {
+            // Just in case getDataActivity() requires extra permissions.
+            return -1;
+        }
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/library_loader/Linker.java b/base/android/java/src/org/chromium/base/library_loader/Linker.java
index 9b0eac7..798acb5 100644
--- a/base/android/java/src/org/chromium/base/library_loader/Linker.java
+++ b/base/android/java/src/org/chromium/base/library_loader/Linker.java
@@ -138,10 +138,6 @@
     @GuardedBy("sLock")
     protected LibInfo mLibInfo;
 
-    // Becomes true to indicate this process needs to wait for a shared RELRO in LibraryLoad().
-    @GuardedBy("sLock")
-    protected boolean mWaitForSharedRelros;
-
     // Set to true if this runs in the browser process. Disabled by initServiceProcess().
     @GuardedBy("sLock")
     protected boolean mInBrowserProcess = true;
@@ -258,8 +254,7 @@
         synchronized (sLock) {
             mInBrowserProcess = false;
             ensureInitializedLocked();
-            assert mState == State.INITIALIZED; // Not after the library has been loaded.
-            mWaitForSharedRelros = false;
+            assert mState == State.INITIALIZED;
         }
     }
 
@@ -298,7 +293,7 @@
      * file. The library must not be the Chromium linker library.
      *
      * @param library The library name to load.
-     * @param isFixesAddressPermitted Whether the library can be loaded at a fixed address for RELRO
+     * @param isFixedAddressPermitted Whether the library can be loaded at a fixed address for RELRO
      * sharing.
      */
     final void loadLibrary(String library, boolean isFixedAddressPermitted) {
@@ -359,11 +354,8 @@
         if (DEBUG) Log.i(TAG, "initServiceProcess(0x%x) called", baseLoadAddress);
         synchronized (sLock) {
             mInBrowserProcess = false;
-
             ensureInitializedLocked();
             assert mState == State.INITIALIZED;
-
-            mWaitForSharedRelros = true;
             mBaseLoadAddress = baseLoadAddress;
         }
     }
@@ -456,15 +448,7 @@
     // Used internally to lazily setup the common random base load address.
     @GuardedBy("sLock")
     private void setupBaseLoadAddressLocked() {
-        if (mBaseLoadAddress == -1) {
-            mBaseLoadAddress = getRandomBaseLoadAddress();
-            if (mBaseLoadAddress == 0) {
-                // If the random address is 0 there are issues with finding enough
-                // free address space, so disable RELRO shared / fixed load addresses.
-                Log.w(TAG, "Disabling shared RELROs due address space pressure");
-                mWaitForSharedRelros = false;
-            }
-        }
+        if (mBaseLoadAddress == -1) mBaseLoadAddress = getRandomBaseLoadAddress();
     }
 
     /**
diff --git a/base/android/radio_utils.cc b/base/android/radio_utils.cc
index 22d177d..0d0c4a6d 100644
--- a/base/android/radio_utils.cc
+++ b/base/android/radio_utils.cc
@@ -29,5 +29,11 @@
   }
 }
 
+RadioDataActivity RadioUtils::GetCellDataActivity() {
+  JNIEnv* env = AttachCurrentThread();
+  return static_cast<RadioDataActivity>(
+      Java_RadioUtils_getCellDataActivity(env));
+}
+
 }  // namespace android
 }  // namespace base
diff --git a/base/android/radio_utils.h b/base/android/radio_utils.h
index 9980d00..a44b697 100644
--- a/base/android/radio_utils.h
+++ b/base/android/radio_utils.h
@@ -23,11 +23,20 @@
   kMaxValue = kGreat,
 };
 
+enum class RadioDataActivity {
+  kNone = 0,
+  kIn = 1,
+  kOut = 2,
+  kInOut = 3,
+  kDormant = 4,
+};
+
 class BASE_EXPORT RadioUtils {
  public:
   static bool IsSupported();
   static bool IsWifiConnected();
   static Optional<RadioSignalLevel> GetCellSignalLevel();
+  static RadioDataActivity GetCellDataActivity();
 };
 
 }  // namespace android
diff --git a/base/containers/fixed_flat_map.h b/base/containers/fixed_flat_map.h
index 6bceee9..802e102 100644
--- a/base/containers/fixed_flat_map.h
+++ b/base/containers/fixed_flat_map.h
@@ -99,7 +99,7 @@
     std::pair<Key, Mapped>(&&data)[N],
     const Compare& comp = Compare()) {
   using FixedFlatMap = fixed_flat_map<Key, Mapped, N, Compare>;
-  typename FixedFlatMap::value_compare value_comp(comp);
+  typename FixedFlatMap::value_compare value_comp{comp};
   internal::InsertionSort(data, data + N, value_comp);
   CHECK(internal::is_sorted_and_unique(data, value_comp));
   // Specify the value_type explicitly to ensure that the returned array has
diff --git a/base/containers/flat_tree.h b/base/containers/flat_tree.h
index 8196f75..22952d0 100644
--- a/base/containers/flat_tree.h
+++ b/base/containers/flat_tree.h
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/compiler_specific.h"
 #include "base/functional/not_fn.h"
 #include "base/ranges/algorithm.h"
 #include "base/stl_util.h"
@@ -145,19 +146,14 @@
   using value_type = typename Container::value_type;
 
   // Wraps the templated key comparison to compare values.
-  class value_compare : public key_compare {
-   public:
-    value_compare() = default;
-
-    template <class Cmp>
-    constexpr explicit value_compare(Cmp&& compare_arg)
-        : KeyCompare(std::forward<Cmp>(compare_arg)) {}
-
+  struct value_compare {
     constexpr bool operator()(const value_type& left,
                               const value_type& right) const {
       GetKeyFromValue extractor;
-      return key_compare::operator()(extractor(left), extractor(right));
+      return comp(extractor(left), extractor(right));
     }
+
+    NO_UNIQUE_ADDRESS key_compare comp;
   };
 
   using pointer = typename Container::pointer;
@@ -399,7 +395,7 @@
   void swap(flat_tree& other) noexcept;
 
   friend bool operator==(const flat_tree& lhs, const flat_tree& rhs) {
-    return lhs.impl_.body_ == rhs.impl_.body_;
+    return lhs.body_ == rhs.body_;
   }
 
   friend bool operator!=(const flat_tree& lhs, const flat_tree& rhs) {
@@ -407,7 +403,7 @@
   }
 
   friend bool operator<(const flat_tree& lhs, const flat_tree& rhs) {
-    return lhs.impl_.body_ < rhs.impl_.body_;
+    return lhs.body_ < rhs.body_;
   }
 
   friend bool operator>(const flat_tree& lhs, const flat_tree& rhs) {
@@ -449,12 +445,11 @@
   // to a key on the right.
   struct KeyValueCompare {
     // The key comparison object must outlive this class.
-    explicit KeyValueCompare(const key_compare& key_comp)
-        : key_comp_(key_comp) {}
+    explicit KeyValueCompare(const key_compare& comp) : comp_(comp) {}
 
     template <typename T, typename U>
     bool operator()(const T& lhs, const U& rhs) const {
-      return key_comp_(extract_if_value_type(lhs), extract_if_value_type(rhs));
+      return comp_(extract_if_value_type(lhs), extract_if_value_type(rhs));
     }
 
    private:
@@ -468,7 +463,7 @@
       return k;
     }
 
-    const key_compare& key_comp_;
+    const key_compare& comp_;
   };
 
   iterator const_cast_it(const_iterator c_it) {
@@ -486,7 +481,7 @@
     auto position = lower_bound(GetKeyFromValue()(val));
 
     if (position == end() || value_comp()(val, *position))
-      return {impl_.body_.emplace(position, std::forward<V>(val)), true};
+      return {body_.emplace(position, std::forward<V>(val)), true};
 
     *position = std::forward<V>(val);
     return {position, false};
@@ -507,7 +502,7 @@
       // emplace_back might invalidate position, which is why distance needs to
       // be cached.
       const difference_type distance = std::distance(begin(), position);
-      impl_.body_.emplace_back(std::forward<V>(val));
+      body_.emplace_back(std::forward<V>(val));
       return {std::next(begin(), distance), true};
     }
 
@@ -530,7 +525,7 @@
       // emplace_back might invalidate position, which is why distance needs to
       // be cached.
       const difference_type distance = std::distance(begin(), position);
-      impl_.body_.emplace_back(std::forward<V>(val));
+      body_.emplace_back(std::forward<V>(val));
       return {std::next(begin(), distance), true};
     }
 
@@ -548,24 +543,11 @@
 
   void sort_and_unique() { sort_and_unique(begin(), end()); }
 
+  container_type body_;
   // To support comparators that may not be possible to default-construct, we
-  // have to store an instance of Compare. Using this to store all internal
-  // state of flat_tree and using private inheritance to store compare lets us
-  // take advantage of an empty base class optimization to avoid extra space in
-  // the common case when Compare has no state.
-  struct Impl : private value_compare {
-    Impl() = default;
-
-    template <class Cmp, class... Body>
-    constexpr explicit Impl(Cmp&& compare_arg, Body&&... underlying_type_args)
-        : value_compare(std::forward<Cmp>(compare_arg)),
-          body_(std::forward<Body>(underlying_type_args)...) {}
-
-    constexpr const value_compare& get_value_comp() const { return *this; }
-    constexpr const key_compare& get_key_comp() const { return *this; }
-
-    container_type body_;
-  } impl_;
+  // have to store an instance of Compare. Since Compare commonly is stateless,
+  // we use the NO_UNIQUE_ADDRESS attribute to save space.
+  NO_UNIQUE_ADDRESS key_compare comp_;
 
   // If the compare is not transparent we want to construct key_type once.
   template <typename K>
@@ -579,7 +561,7 @@
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
     const KeyCompare& comp)
-    : impl_(comp) {}
+    : comp_(comp) {}
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 template <class InputIterator>
@@ -587,7 +569,7 @@
     InputIterator first,
     InputIterator last,
     const KeyCompare& comp)
-    : impl_(comp, first, last) {
+    : body_(first, last), comp_(comp) {
   sort_and_unique();
 }
 
@@ -595,7 +577,7 @@
 flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
     const container_type& items,
     const KeyCompare& comp)
-    : impl_(comp, items) {
+    : body_(items), comp_(comp) {
   sort_and_unique();
 }
 
@@ -603,7 +585,7 @@
 flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
     container_type&& items,
     const KeyCompare& comp)
-    : impl_(comp, std::move(items)) {
+    : body_(std::move(items)), comp_(comp) {
   sort_and_unique();
 }
 
@@ -620,7 +602,7 @@
     InputIterator first,
     InputIterator last,
     const KeyCompare& comp)
-    : impl_(comp, first, last) {
+    : body_(first, last), comp_(comp) {
   DCHECK(is_sorted_and_unique(*this, value_comp()));
 }
 
@@ -629,7 +611,7 @@
     sorted_unique_t,
     const container_type& items,
     const KeyCompare& comp)
-    : impl_(comp, items) {
+    : body_(items), comp_(comp) {
   DCHECK(is_sorted_and_unique(*this, value_comp()));
 }
 
@@ -638,7 +620,7 @@
     sorted_unique_t,
     container_type&& items,
     const KeyCompare& comp)
-    : impl_(comp, std::move(items)) {
+    : body_(std::move(items)), comp_(comp) {
   DCHECK(is_sorted_and_unique(*this, value_comp()));
 }
 
@@ -665,7 +647,7 @@
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::operator=(
     std::initializer_list<value_type> ilist) -> flat_tree& {
-  impl_.body_ = ilist;
+  body_ = ilist;
   sort_and_unique();
   return *this;
 }
@@ -676,18 +658,18 @@
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::reserve(
     size_type new_capacity) {
-  impl_.body_.reserve(new_capacity);
+  body_.reserve(new_capacity);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::capacity() const
     -> size_type {
-  return impl_.body_.capacity();
+  return body_.capacity();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::shrink_to_fit() {
-  impl_.body_.shrink_to_fit();
+  body_.shrink_to_fit();
 }
 
 // ----------------------------------------------------------------------------
@@ -695,24 +677,24 @@
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::clear() {
-  impl_.body_.clear();
+  body_.clear();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::size() const
     -> size_type {
-  return impl_.body_.size();
+  return body_.size();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::max_size() const
     -> size_type {
-  return impl_.body_.max_size();
+  return body_.max_size();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 bool flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::empty() const {
-  return impl_.body_.empty();
+  return body_.empty();
 }
 
 // ----------------------------------------------------------------------------
@@ -721,72 +703,72 @@
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::begin()
     -> iterator {
-  return impl_.body_.begin();
+  return body_.begin();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 constexpr auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::begin()
     const -> const_iterator {
-  return ranges::begin(impl_.body_);
+  return ranges::begin(body_);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::cbegin() const
     -> const_iterator {
-  return impl_.body_.cbegin();
+  return body_.cbegin();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::end() -> iterator {
-  return impl_.body_.end();
+  return body_.end();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 constexpr auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::end()
     const -> const_iterator {
-  return ranges::end(impl_.body_);
+  return ranges::end(body_);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::cend() const
     -> const_iterator {
-  return impl_.body_.cend();
+  return body_.cend();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rbegin()
     -> reverse_iterator {
-  return impl_.body_.rbegin();
+  return body_.rbegin();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rbegin() const
     -> const_reverse_iterator {
-  return impl_.body_.rbegin();
+  return body_.rbegin();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::crbegin() const
     -> const_reverse_iterator {
-  return impl_.body_.crbegin();
+  return body_.crbegin();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rend()
     -> reverse_iterator {
-  return impl_.body_.rend();
+  return body_.rend();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rend() const
     -> const_reverse_iterator {
-  return impl_.body_.rend();
+  return body_.rend();
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::crend() const
     -> const_reverse_iterator {
-  return impl_.body_.crend();
+  return body_.crend();
 }
 
 // ----------------------------------------------------------------------------
@@ -885,7 +867,7 @@
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::
     extract() && -> container_type {
-  return std::exchange(impl_.body_, container_type());
+  return std::exchange(body_, container_type());
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
@@ -894,7 +876,7 @@
   // Ensure that `body` is sorted and has no repeated elements according to
   // `value_comp()`.
   DCHECK(is_sorted_and_unique(body, value_comp()));
-  impl_.body_ = std::move(body);
+  body_ = std::move(body);
 }
 
 // ----------------------------------------------------------------------------
@@ -903,16 +885,16 @@
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(
     iterator position) -> iterator {
-  CHECK(position != impl_.body_.end());
-  return impl_.body_.erase(position);
+  CHECK(position != body_.end());
+  return body_.erase(position);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 template <typename DummyT>
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(
     const_iterator position) -> iterator {
-  CHECK(position != impl_.body_.end());
-  return impl_.body_.erase(position);
+  CHECK(position != body_.end());
+  return body_.erase(position);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
@@ -929,7 +911,7 @@
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(
     const_iterator first,
     const_iterator last) -> iterator {
-  return impl_.body_.erase(first, last);
+  return body_.erase(first, last);
 }
 
 // ----------------------------------------------------------------------------
@@ -939,14 +921,14 @@
 constexpr auto
 flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::key_comp() const
     -> key_compare {
-  return impl_.get_key_comp();
+  return comp_;
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 constexpr auto
 flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::value_comp() const
     -> value_compare {
-  return impl_.get_value_comp();
+  return value_compare{comp_};
 }
 
 // ----------------------------------------------------------------------------
@@ -980,7 +962,7 @@
 bool flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::contains(
     const K& key) const {
   auto lower = lower_bound(key);
-  return lower != end() && !key_comp()(key, GetKeyFromValue()(*lower));
+  return lower != end() && !comp_(key, GetKeyFromValue()(*lower));
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
@@ -997,8 +979,8 @@
     const K& key) const -> std::pair<const_iterator, const_iterator> {
   auto lower = lower_bound(key);
 
-  GetKeyFromValue extractor;
-  if (lower == end() || impl_.get_key_comp()(key, extractor(*lower)))
+  KeyValueCompare comp(comp_);
+  if (lower == end() || comp(key, *lower))
     return {lower, lower};
 
   return {lower, std::next(lower)};
@@ -1021,8 +1003,8 @@
 
   const KeyTypeOrK<K>& key_ref = key;
 
-  KeyValueCompare key_value(impl_.get_key_comp());
-  return ranges::lower_bound(*this, key_ref, key_value);
+  KeyValueCompare comp(comp_);
+  return ranges::lower_bound(*this, key_ref, comp);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
@@ -1042,8 +1024,8 @@
 
   const KeyTypeOrK<K>& key_ref = key;
 
-  KeyValueCompare key_value(impl_.get_key_comp());
-  return ranges::upper_bound(*this, key_ref, key_value);
+  KeyValueCompare comp(comp_);
+  return ranges::upper_bound(*this, key_ref, comp);
 }
 
 // ----------------------------------------------------------------------------
@@ -1052,7 +1034,7 @@
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
 void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::swap(
     flat_tree& other) noexcept {
-  std::swap(impl_, other.impl_);
+  std::swap(*this, other);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
@@ -1060,7 +1042,7 @@
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::unsafe_emplace(
     const_iterator position,
     Args&&... args) -> iterator {
-  return impl_.body_.emplace(position, std::forward<Args>(args)...);
+  return body_.emplace(position, std::forward<Args>(args)...);
 }
 
 template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
@@ -1069,7 +1051,7 @@
     const K& key,
     Args&&... args) -> std::pair<iterator, bool> {
   auto lower = lower_bound(key);
-  if (lower == end() || key_comp()(key, GetKeyFromValue()(*lower)))
+  if (lower == end() || comp_(key, GetKeyFromValue()(*lower)))
     return {unsafe_emplace(lower, std::forward<Args>(args)...), true};
   return {lower, false};
 }
@@ -1079,13 +1061,13 @@
 auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::
     emplace_hint_key_args(const_iterator hint, const K& key, Args&&... args)
         -> std::pair<iterator, bool> {
-  GetKeyFromValue extractor;
-  if ((hint == begin() || key_comp()(extractor(*std::prev(hint)), key))) {
-    if (hint == end() || key_comp()(key, extractor(*hint))) {
+  KeyValueCompare comp(comp_);
+  if ((hint == begin() || comp(*std::prev(hint), key))) {
+    if (hint == end() || comp(key, *hint)) {
       // *(hint - 1) < key < *hint => key did not exist and hint is correct.
       return {unsafe_emplace(hint, std::forward<Args>(args)...), true};
     }
-    if (!key_comp()(extractor(*hint), key)) {
+    if (!comp(*hint, key)) {
       // key == *hint => no-op, return correct hint.
       return {const_cast_it(hint), false};
     }
diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc
index 8d435d2..36bc0929 100644
--- a/base/files/important_file_writer.cc
+++ b/base/files/important_file_writer.cc
@@ -274,8 +274,13 @@
   tmp_file.Close();
   const bool result = ReplaceFile(tmp_file_path, path, &replace_file_error);
 #if defined(OS_WIN)
+  // Save and restore the last error code so that it's not polluted by the
+  // thread priority change.
+  const auto last_error = ::GetLastError();
   if (reset_priority)
     PlatformThread::SetCurrentThreadPriority(previous_priority);
+  if (!result)
+    ::SetLastError(last_error);
 #endif  // defined(OS_WIN)
 
   if (!result) {
diff --git a/base/memory/checked_ptr.h b/base/memory/checked_ptr.h
index 92ec669..3687ed18 100644
--- a/base/memory/checked_ptr.h
+++ b/base/memory/checked_ptr.h
@@ -14,20 +14,12 @@
 #include "base/allocator/partition_allocator/partition_address_space.h"
 #include "base/allocator/partition_allocator/partition_alloc_forward.h"
 #include "base/allocator/partition_allocator/partition_ref_count.h"
-#include "base/allocator/partition_allocator/partition_tag.h"
 #include "base/check_op.h"
 #include "base/compiler_specific.h"
 #include "base/partition_alloc_buildflags.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
 
-#define ENABLE_CHECKED_PTR2_OR_MTE_IMPL 0
-#if ENABLE_CHECKED_PTR2_OR_MTE_IMPL
-static_assert(ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_MTE_CHECKED_PTR ||
-                  ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR,
-              "CheckedPtr2OrMTEImpl can only by used if tags are enabled");
-#endif
-
 #define ENABLE_BACKUP_REF_PTR_IMPL 0
 #if ENABLE_BACKUP_REF_PTR_IMPL
 static_assert(ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR,
@@ -35,12 +27,6 @@
               "enabled");
 #endif
 
-#define CHECKED_PTR2_USE_NO_OP_WRAPPER 0
-#define CHECKED_PTR2_USE_TRIVIAL_UNWRAPPER 0
-
-// Set it to 1 to avoid branches when dereferencing the pointer.
-#define CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING 1
-
 namespace base {
 
 // NOTE: All methods should be ALWAYS_INLINE. CheckedPtr is meant to be a
@@ -116,211 +102,6 @@
 
 #if defined(ARCH_CPU_64_BITS) && !defined(OS_NACL)
 
-constexpr int kValidAddressBits = 48;
-constexpr uintptr_t kAddressMask = (1ull << kValidAddressBits) - 1;
-constexpr int kGenerationBits = sizeof(uintptr_t) * 8 - kValidAddressBits;
-constexpr uintptr_t kGenerationMask = ~kAddressMask;
-constexpr int kTopBitShift = 63;
-constexpr uintptr_t kTopBit = 1ull << kTopBitShift;
-static_assert(kTopBit << 1 == 0, "kTopBit should really be the top bit");
-static_assert((kTopBit & kGenerationMask) > 0,
-              "kTopBit bit must be inside the generation region");
-
-#if BUILDFLAG(USE_PARTITION_ALLOC) && ENABLE_CHECKED_PTR2_OR_MTE_IMPL
-// This functionality is outside of CheckedPtr2OrMTEImpl, so that it can be
-// overridden by tests.
-struct CheckedPtr2OrMTEImplPartitionAllocSupport {
-  // Checks if the necessary support is enabled in PartitionAlloc for |ptr|.
-  static ALWAYS_INLINE bool EnabledForPtr(void* ptr) {
-    // CheckedPtr2 and MTECheckedPtr algorithms work only when memory is
-    // allocated by PartitionAlloc, from normal buckets pool. CheckedPtr2
-    // additionally requires that the pointer points to the beginning of the
-    // allocated slot.
-    //
-    // TODO(bartekn): Allow direct-map buckets for MTECheckedPtr, once
-    // PartitionAlloc supports it. (Currently not implemented for simplicity,
-    // but there are no technological obstacles preventing it; whereas in case
-    // of CheckedPtr2, PartitionAllocGetSlotOffset won't work with direct-map.)
-    return IsManagedByPartitionAllocNormalBuckets(ptr)
-    // Checking offset is not needed for ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR,
-    // but call it anyway for apples-to-apples comparison with
-    // ENABLE_TAG_FOR_CHECKED_PTR2.
-#if ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-           && base::internal::PartitionAllocGetSlotOffset(ptr) == 0
-#endif
-        ;
-  }
-
-  // Returns pointer to the tag that protects are pointed by |ptr|.
-  static ALWAYS_INLINE void* TagPointer(void* ptr) {
-    return PartitionTagPointer(ptr);
-  }
-};
-#endif  // BUILDFLAG(USE_PARTITION_ALLOC) && ENABLE_CHECKED_PTR2_OR_MTE_IMPL
-
-template <typename PartitionAllocSupport>
-struct CheckedPtr2OrMTEImpl {
-  // This implementation assumes that pointers are 64 bits long and at least 16
-  // top bits are unused. The latter is harder to verify statically, but this is
-  // true for all currently supported 64-bit architectures (DCHECK when wrapping
-  // will verify that).
-  static_assert(sizeof(void*) >= 8, "Need 64-bit pointers");
-
-  // Wraps a pointer, and returns its uintptr_t representation.
-  static ALWAYS_INLINE uintptr_t WrapRawPtr(const volatile void* cv_ptr) {
-    void* ptr = const_cast<void*>(cv_ptr);
-    uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
-#if !CHECKED_PTR2_USE_NO_OP_WRAPPER
-    // Make sure that the address bits that will be used for generation are 0.
-    // If they aren't, they'd fool the unwrapper into thinking that the
-    // protection is enabled, making it try to read and compare the generation.
-    DCHECK_EQ(ExtractGeneration(addr), 0ull);
-
-    // Return a not-wrapped |addr|, if it's either nullptr or if the protection
-    // for this pointer is disabled.
-    if (!PartitionAllocSupport::EnabledForPtr(ptr)) {
-      return addr;
-    }
-
-    // Read the generation and place it in the top bits of the address.
-    // Even if PartitionAlloc's tag has less than kGenerationBits, we'll read
-    // what's given and pad the rest with 0s.
-    static_assert(sizeof(PartitionTag) * 8 <= kGenerationBits, "");
-    uintptr_t generation = *(static_cast<volatile PartitionTag*>(
-        PartitionAllocSupport::TagPointer(ptr)));
-
-    generation <<= kValidAddressBits;
-    addr |= generation;
-#endif  // !CHECKED_PTR2_USE_NO_OP_WRAPPER
-    return addr;
-  }
-
-  // Notifies the allocator when a wrapped pointer is being removed or replaced.
-  // No-op for CheckedPtr2OrMTEImpl.
-  static ALWAYS_INLINE void ReleaseWrappedPtr(uintptr_t) {}
-
-  // Returns equivalent of |WrapRawPtr(nullptr)|. Separated out to make it a
-  // constexpr.
-  static constexpr ALWAYS_INLINE uintptr_t GetWrappedNullPtr() {
-    return kWrappedNullPtr;
-  }
-
-  // Unwraps the pointer's uintptr_t representation, while asserting that memory
-  // hasn't been freed. The function is allowed to crash on nullptr.
-  static ALWAYS_INLINE void* SafelyUnwrapPtrForDereference(
-      uintptr_t wrapped_ptr) {
-    uintptr_t ptr_generation = wrapped_ptr >> kValidAddressBits;
-    if (ptr_generation > 0) {
-      // Read the generation provided by PartitionAlloc.
-      //
-      // Cast to volatile to ensure memory is read. E.g. in a tight loop, the
-      // compiler could cache the value in a register and thus could miss that
-      // another thread freed memory and cleared generation.
-      uintptr_t read_generation = *static_cast<volatile PartitionTag*>(
-          PartitionAllocSupport::TagPointer(ExtractPtr(wrapped_ptr)));
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING
-      // Use hardware to detect generation mismatch. CPU will crash if top bits
-      // aren't all 0 (technically it won't if all bits are 1, but that's a
-      // kernel mode address, which isn't allowed either).
-      read_generation <<= kValidAddressBits;
-      return reinterpret_cast<void*>(read_generation ^ wrapped_ptr);
-#else
-      if (UNLIKELY(ptr_generation != read_generation))
-        IMMEDIATE_CRASH();
-      return reinterpret_cast<void*>(wrapped_ptr & kAddressMask);
-#endif  // CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING
-    }
-    return reinterpret_cast<void*>(wrapped_ptr);
-  }
-
-  // Unwraps the pointer's uintptr_t representation, while asserting that memory
-  // hasn't been freed. The function must handle nullptr gracefully.
-  static ALWAYS_INLINE void* SafelyUnwrapPtrForExtraction(
-      uintptr_t wrapped_ptr) {
-    // SafelyUnwrapPtrForDereference handles nullptr case well.
-    return SafelyUnwrapPtrForDereference(wrapped_ptr);
-  }
-
-  // Unwraps the pointer's uintptr_t representation, without making an assertion
-  // on whether memory was freed or not.
-  static ALWAYS_INLINE void* UnsafelyUnwrapPtrForComparison(
-      uintptr_t wrapped_ptr) {
-    return ExtractPtr(wrapped_ptr);
-  }
-
-  // Upcasts the wrapped pointer.
-  template <typename To, typename From>
-  static ALWAYS_INLINE uintptr_t Upcast(uintptr_t wrapped_ptr) {
-    static_assert(std::is_convertible<From*, To*>::value,
-                  "From must be convertible to To.");
-
-#if ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR
-    if (IsPtrUnaffectedByUpcast<To, From>())
-      return wrapped_ptr;
-
-    // CheckedPtr2 doesn't support a pointer pointing in the middle of an
-    // allocated object, so disable the generation tag.
-    //
-    // Clearing tag is not needed for ENABLE_TAG_FOR_SINGLE_TAG_CHECKED_PTR,
-    // but do it anyway for apples-to-apples comparison with
-    // ENABLE_TAG_FOR_CHECKED_PTR2.
-    uintptr_t base_addr = reinterpret_cast<uintptr_t>(
-        static_cast<To*>(reinterpret_cast<From*>(ExtractPtr(wrapped_ptr))));
-    return base_addr;
-#elif ENABLE_TAG_FOR_MTE_CHECKED_PTR
-    // The top-bit generation tag must not affect the result of upcast.
-    return reinterpret_cast<uintptr_t>(
-        static_cast<To*>(reinterpret_cast<From*>(wrapped_ptr)));
-#else
-    static_assert(std::is_void<To>::value,  // Always false.
-                  "Unknown tagging mode");
-    return 0;
-#endif
-  }
-
-  // Advance the wrapped pointer by |delta| bytes.
-  static ALWAYS_INLINE uintptr_t Advance(uintptr_t wrapped_ptr, size_t delta) {
-    // Mask out the generation to disable the protection. It's not supported for
-    // pointers inside an allocation.
-    return ExtractAddress(wrapped_ptr) + delta;
-  }
-
-  // Returns a copy of a wrapped pointer, without making an assertion
-  // on whether memory was freed or not.
-  static ALWAYS_INLINE uintptr_t Duplicate(uintptr_t wrapped_ptr) {
-    return wrapped_ptr;
-  }
-
-  // This is for accounting only, used by unit tests.
-  static ALWAYS_INLINE void IncrementSwapCountForTest() {}
-
- private:
-  static ALWAYS_INLINE uintptr_t ExtractAddress(uintptr_t wrapped_ptr) {
-    return wrapped_ptr & kAddressMask;
-  }
-  static ALWAYS_INLINE void* ExtractPtr(uintptr_t wrapped_ptr) {
-    return reinterpret_cast<void*>(ExtractAddress(wrapped_ptr));
-  }
-  static ALWAYS_INLINE uintptr_t ExtractGeneration(uintptr_t wrapped_ptr) {
-    return wrapped_ptr & kGenerationMask;
-  }
-
-  template <typename To, typename From>
-  static constexpr ALWAYS_INLINE bool IsPtrUnaffectedByUpcast() {
-    static_assert(std::is_convertible<From*, To*>::value,
-                  "From must be convertible to To.");
-    uintptr_t d = 0x10000;
-    From* dp = reinterpret_cast<From*>(d);
-    To* bp = dp;
-    uintptr_t b = reinterpret_cast<uintptr_t>(bp);
-    return b == d;
-  }
-
-  // This relies on nullptr and 0 being equal in the eyes of reinterpret_cast,
-  // which apparently isn't true in some rare environments.
-  static constexpr uintptr_t kWrappedNullPtr = 0;
-};
-
 #if ENABLE_BACKUP_REF_PTR_IMPL
 
 struct BackupRefPtrImpl {
@@ -427,16 +208,11 @@
 template <typename T,
 #if defined(ARCH_CPU_64_BITS) && !defined(OS_NACL) && \
     BUILDFLAG(USE_PARTITION_ALLOC)
-
-#if ENABLE_CHECKED_PTR2_OR_MTE_IMPL
-          typename Impl = internal::CheckedPtr2OrMTEImpl<
-              internal::CheckedPtr2OrMTEImplPartitionAllocSupport>>
-#elif ENABLE_BACKUP_REF_PTR_IMPL
+#if ENABLE_BACKUP_REF_PTR_IMPL
           typename Impl = internal::BackupRefPtrImpl>
 #else
           typename Impl = internal::CheckedPtrNoOpImpl>
 #endif
-
 #else  // defined(ARCH_CPU_64_BITS) && !defined(OS_NACL) &&
        // BUILDFLAG(USE_PARTITION_ALLOC)
           typename Impl = internal::CheckedPtrNoOpImpl>
@@ -704,21 +480,13 @@
   // dereferenced. It is allowed to crash on nullptr (it may or may not),
   // because it knows that the caller will crash on nullptr.
   ALWAYS_INLINE T* GetForDereference() const {
-#if CHECKED_PTR2_USE_TRIVIAL_UNWRAPPER
-    return static_cast<T*>(Impl::UnsafelyUnwrapPtrForComparison(wrapped_ptr_));
-#else
     return static_cast<T*>(Impl::SafelyUnwrapPtrForDereference(wrapped_ptr_));
-#endif
   }
   // This getter is meant for situations where the raw pointer is meant to be
   // extracted outside of this class, but not necessarily with an intention to
   // dereference. It mustn't crash on nullptr.
   ALWAYS_INLINE T* GetForExtraction() const {
-#if CHECKED_PTR2_USE_TRIVIAL_UNWRAPPER
-    return static_cast<T*>(Impl::UnsafelyUnwrapPtrForComparison(wrapped_ptr_));
-#else
     return static_cast<T*>(Impl::SafelyUnwrapPtrForExtraction(wrapped_ptr_));
-#endif
   }
   // This getter is meant *only* for situations where the pointer is meant to be
   // compared (guaranteeing no dereference or extraction outside of this class).
diff --git a/base/memory/checked_ptr_unittest.cc b/base/memory/checked_ptr_unittest.cc
index d491123..36cdf72 100644
--- a/base/memory/checked_ptr_unittest.cc
+++ b/base/memory/checked_ptr_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/allocator/partition_allocator/checked_ptr_support.h"
 #include "base/allocator/partition_allocator/partition_alloc.h"
 #include "base/allocator/partition_allocator/partition_alloc_features.h"
-#include "base/allocator/partition_allocator/partition_tag.h"
 #include "base/logging.h"
 #include "base/partition_alloc_buildflags.h"
 #include "build/build_config.h"
@@ -711,168 +710,10 @@
 namespace base {
 namespace internal {
 
-static constexpr size_t kTagOffsetForTest = 2;
-
-struct CheckedPtr2OrMTEImplPartitionAllocSupportForTest {
-  static bool EnabledForPtr(void* ptr) { return !!ptr; }
-
-  static ALWAYS_INLINE void* TagPointer(void* ptr) {
-    return static_cast<char*>(ptr) - kTagOffsetForTest;
-  }
-};
-
-using CheckedPtr2OrMTEImplForTest =
-    CheckedPtr2OrMTEImpl<CheckedPtr2OrMTEImplPartitionAllocSupportForTest>;
-
-TEST(CheckedPtr2OrMTEImpl, WrapNull) {
-  ASSERT_EQ(CheckedPtr2OrMTEImplForTest::GetWrappedNullPtr(), 0u);
-  ASSERT_EQ(CheckedPtr2OrMTEImplForTest::WrapRawPtr(nullptr), 0u);
-}
-
-TEST(CheckedPtr2OrMTEImpl, SafelyUnwrapNull) {
-  ASSERT_EQ(CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForExtraction(0),
-            nullptr);
-}
-
-TEST(CheckedPtr2OrMTEImpl, WrapAndSafelyUnwrap) {
-  // Create a fake allocation, with first 2B for generation.
-  // It is ok to use a fake allocation, instead of PartitionAlloc, because
-  // CheckedPtr2OrMTEImplForTest fakes the functionality is enabled for this
-  // pointer and points to the tag appropriately.
-  char bytes[] = {0xBA, 0x42, 0x78, 0x89};
-  void* ptr = bytes + kTagOffsetForTest;
-  ASSERT_EQ(0x78, *static_cast<char*>(ptr));
-  uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
-
-  uintptr_t mask = 0xFFFFFFFFFFFFFFFF;
-  if (sizeof(PartitionTag) < 2)
-    mask = 0x00FFFFFFFFFFFFFF;
-
-  uintptr_t wrapped = CheckedPtr2OrMTEImplForTest::WrapRawPtr(ptr);
-  // The bytes before the allocation will be used as generation (in reverse
-  // order due to little-endianness).
-#if CHECKED_PTR2_USE_NO_OP_WRAPPER
-  ASSERT_EQ(wrapped, addr);
-  std::ignore = mask;
-#else
-  ASSERT_EQ(wrapped, (addr | 0x42BA000000000000) & mask);
-#endif
-  ASSERT_EQ(CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(wrapped),
-            ptr);
-
-  // Modify the generation in the fake allocation.
-  bytes[0] |= 0x40;
-  wrapped = CheckedPtr2OrMTEImplForTest::WrapRawPtr(ptr);
-#if CHECKED_PTR2_USE_NO_OP_WRAPPER
-  ASSERT_EQ(wrapped, addr);
-#else
-  ASSERT_EQ(wrapped, (addr | 0x42FA000000000000) & mask);
-#endif
-  ASSERT_EQ(CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(wrapped),
-            ptr);
-
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING
-  // Clear the generation associated with the fake allocation.
-  bytes[0] = 0;
-  bytes[1] = 0;
-
-  // Mask out the top bit, because in some cases (not all), it may differ.
-  ASSERT_EQ(
-      reinterpret_cast<uintptr_t>(
-          CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(wrapped)),
-      wrapped);
-#endif  // CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING
-}
-
-TEST(CheckedPtr2OrMTEImpl, SafelyUnwrapDisabled) {
-  // Create a fake allocation, with first 2B for generation.
-  // It is ok to use a fake allocation, instead of PartitionAlloc, because
-  // CheckedPtr2OrMTEImplForTest fakes the functionality is enabled for this
-  // pointer and points to the tag appropriately.
-  char bytes[] = {0xBA, 0x42, 0x78, 0x89};
-  void* ptr = bytes + kTagOffsetForTest;
-  ASSERT_EQ(0x78, *static_cast<char*>(ptr));
-  uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
-  ASSERT_EQ(CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(addr),
-            ptr);
-}
-
-TEST(CheckedPtr2OrMTEImpl, CrashOnGenerationMismatch) {
-  // Create a fake allocation, with first 2B for generation.
-  // It is ok to use a fake allocation, instead of PartitionAlloc, because
-  // CheckedPtr2OrMTEImplForTest fakes the functionality is enabled for this
-  // pointer and points to the tag appropriately.
-  char bytes[] = {0xBA, 0x42, 0x78, 0x89};
-  CheckedPtr<char, CheckedPtr2OrMTEImplForTest> ptr = bytes + kTagOffsetForTest;
-  EXPECT_EQ(*ptr, 0x78);
-  // Clobber the generation associated with the fake allocation.
-  bytes[0] = 0;
-  EXPECT_DEATH_IF_SUPPORTED(if (*ptr == 0x78) return, "");
-}
-
 void HandleOOM(size_t unused_size) {
   LOG(FATAL) << "Out of memory";
 }
 
-// This test works only when PartitionAlloc is used, when tags are enabled.
-// Don't enable it when MEMORY_TOOL_REPLACES_ALLOCATOR is defined, because it
-// makes PartitionAlloc take a different path that doesn't provide tags, thus no
-// crash on UaF, thus missing the EXPECT_DEATH_IF_SUPPORTED expectation.
-#if BUILDFLAG(USE_PARTITION_ALLOC) && ENABLE_CHECKED_PTR2_OR_MTE_IMPL && \
-    !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
-
-TEST(CheckedPtr2OrMTEImpl, CrashOnUseAfterFree) {
-  // This test works only if GigaCage is enabled. Bail out otherwise.
-  if (!IsPartitionAllocGigaCageEnabled())
-    return;
-
-  // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
-  // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator<ThreadSafe> allocator;
-  allocator.init({});
-  void* raw_ptr = allocator.root()->Alloc(sizeof(int), "int");
-  // Use the actual CheckedPtr implementation, not a test substitute, to
-  // exercise real PartitionAlloc paths.
-  CheckedPtr<int> ptr = static_cast<int*>(raw_ptr);
-  *ptr = 42;
-  EXPECT_EQ(*ptr, 42);
-  allocator.root()->Free(raw_ptr);
-  EXPECT_DEATH_IF_SUPPORTED(if (*ptr == 42) return, "");
-}
-
-#ifdef ENABLE_TAG_FOR_MTE_CHECKED_PTR
-TEST(CheckedPtr2OrMTEImpl, CrashOnUseAfterFree_WithOffset) {
-  // This test works only if GigaCage is enabled. Bail out otherwise.
-  if (!IsPartitionAllocGigaCageEnabled())
-    return;
-
-  // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
-  // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator<ThreadSafe> allocator;
-  allocator.init({});
-  const uint8_t kSize = 100;
-  void* raw_ptr = allocator.root()->Alloc(kSize * sizeof(uint8_t), "uint8_t");
-  // Use the actual CheckedPtr implementation, not a test substitute, to
-  // exercise real PartitionAlloc paths.
-  CheckedPtr<uint8_t> ptrs[kSize];
-  for (uint8_t i = 0; i < kSize; ++i) {
-    ptrs[i] = static_cast<uint8_t*>(raw_ptr) + i;
-  }
-  for (uint8_t i = 0; i < kSize; ++i) {
-    *ptrs[i] = 42 + i;
-    EXPECT_TRUE(*ptrs[i] == 42 + i);
-  }
-  allocator.root()->Free(raw_ptr);
-  for (uint8_t i = 0; i < kSize; i += 15) {
-    EXPECT_DEATH_IF_SUPPORTED(if (*ptrs[i] == 42 + i) return, "");
-  }
-}
-#endif  // ENABLE_TAG_FOR_MTE_CHECKED_PTR
-#endif  // BUILDFLAG(USE_PARTITION_ALLOC) && ENABLE_CHECKED_PTR2_OR_MTE_IMPL &&
-        // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
-
 #if BUILDFLAG(USE_PARTITION_ALLOC) && ENABLE_BACKUP_REF_PTR_IMPL && \
     !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
 TEST(BackupRefPtrImpl, Basic) {
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseActivityTestRule.java b/base/test/android/javatests/src/org/chromium/base/test/BaseActivityTestRule.java
deleted file mode 100644
index af570fb..0000000
--- a/base/test/android/javatests/src/org/chromium/base/test/BaseActivityTestRule.java
+++ /dev/null
@@ -1,94 +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.
-
-package org.chromium.base.test;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.support.test.runner.lifecycle.Stage;
-import android.text.TextUtils;
-
-import androidx.annotation.NonNull;
-
-import org.junit.Assert;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.Log;
-import org.chromium.base.test.util.ApplicationTestUtils;
-
-/**
- * A replacement for ActivityTestRule, designed for use in Chromium. This implementation supports
- * launching the target activity through a launcher or redirect from another Activity.
- *
- * @param <T> The type of Activity this Rule will use.
- */
-public class BaseActivityTestRule<T extends Activity> implements TestRule {
-    private static final String TAG = "BaseActivityTestRule";
-
-    private final Class<T> mActivityClass;
-    private boolean mFinishActivity = true;
-    private T mActivity;
-
-    /**
-     * @param activityClass The Class of the Activity the TestRule will use.
-     */
-    public BaseActivityTestRule(Class<T> activityClass) {
-        mActivityClass = activityClass;
-    }
-
-    @Override
-    public Statement apply(final Statement base, final Description desc) {
-        return new Statement() {
-            @Override
-            public void evaluate() throws Throwable {
-                base.evaluate();
-                if (mFinishActivity && mActivity != null) {
-                    ApplicationTestUtils.finishActivity(mActivity);
-                }
-            }
-        };
-    }
-
-    /**
-     * @param finishActivity Whether to finish the Activity between tests. This is only meaningful
-     *     in the context of {@link Batch} tests. Non-batched tests will always finish Activities
-     *     between tests.
-     */
-    public void setFinishActivity(boolean finishActivity) {
-        mFinishActivity = finishActivity;
-    }
-
-    /**
-     * @return The activity under test.
-     */
-    public T getActivity() {
-        return mActivity;
-    }
-
-    /**
-     * Set the Activity to be used by this TestRule.
-     */
-    public void setActivity(T activity) {
-        mActivity = activity;
-    }
-
-    /**
-     * Launches the Activity under test using the provided intent.
-     */
-    public void launchActivity(@NonNull Intent startIntent) {
-        String packageName = ContextUtils.getApplicationContext().getPackageName();
-        Assert.assertTrue(TextUtils.equals(startIntent.getPackage(), packageName)
-                || TextUtils.equals(startIntent.getComponent().getPackageName(), packageName));
-
-        startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        Log.d(TAG, String.format("Launching activity %s", mActivityClass.getName()));
-
-        mActivity = ApplicationTestUtils.waitForActivityWithClass(mActivityClass, Stage.CREATED,
-                () -> ContextUtils.getApplicationContext().startActivity(startIntent));
-    }
-}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/ApplicationTestUtils.java b/base/test/android/javatests/src/org/chromium/base/test/util/ApplicationTestUtils.java
index bd174282..799c803 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/util/ApplicationTestUtils.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/util/ApplicationTestUtils.java
@@ -26,16 +26,9 @@
 
     /** Waits until the given activity transitions to the given state. */
     public static void waitForActivityState(Activity activity, Stage stage) {
-        waitForActivityState(null, activity, stage);
-    }
-
-    /** Waits until the given activity transitions to the given state. */
-    public static void waitForActivityState(String failureReason, Activity activity, Stage stage) {
-        CriteriaHelper.pollUiThread(
-                ()
-                        -> { return sMonitor.getLifecycleStageOf(activity) == stage; },
-                failureReason, ScalableTimeout.scaleTimeout(10000),
-                CriteriaHelper.DEFAULT_POLLING_INTERVAL);
+        CriteriaHelper.pollUiThread(() -> {
+            return sMonitor.getLifecycleStageOf(activity) == stage;
+        }, ScalableTimeout.scaleTimeout(10000), CriteriaHelper.DEFAULT_POLLING_INTERVAL);
     }
 
     /** Finishes the given activity and waits for its onDestroy() to be called. */
@@ -45,9 +38,7 @@
                 activity.finish();
             }
         });
-        waitForActivityState(
-                "Failed to finish the Activity. Did you start a second Activity and not finish it?",
-                activity, Stage.DESTROYED);
+        waitForActivityState(activity, Stage.DESTROYED);
     }
 
     /**
@@ -57,25 +48,11 @@
      * @return The newly created Activity.
      */
     public static <T extends Activity> T recreateActivity(T activity) {
-        return waitForActivityWithClass(
-                activity.getClass(), Stage.RESUMED, () -> activity.recreate());
-    }
-
-    /**
-     * Waits for an activity of the specified class to reach the specified Activity {@link Stage},
-     * triggered by running the provided trigger.
-     *
-     * @param activityClass The class type to wait for.
-     * @param state The Activity {@link Stage} to wait for an activity of the right class type to
-     * reach.
-     * @param trigger The Runnable that will trigger the state change to wait for.
-     */
-    public static <T extends Activity> T waitForActivityWithClass(
-            Class<? extends Activity> activityClass, Stage stage, Runnable trigger) {
+        final Class<?> activityClass = activity.getClass();
         final CallbackHelper activityCallback = new CallbackHelper();
         final AtomicReference<T> activityRef = new AtomicReference<>();
-        ActivityLifecycleCallback stateListener = (Activity newActivity, Stage newStage) -> {
-            if (newStage == stage) {
+        ActivityLifecycleCallback stateListener = (Activity newActivity, Stage stage) -> {
+            if (stage == Stage.RESUMED) {
                 if (!activityClass.isAssignableFrom(newActivity.getClass())) return;
 
                 activityRef.set((T) newActivity);
@@ -85,8 +62,8 @@
         sMonitor.addLifecycleCallback(stateListener);
 
         try {
-            ThreadUtils.runOnUiThreadBlocking(() -> trigger.run());
-            activityCallback.waitForCallback("No Activity reached target state.", 0);
+            ThreadUtils.runOnUiThreadBlocking(() -> activity.recreate());
+            activityCallback.waitForCallback("Activity did not start as expected", 0);
             T createdActivity = activityRef.get();
             Assert.assertNotNull("Activity reference is null.", createdActivity);
             return createdActivity;
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
index 8f41965..b2d0c9e 100644
--- a/base/trace_event/builtin_categories.h
+++ b/base/trace_event/builtin_categories.h
@@ -122,6 +122,7 @@
   X("paint_preview")                                                     \
   X("pepper")                                                            \
   X("PlatformMalloc")                                                    \
+  X("power")                                                             \
   X("ppapi")                                                             \
   X("ppapi proxy")                                                       \
   X("print")                                                             \
diff --git a/base/types/strong_alias.h b/base/types/strong_alias.h
index 9590a137..1d3b5539 100644
--- a/base/types/strong_alias.h
+++ b/base/types/strong_alias.h
@@ -35,11 +35,14 @@
 //
 // using Orange = StrongAlias<class OrangeTag, int>;
 // using Apple = StrongAlias<class AppleTag, int>;
+// using Banana = StrongAlias<class BananaTag, std::string>;
 // Apple apple(2);
+// Banana banana("Hello");
 // Orange orange = apple;  // Does not compile.
 // Orange other_orange = orange;  // Compiles, types match.
 // Orange x = orange + apple;  // Does not compile.
 // Orange y = Orange(orange.value() + apple.value());  // Compiles.
+// Orange z = Orange(banana->size() + *other_orange);  // Compiles.
 // if (orange > apple);  // Does not compile.
 // if (orange > other_orange);  // Compiles.
 // void foo(Orange);
@@ -59,7 +62,8 @@
 // impossible, without reflection, to expose all methods of the UnderlyingType
 // in StrongAlias's interface. It's also potentially unwanted (ex. you don't
 // want to be able to add two StrongAliases that represent socket handles).
-// A getter is provided in case you need to access the UnderlyingType.
+// A getter and dereference operators are provided in case you need to access
+// the UnderlyingType.
 //
 // See also
 // - //styleguide/c++/blink-c++.md which provides recommendation and examples of
@@ -76,6 +80,16 @@
   constexpr explicit StrongAlias(UnderlyingType&& v) noexcept
       : value_(std::move(v)) {}
 
+  constexpr UnderlyingType* operator->() { return &value_; }
+  constexpr const UnderlyingType* operator->() const { return &value_; }
+
+  constexpr UnderlyingType& operator*() & { return value_; }
+  constexpr const UnderlyingType& operator*() const& { return value_; }
+  constexpr UnderlyingType&& operator*() && { return std::move(value_); }
+  constexpr const UnderlyingType&& operator*() const&& {
+    return std::move(value_);
+  }
+
   constexpr UnderlyingType& value() & { return value_; }
   constexpr const UnderlyingType& value() const& { return value_; }
   constexpr UnderlyingType&& value() && { return std::move(value_); }
diff --git a/base/types/strong_alias_unittest.cc b/base/types/strong_alias_unittest.cc
index f8b7a4b..94f3198 100644
--- a/base/types/strong_alias_unittest.cc
+++ b/base/types/strong_alias_unittest.cc
@@ -13,6 +13,7 @@
 #include <unordered_map>
 #include <utility>
 
+#include "base/strings/string_piece.h"
 #include "base/template_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -114,6 +115,39 @@
   EXPECT_EQ(*b.value(), GetExampleValue<TypeParam>(1));
 }
 
+TYPED_TEST(StrongAliasTest, MutableOperatorArrow) {
+  // Note, using a move-only unique_ptr to T:
+  using Ptr = std::unique_ptr<TypeParam>;
+  using FooAlias = StrongAlias<class FooTag, Ptr>;
+
+  FooAlias a(std::make_unique<TypeParam>());
+  EXPECT_TRUE(a.value());
+
+  // Check that `a` can be modified through the use of operator->.
+  a->reset();
+
+  EXPECT_FALSE(a.value());
+}
+
+TYPED_TEST(StrongAliasTest, MutableOperatorStar) {
+  // Note, using a move-only unique_ptr to T:
+  using Ptr = std::unique_ptr<TypeParam>;
+  using FooAlias = StrongAlias<class FooTag, Ptr>;
+
+  FooAlias a(std::make_unique<TypeParam>());
+  FooAlias b(std::make_unique<TypeParam>());
+  EXPECT_TRUE(*a);
+  EXPECT_TRUE(*b);
+
+  // Check that both the mutable l-value and r-value overloads work and we can
+  // move out of the aliases.
+  { Ptr ignore(*std::move(a)); }
+  { Ptr ignore(std::move(*b)); }
+
+  EXPECT_FALSE(a.value());
+  EXPECT_FALSE(b.value());
+}
+
 TYPED_TEST(StrongAliasTest, MutableValue) {
   // Note, using a move-only unique_ptr to T:
   using Ptr = std::unique_ptr<TypeParam>;
@@ -296,10 +330,20 @@
 
 TEST(StrongAliasTest, EnsureConstexpr) {
   using FooAlias = StrongAlias<class FooTag, int>;
+  using BarAlias = StrongAlias<class BarTag, base::StringPiece>;
 
   // Check constructors.
   static constexpr FooAlias kZero{};
   static constexpr FooAlias kOne(1);
+  static constexpr BarAlias kHello("Hello");
+
+  // Check operator->.
+  static_assert(kHello->size() == 5, "");
+
+  // Check operator*.
+  static_assert(*kZero == 0, "");
+  static_assert(*kOne == 1, "");
+  static_assert(*kHello == "Hello", "");
 
   // Check value().
   static_assert(kZero.value() == 0, "");
diff --git a/build/apple/tweak_info_plist.py b/build/apple/tweak_info_plist.py
index 8bbc46a..69e0d6f7 100755
--- a/build/apple/tweak_info_plist.py
+++ b/build/apple/tweak_info_plist.py
@@ -278,7 +278,7 @@
       'like key=value (can be passed multiple time to configure '
       'more than one override)')
   parser.add_option('--format',
-                    choices=('binary1', 'xml1', 'json'),
+                    choices=('binary1', 'xml1'),
                     default='xml1',
                     help='Format to use when writing property list '
                     '(default: %(default)s)')
diff --git a/build/config/mac/plist_util.py b/build/config/mac/plist_util.py
index cf9b449a..2d61b98 100644
--- a/build/config/mac/plist_util.py
+++ b/build/config/mac/plist_util.py
@@ -178,7 +178,7 @@
         '-o', '--output', required=True,
         help='path to the output plist file')
     parser.add_argument(
-        '-f', '--format', required=True, choices=('xml1', 'binary1', 'json'),
+        '-f', '--format', required=True, choices=('xml1', 'binary1'),
         help='format of the plist file to generate')
     parser.add_argument(
         '-x',
@@ -214,7 +214,7 @@
         '-s', '--substitution', action='append', default=[],
         help='substitution rule in the format key=value')
     parser.add_argument(
-        '-f', '--format', required=True, choices=('xml1', 'binary1', 'json'),
+        '-f', '--format', required=True, choices=('xml1', 'binary1'),
         help='format of the plist file to generate')
     parser.add_argument(
         '-x',
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index e6083fd..064a743 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-0.20201123.2.1
+0.20201124.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index e6083fd..63e9cc5 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-0.20201123.2.1
+0.20201123.3.1
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index a2e134a..771d0c6 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -332,6 +332,7 @@
     "//chrome/browser/share:java",
     "//chrome/browser/share/android:java_resources",
     "//chrome/browser/signin/android:java",
+    "//chrome/browser/signin/services/android:java",
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:factory_java",
     "//chrome/browser/tabmodel:java",
@@ -824,6 +825,7 @@
     "//chrome/browser/safety_check/android:java",
     "//chrome/browser/safety_check/android:junit",
     "//chrome/browser/share:java",
+    "//chrome/browser/signin/services/android:java",
     "//chrome/browser/signin/services/android:junit",
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:factory_java",
@@ -1058,6 +1060,7 @@
     "//chrome/browser/settings:test_support_java",
     "//chrome/browser/share:java",
     "//chrome/browser/share/android:java_resources",
+    "//chrome/browser/signin/services/android:java",
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:java",
     "//chrome/browser/tabmodel/internal:java",
diff --git a/chrome/android/DEPS b/chrome/android/DEPS
index 6c074d5..8f93aaa 100644
--- a/chrome/android/DEPS
+++ b/chrome/android/DEPS
@@ -19,6 +19,7 @@
   "+chrome/browser/preferences/android/java",
   "+chrome/browser/safe_browsing/android",
   "+chrome/browser/safety_check/android",
+  "+chrome/browser/signin/services/android/java",
   "+chrome/browser/settings/android",
   "+chrome/browser/ui/android/favicon/java",
   "+chrome/browser/ui/android/native_page",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 76102e5..c74c20c 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -1274,7 +1274,6 @@
   "java/src/org/chromium/chrome/browser/signin/SigninHelper.java",
   "java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java",
   "java/src/org/chromium/chrome/browser/signin/SigninManager.java",
-  "java/src/org/chromium/chrome/browser/signin/SigninPreferencesManager.java",
   "java/src/org/chromium/chrome/browser/signin/SigninPromoController.java",
   "java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java",
   "java/src/org/chromium/chrome/browser/signin/SigninScrollView.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinatorTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinatorTest.java
index 2717c72..80b4009 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinatorTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinatorTest.java
@@ -23,9 +23,10 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.verify;
 
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntil;
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition;
 
-import android.support.test.runner.lifecycle.Stage;
+import android.app.Activity;
 import android.text.Spanned;
 import android.text.style.ClickableSpan;
 import android.view.View;
@@ -42,10 +43,10 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import org.chromium.base.ActivityState;
+import org.chromium.base.ApplicationStatus;
 import org.chromium.base.Callback;
-import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.chrome.autofill_assistant.R;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayCoordinator;
@@ -56,6 +57,7 @@
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -293,11 +295,8 @@
                                     spannedMessage.getSpanEnd(spans[0]))
                             .toString());
         });
-        CustomTabActivity activity = ApplicationTestUtils.waitForActivityWithClass(
-                CustomTabActivity.class, Stage.RESUMED, () -> spans[0].onClick(termsMessage));
-        CriteriaHelper.pollUiThread(
-                () -> activity.getActivityTab().getUrlString().equals(expectedTermsUrl));
-        activity.finish();
+        spans[0].onClick(termsMessage);
+        waitUntil(() -> getOpenedUrlSpec().equals(expectedTermsUrl));
     }
 
     @Test
@@ -357,13 +356,12 @@
                             .toString()
                             .replaceAll("\\s+", " "));
         });
-        CustomTabActivity activity = ApplicationTestUtils.waitForActivityWithClass(
-                CustomTabActivity.class, Stage.RESUMED, () -> spans[0].onClick(termsMessage));
-        String url = mActivity.getResources()
-                             .getText(R.string.autofill_assistant_google_terms_url)
-                             .toString();
-        CriteriaHelper.pollUiThread(() -> activity.getActivityTab().getUrlString().equals(url));
-        activity.finish();
+        spans[0].onClick(termsMessage);
+        waitUntil(()
+                          -> getOpenedUrlSpec().equals(
+                                  mActivity.getResources()
+                                          .getText(R.string.autofill_assistant_google_terms_url)
+                                          .toString()));
     }
 
     /** Trigger onboarding and wait until it is fully displayed. */
@@ -372,4 +370,21 @@
         TestThreadUtils.runOnUiThreadBlocking(() -> coordinator.show(callback));
         waitUntilViewMatchesCondition(withId(R.id.button_init_ok), isCompletelyDisplayed());
     }
+
+    // Get the newly opened Activity (through CustomTabActivity.showInfoPage) that happens on
+    // terms click. Return the URL of the current tab on that activity.
+    private String getOpenedUrlSpec() {
+        for (Activity runningActivity : ApplicationStatus.getRunningActivities()) {
+            if (runningActivity instanceof CustomTabActivity
+                    && ApplicationStatus.getStateForActivity(runningActivity)
+                            == ActivityState.RESUMED) {
+                return ChromeTabUtils
+                        .getUrlOnUiThread(((CustomTabActivity) runningActivity)
+                                                  .getTabModelSelector()
+                                                  .getCurrentTab())
+                        .getSpec();
+            }
+        }
+        return "";
+    }
 }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
index a3ae2c4..51b95d2 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -65,7 +65,6 @@
 import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
-import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.compositor.layouts.Layout;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone;
@@ -173,7 +172,7 @@
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(Intent.CATEGORY_LAUNCHER);
         mActivityTestRule.prepareUrlIntent(intent, null);
-        mActivityTestRule.launchActivity(intent);
+        mActivityTestRule.startActivityCompletely(intent);
     }
 
     public static Bitmap createThumbnailBitmapAndWriteToFile(int tabId) {
@@ -272,8 +271,7 @@
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> mActivityTestRule.getActivity().startDelayedNativeInitializationForTests());
         CriteriaHelper.pollUiThread(
-                mActivityTestRule.getActivity().getTabModelSelector()::isTabStateInitialized,
-                ScalableTimeout.scaleTimeout(10000L), CriteriaHelper.DEFAULT_POLLING_INTERVAL);
+                mActivityTestRule.getActivity().getTabModelSelector()::isTabStateInitialized);
         Assert.assertTrue(LibraryLoader.getInstance().isInitialized());
     }
 
@@ -570,7 +568,6 @@
             RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(i);
             if (viewHolder != null) {
                 ImageView thumbnail = viewHolder.itemView.findViewById(R.id.tab_thumbnail);
-                if (!(thumbnail.getDrawable() instanceof BitmapDrawable)) return false;
                 BitmapDrawable drawable = (BitmapDrawable) thumbnail.getDrawable();
                 Bitmap bitmap = drawable.getBitmap();
                 if (bitmap == null) return false;
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java
index 260b84d6..19a30c7 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java
@@ -91,7 +91,7 @@
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(Intent.CATEGORY_LAUNCHER);
         mActivityTestRule.prepareUrlIntent(intent, null);
-        mActivityTestRule.launchActivity(intent);
+        mActivityTestRule.startActivityCompletely(intent);
     }
 
     @Before
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
index 91f7d94..863eac0 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -812,7 +812,7 @@
     @CommandLineFlags.Add({BASE_PARAMS + "/single/exclude_mv_tiles/true"
             + "/show_last_active_tab_only/true/show_stack_tab_switcher/true"})
     public void
-    testShow_SingleAsHomepageV2_FromResumeShowStart() throws Exception {
+    testShow_SingleAsHomepageV2_FromResumeShowStart() throws ExecutionException {
         // clang-format on
         if (!mImmediateReturn) return;
 
@@ -832,7 +832,7 @@
         pressHome();
 
         // Simulates pressing Chrome's icon and launching Chrome from warm start.
-        mActivityTestRule.resumeMainActivityFromLauncher();
+        startMainActivityFromLauncher();
 
         CriteriaHelper.pollUiThread(
                 () -> cta.getLayoutManager() != null && cta.getLayoutManager().overviewVisible());
diff --git a/chrome/android/java/res/layout/account_picker_state_collapsed.xml b/chrome/android/java/res/layout/account_picker_state_collapsed.xml
index ceb1b8e..2c8da944 100644
--- a/chrome/android/java/res/layout/account_picker_state_collapsed.xml
+++ b/chrome/android/java/res/layout/account_picker_state_collapsed.xml
@@ -31,6 +31,6 @@
         android:layout_height="wrap_content"
         android:layout_marginStart="24dp"
         android:layout_marginEnd="24dp"
-        android:text="@string/no_thanks" />
+        android:text="@string/signin_account_picker_dismiss_button" />
 
 </LinearLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 07ee1f46..78f1c3a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -305,6 +305,7 @@
             new ObservableSupplierImpl<>();
 
     private CallbackController mCallbackController = new CallbackController();
+    private TabbedModeTabDelegateFactory mTabDelegateFactory;
 
     private final IncognitoTabHost mIncognitoTabHost = new IncognitoTabHost() {
         @Override
@@ -1651,15 +1652,19 @@
                 mBookmarkBridgeSupplier, getModalDialogManager());
     }
 
-    @Override
-    protected Pair<ChromeTabCreator, ChromeTabCreator> createTabCreators() {
-        Supplier<TabDelegateFactory> tabDelegateFactorySupplier = () -> {
-            return new TabbedModeTabDelegateFactory(this, getAppBrowserControlsVisibilityDelegate(),
-                    getShareDelegateSupplier(), mEphemeralTabCoordinatorSupplier,
+    private TabDelegateFactory getTabDelegateFactory() {
+        if (mTabDelegateFactory == null) {
+            mTabDelegateFactory = new TabbedModeTabDelegateFactory(this,
+                    getAppBrowserControlsVisibilityDelegate(), getShareDelegateSupplier(),
+                    mEphemeralTabCoordinatorSupplier,
                     ((TabbedRootUiCoordinator) mRootUiCoordinator)::onContextMenuCopyLink,
                     mRootUiCoordinator.getBottomSheetController());
-        };
+        }
+        return mTabDelegateFactory;
+    }
 
+    @Override
+    protected Pair<ChromeTabCreator, ChromeTabCreator> createTabCreators() {
         ChromeTabCreator.OverviewNTPCreator overviewNTPCreator = null;
 
         if (StartSurfaceConfiguration.isStartSurfaceEnabled()) {
@@ -1676,10 +1681,10 @@
             };
         }
         return Pair.create(new ChromeTabCreator(this, getWindowAndroid(), getStartupTabPreloader(),
-                                   tabDelegateFactorySupplier, false, overviewNTPCreator,
+                                   this::getTabDelegateFactory, false, overviewNTPCreator,
                                    AsyncTabParamsManagerSingleton.getInstance()),
                 new ChromeTabCreator(this, getWindowAndroid(), getStartupTabPreloader(),
-                        tabDelegateFactorySupplier, true, overviewNTPCreator,
+                        this::getTabDelegateFactory, true, overviewNTPCreator,
                         AsyncTabParamsManagerSingleton.getInstance()));
     }
 
@@ -2158,6 +2163,7 @@
         ChromeAccessibilityUtil.get().removeObserver(this);
         ChromeAccessibilityUtil.get().removeObserver(mLayoutManager);
 
+        if (mTabDelegateFactory != null) mTabDelegateFactory.destroy();
         super.onDestroyInternal();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java
index ebbe03f..37b4a96 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java
@@ -85,4 +85,9 @@
         }
         return mNativePageFactory.createNativePage(url, candidatePage, tab);
     }
+
+    /** Destroy and unhook objects at destruction. */
+    public void destroy() {
+        if (mNativePageFactory != null) mNativePageFactory.destroy();
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
index b966d80e..5ab3865 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -52,7 +52,7 @@
 import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
 import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator;
 import org.chromium.components.external_intents.ExternalNavigationHandler;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.components.external_intents.ExternalNavigationParams;
 import org.chromium.components.external_intents.RedirectHandler;
 import org.chromium.components.navigation_interception.NavigationParams;
@@ -1098,7 +1098,7 @@
                             .setIsMainFrame(navigationParams.isMainFrame)
                             .build();
             if (externalNavHandler.shouldOverrideUrlLoading(params)
-                    != OverrideUrlLoadingResult.NO_OVERRIDE) {
+                    != OverrideUrlLoadingResultType.NO_OVERRIDE) {
                 return false;
             }
             return !navigationParams.isExternalProtocol;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java
index ba609cd7..01441c0e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java
@@ -35,7 +35,7 @@
 import org.chromium.components.external_intents.ExternalNavigationDelegate;
 import org.chromium.components.external_intents.ExternalNavigationDelegate.StartActivityIfNeededResult;
 import org.chromium.components.external_intents.ExternalNavigationHandler;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.components.external_intents.ExternalNavigationParams;
 import org.chromium.components.external_intents.RedirectHandler;
 import org.chromium.content_public.browser.LoadUrlParams;
@@ -149,13 +149,14 @@
     }
 
     @Override
-    public @OverrideUrlLoadingResult int handleIncognitoIntentTargetingSelf(
+    public @OverrideUrlLoadingResultType int handleIncognitoIntentTargetingSelf(
             final Intent intent, final String referrerUrl, final String fallbackUrl) {
         String primaryUrl = intent.getDataString();
         boolean isUrlLoadedInTheSameTab = ExternalNavigationHandler.loadUrlFromIntent(
                 referrerUrl, primaryUrl, fallbackUrl, this, false, true);
-        return (isUrlLoadedInTheSameTab) ? OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB
-                                         : OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+        return (isUrlLoadedInTheSameTab)
+                ? OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB
+                : OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
index 9ca5c483..93f8af1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
@@ -229,4 +229,9 @@
             return new BrowserControlsMarginSupplier(mBrowserControlsStateProvider);
         }
     }
+
+    /** Destroy and unhook objects at destruction. */
+    public void destroy() {
+        if (mNewTabPageUma != null) mNewTabPageUma.destroy();
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
index be575e0..3b203bb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
@@ -156,6 +156,7 @@
     private final Supplier<Long> mLastInteractionTime;
     private final boolean mActivityHadWarmStart;
     private final Supplier<Intent> mActivityIntent;
+    private TabCreationRecorder mTabCreationRecorder;
 
     /**
      * Constructor.
@@ -216,7 +217,8 @@
      * users navigate back to already opened NTPs.
      */
     public void monitorNTPCreation() {
-        mTabModelSelector.addObserver(new TabCreationRecorder());
+        mTabCreationRecorder = new TabCreationRecorder();
+        mTabModelSelector.addObserver(mTabCreationRecorder);
     }
 
     /**
@@ -321,4 +323,9 @@
             }
         });
     }
+
+    /** Destroy and unhook objects at destruction. */
+    public void destroy() {
+        if (mTabCreationRecorder != null) mTabModelSelector.removeObserver(mTabCreationRecorder);
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
index e8d0a51..097dac1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
@@ -21,8 +21,8 @@
 import org.chromium.chrome.browser.signin.SigninManager;
 import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver;
 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
-import org.chromium.chrome.browser.signin.SigninPreferencesManager;
 import org.chromium.chrome.browser.signin.SigninPromoController;
+import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
 import org.chromium.components.signin.AccountsChangeObserver;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java
index a750de0..3985c87e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java
@@ -17,7 +17,7 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.SigninHelper;
-import org.chromium.chrome.browser.signin.SigninPreferencesManager;
+import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.components.signin.AccountTrackerService;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java
index fe87ec7..2cb164a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java
@@ -65,12 +65,12 @@
         private static PendingProfileDownloads sPendingProfileDownloads;
 
         private final ArrayList<Profile> mProfiles;
-        private final ArrayList<String> mAccountIds;
+        private final ArrayList<String> mAccountEmails;
         private final ArrayList<Integer> mImageSidePixels;
 
         private PendingProfileDownloads() {
             mProfiles = new ArrayList<>();
-            mAccountIds = new ArrayList<>();
+            mAccountEmails = new ArrayList<>();
             mImageSidePixels = new ArrayList<>();
         }
 
@@ -85,22 +85,22 @@
             return sPendingProfileDownloads;
         }
 
-        public void pendProfileDownload(Profile profile, String accountId, int imageSidePixels) {
+        public void pendProfileDownload(Profile profile, String accountEmail, int imageSidePixels) {
             mProfiles.add(profile);
-            mAccountIds.add(accountId);
+            mAccountEmails.add(accountEmail);
             mImageSidePixels.add(imageSidePixels);
         }
 
         @Override
         public void onSystemAccountsSeedingComplete() {
-            int numberOfPendingRequests = mAccountIds.size();
+            int numberOfPendingRequests = mAccountEmails.size();
             while (numberOfPendingRequests > 0) {
                 // Pending requests here must be pre-signin request since SigninManager will wait
                 // system accounts been seeded into AccountTrackerService before finishing sign in.
                 ProfileDownloaderJni.get().startFetchingAccountInfoFor(
-                        mProfiles.get(0), mAccountIds.get(0), mImageSidePixels.get(0), true);
+                        mProfiles.get(0), mAccountEmails.get(0), mImageSidePixels.get(0), true);
                 mProfiles.remove(0);
-                mAccountIds.remove(0);
+                mAccountEmails.remove(0);
                 mImageSidePixels.remove(0);
                 numberOfPendingRequests--;
             }
@@ -109,7 +109,7 @@
         @Override
         public void onSystemAccountsChanged() {
             mProfiles.clear();
-            mAccountIds.clear();
+            mAccountEmails.clear();
             mImageSidePixels.clear();
         }
     }
@@ -117,30 +117,30 @@
     /**
      * Starts fetching the account information for a given account.
      * @param context context associated with the request
-     * @param accountId Account name to fetch the information for
+     * @param accountEmail Account email to fetch the information for
      * @param imageSidePixels Request image side (in pixels)
      */
     public static void startFetchingAccountInfoFor(
-            Context context, String accountId, int imageSidePixels, boolean isPreSignin) {
+            Context context, String accountEmail, int imageSidePixels, boolean isPreSignin) {
         ThreadUtils.assertOnUiThread();
         Profile profile = Profile.getLastUsedRegularProfile();
         if (!IdentityServicesProvider.get()
                         .getAccountTrackerService(profile)
                         .checkAndSeedSystemAccounts()) {
             PendingProfileDownloads.get(context).pendProfileDownload(
-                    profile, accountId, imageSidePixels);
+                    profile, accountEmail, imageSidePixels);
             return;
         }
         ProfileDownloaderJni.get().startFetchingAccountInfoFor(
-                profile, accountId, imageSidePixels, isPreSignin);
+                profile, accountEmail, imageSidePixels, isPreSignin);
     }
 
     @CalledByNative
     private static void onProfileDownloadSuccess(
-            String accountId, String fullName, String givenName, Bitmap bitmap) {
+            String accountEmail, String fullName, String givenName, Bitmap bitmap) {
         ThreadUtils.assertOnUiThread();
         for (Observer observer : sObservers) {
-            observer.onProfileDownloaded(accountId, fullName, givenName, bitmap);
+            observer.onProfileDownloaded(accountEmail, fullName, givenName, bitmap);
         }
     }
 
@@ -171,7 +171,7 @@
     @NativeMethods
     interface Natives {
         void startFetchingAccountInfoFor(
-                Profile profile, String accountId, int imageSidePixels, boolean isPreSignin);
+                Profile profile, String accountEmail, int imageSidePixels, boolean isPreSignin);
         String getCachedFullNameForPrimaryAccount(Profile profile);
         String getCachedGivenNameForPrimaryAccount(Profile profile);
         Bitmap getCachedAvatarForPrimaryAccount(Profile profile);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
index 1564ffb..6d9a2a4a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -22,6 +22,7 @@
 import org.chromium.base.task.AsyncTask;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.SigninManager.SignInCallback;
+import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.chrome.browser.sync.SyncController;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
 import org.chromium.components.signin.AccountTrackerService;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
index 5c5d43447..fb636e4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -24,6 +24,7 @@
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.chrome.browser.sync.AndroidSyncSettings;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.components.signin.AccountTrackerService;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPreferencesManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPreferencesManager.java
deleted file mode 100644
index 90b711b..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPreferencesManager.java
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2019 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.
-
-package org.chromium.chrome.browser.signin;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-
-import java.util.Set;
-
-/**
- * SigninPreferencesManager stores the state of SharedPreferences related to account sign-in.
- *
- * Please use SigninPreferencesManager in org.chromium.chrome.browser.signin.services,
- * the current class will be removed after migration of this class in clank.
- */
-@Deprecated
-public class SigninPreferencesManager {
-    private static final SigninPreferencesManager INSTANCE = new SigninPreferencesManager();
-
-    private final SharedPreferencesManager mManager;
-
-    private SigninPreferencesManager() {
-        mManager = SharedPreferencesManager.getInstance();
-    }
-
-    /**
-     * @return the SignInPromoStore singleton
-     */
-    public static SigninPreferencesManager getInstance() {
-        return INSTANCE;
-    }
-
-    /**
-     * Sets the {@link ChromePreferenceKeys#SIGNIN_ACCOUNTS_CHANGED} to true.
-     */
-    public void markAccountsChangedPref() {
-        // The process may go away as soon as we return from onReceive but Android makes sure
-        // that in-flight disk writes from apply() complete before changing component states.
-        mManager.writeBoolean(ChromePreferenceKeys.SIGNIN_ACCOUNTS_CHANGED, true);
-    }
-
-    /**
-     * @return The new account name of the current user. Null if it wasn't renamed.
-     */
-    String getNewSignedInAccountName() {
-        return mManager.readString(ChromePreferenceKeys.SIGNIN_ACCOUNT_RENAMED, null);
-    }
-
-    /**
-     * Sets the new account name of the current user.
-     *
-     * @param newName the new name to write
-     */
-    void setNewSignedInAccountName(@Nullable String newName) {
-        mManager.writeString(ChromePreferenceKeys.SIGNIN_ACCOUNT_RENAMED, newName);
-    }
-
-    /**
-     * Clears the new account name of the current user.
-     */
-    void clearNewSignedInAccountName() {
-        setNewSignedInAccountName(null);
-    }
-
-    /**
-     * Sets the last read index of all the account changed events of the current signed in account.
-     *
-     * @param newIndex the new index to write
-     */
-    void setLastAccountChangedEventIndex(int newIndex) {
-        mManager.writeInt(ChromePreferenceKeys.SIGNIN_ACCOUNT_RENAME_EVENT_INDEX, newIndex);
-    }
-
-    /**
-     * @return the last read index of all the account changed events of the current signed in
-     *         account.
-     */
-    int getLastAccountChangedEventIndex() {
-        return mManager.readInt(ChromePreferenceKeys.SIGNIN_ACCOUNT_RENAME_EVENT_INDEX);
-    }
-
-    /**
-     * Gets the state of {@link ChromePreferenceKeys#SIGNIN_ACCOUNTS_CHANGED} and clears it.
-     *
-     * @return the state of {@link ChromePreferenceKeys#SIGNIN_ACCOUNTS_CHANGED} before the call.
-     */
-    public boolean checkAndClearAccountsChangedPref() {
-        if (mManager.readBoolean(ChromePreferenceKeys.SIGNIN_ACCOUNTS_CHANGED, false)) {
-            // Clear the value in prefs.
-            mManager.writeBoolean(ChromePreferenceKeys.SIGNIN_ACCOUNTS_CHANGED, false);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Clears the accounts state-related shared prefs.
-     */
-    @VisibleForTesting
-    public void clearAccountsStateSharedPrefsForTesting() {
-        mManager.removeKey(ChromePreferenceKeys.SIGNIN_ACCOUNT_RENAME_EVENT_INDEX);
-        mManager.removeKey(ChromePreferenceKeys.SIGNIN_ACCOUNT_RENAMED);
-        mManager.removeKey(ChromePreferenceKeys.SIGNIN_ACCOUNTS_CHANGED);
-    }
-
-    /**
-     * Returns Chrome major version number when signin promo was last shown, or 0 if version number
-     * isn't known.
-     */
-    int getSigninPromoLastShownVersion() {
-        return mManager.readInt(ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION);
-    }
-
-    /**
-     * Sets Chrome major version number when signin promo was last shown.
-     */
-    void setSigninPromoLastShownVersion(int majorVersion) {
-        mManager.writeInt(ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION, majorVersion);
-    }
-
-    /**
-     * Returns a set of account names on the device when signin promo was last shown,
-     * or null if promo hasn't been shown yet.
-     */
-    @Nullable
-    Set<String> getSigninPromoLastAccountNames() {
-        return mManager.readStringSet(
-                ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, null);
-    }
-
-    /**
-     * Stores a set of account names on the device when signin promo is shown.
-     */
-    void setSigninPromoLastAccountNames(Set<String> accountNames) {
-        mManager.writeStringSet(
-                ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, accountNames);
-    }
-
-    /**
-     * Returns timestamp of the suppression period start if signin promos in the New Tab Page are
-     * temporarily suppressed; zero otherwise.
-     * @return the epoch time in milliseconds (see {@link System#currentTimeMillis()}).
-     */
-    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-    public long getNewTabPageSigninPromoSuppressionPeriodStart() {
-        return mManager.readLong(
-                ChromePreferenceKeys.SIGNIN_PROMO_NTP_PROMO_SUPPRESSION_PERIOD_START);
-    }
-
-    /**
-     * Sets timestamp of the suppression period start if signin promos in the New Tab Page are
-     * temporarily suppressed.
-     * @param timeMillis the epoch time in milliseconds (see {@link System#currentTimeMillis()}).
-     */
-    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-    public void setNewTabPageSigninPromoSuppressionPeriodStart(long timeMillis) {
-        mManager.writeLong(
-                ChromePreferenceKeys.SIGNIN_PROMO_NTP_PROMO_SUPPRESSION_PERIOD_START, timeMillis);
-    }
-
-    /**
-     * Removes the stored timestamp of the suppression period start when signin promos in the New
-     * Tab Page are no longer suppressed.
-     */
-    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-    public void clearNewTabPageSigninPromoSuppressionPeriodStart() {
-        mManager.removeKey(ChromePreferenceKeys.SIGNIN_PROMO_NTP_PROMO_SUPPRESSION_PERIOD_START);
-    }
-
-    /**
-     * Sets the email of the account for which sync was enabled.
-     *
-     * @param accountEmail The email of the sync account or null if sync isn't enabled.
-     */
-    // TODO(https://crbug.com/1091858): Remove this after migrating the legacy code that uses
-    //                                  the sync account before the native is loaded.
-    public void setLegacySyncAccountEmail(@Nullable String accountEmail) {
-        mManager.writeString(ChromePreferenceKeys.SIGNIN_LEGACY_SYNC_ACCOUNT_EMAIL, accountEmail);
-    }
-
-    /**
-     * The email of the account for which sync was enabled.
-     */
-    // TODO(https://crbug.com/1091858): Remove this after migrating the legacy code that uses
-    //                                  the sync account before the native is loaded.
-    public String getLegacySyncAccountEmail() {
-        return mManager.readString(ChromePreferenceKeys.SIGNIN_LEGACY_SYNC_ACCOUNT_EMAIL, null);
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
index 348fe787..657ed1c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
@@ -16,6 +16,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.chrome.browser.version.ChromeVersionInfo;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
 import org.chromium.components.signin.AccountUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
index 55cc509..2d53db6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
@@ -130,10 +130,10 @@
 
     @Override
     public boolean hasTab() {
-        // TODO(https://crbug.com/1147131): Remove the isInitialized() and isDestroyed checks when
-        // we no longer wait for TAB_CLOSED events to remove this tab.  Otherwise there is a chance
-        // we use this tab after {@link Tab#destroy()} is called.
-        return mTab != null && mTab.isInitialized() && !mTab.isDestroyed();
+        // TODO(dtrainor, tedchoc): Remove the isInitialized() check when we no longer wait for
+        // TAB_CLOSED events to remove this tab.  Otherwise there is a chance we use this tab after
+        // {@link ChromeTab#destroy()} is called.
+        return mTab != null && mTab.isInitialized();
     }
 
     @Override
diff --git a/chrome/android/javatests/DEPS b/chrome/android/javatests/DEPS
index 3cf021b..aa47f670 100644
--- a/chrome/android/javatests/DEPS
+++ b/chrome/android/javatests/DEPS
@@ -15,6 +15,7 @@
   "+chrome/browser/ui/android/appmenu",
   "-chrome/browser/ui/android/appmenu/internal",
   "+chrome/browser/ui/messages/android/java",
+  "+chrome/browser/signin/services/android/java",
   "+components/autofill/android/java/src/org/chromium/components/autofill",
   "+components/background_task_scheduler/android/java",
   "+components/bookmarks/common/android/java/src/org/chromium/components/bookmarks",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/CopylessPasteTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/CopylessPasteTest.java
index d2e0260..279eb8d3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/CopylessPasteTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/CopylessPasteTest.java
@@ -15,6 +15,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
@@ -71,6 +72,7 @@
     @After
     public void tearDown() throws Exception {
         AppIndexingUtil.setCallbackForTesting(null);
+        ApplicationTestUtils.finishActivity(mActivityTestRule.getActivity());
     }
 
     private static class CopylessHelper extends CallbackHelper {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java
index 723653c..cee2800 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java
@@ -8,11 +8,13 @@
 
 import androidx.test.filters.SmallTest;
 
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
@@ -34,6 +36,11 @@
     @Rule
     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
 
+    @After
+    public void tearDown() throws Exception {
+        ApplicationTestUtils.finishActivity(mActivityTestRule.getActivity());
+    }
+
     /**
      * Verify launch the activity with URL.
      */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java
index 8640a48..2d586b71 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java
@@ -11,11 +11,8 @@
 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 
-import static org.hamcrest.CoreMatchers.allOf;
 import static org.junit.Assert.assertEquals;
 
-import static org.chromium.chrome.test.util.ViewUtils.onViewWaiting;
-
 import android.support.test.InstrumentationRegistry;
 
 import androidx.test.filters.MediumTest;
@@ -84,7 +81,7 @@
     @MediumTest
     public void testPromoNotShownAfterBeingDismissed() {
         mBookmarkTestRule.showBookmarkManager(mSyncTestRule.getActivity());
-        onViewWaiting(allOf(withId(R.id.signin_promo_view_container), isDisplayed()));
+        onView(withId(R.id.signin_promo_view_container)).check(matches(isDisplayed()));
         onView(withId(R.id.signin_promo_close_button)).perform(click());
         onView(withId(R.id.signin_promo_view_container)).check(doesNotExist());
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
index 733c40d..645fad0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
@@ -204,9 +204,8 @@
     }
 
     @After
-    public void tearDown() throws Exception {
+    public void tearDown() {
         if (mTestServer != null) mTestServer.stopAndDestroyServer();
-        if (mBookmarkActivity != null) ApplicationTestUtils.finishActivity(mBookmarkActivity);
     }
 
     @AfterClass
@@ -284,7 +283,7 @@
         // Click the star button again to launch the edit activity.
         MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
                 mActivityTestRule.getActivity(), R.id.bookmark_this_page_id);
-        waitForEditActivity().finish();
+        waitForEditActivity();
     }
 
     @Test
@@ -315,9 +314,8 @@
             currentSnackbar.getController().onAction(null);
         });
 
-        BookmarkEditActivity activity = waitForEditActivity();
+        waitForEditActivity();
         SnackbarManager.setDurationForTesting(0);
-        activity.finish();
     }
 
     @Test
@@ -1733,13 +1731,12 @@
         RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer);
     }
 
-    private BookmarkEditActivity waitForEditActivity() {
+    private void waitForEditActivity() {
         CriteriaHelper.pollUiThread(() -> {
             Criteria.checkThat(ApplicationStatus.getLastTrackedFocusedActivity(),
                     IsInstanceOf.instanceOf(BookmarkEditActivity.class));
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-        return (BookmarkEditActivity) ApplicationStatus.getLastTrackedFocusedActivity();
     }
 
     private ChromeTabbedActivity waitForTabbedActivity() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java
index c6d9b533..6fc157e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java
@@ -17,7 +17,6 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
@@ -45,18 +44,14 @@
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 public class ClearBrowsingDataFragmentBasicTest {
+    @Rule
     public final ChromeTabbedActivityTestRule mActivityTestRule =
             new ChromeTabbedActivityTestRule();
+    @Rule
     public final SettingsActivityTestRule<ClearBrowsingDataFragmentBasic>
             mSettingsActivityTestRule =
                     new SettingsActivityTestRule<>(ClearBrowsingDataFragmentBasic.class);
 
-    // SettingsActivity has to be finished before the outer CTA can be finished or trying to finish
-    // CTA won't work.
-    @Rule
-    public final RuleChain mRuleChain =
-            RuleChain.outerRule(mActivityTestRule).around(mSettingsActivityTestRule);
-
     @Rule
     public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule();
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
index 96b2323a..8101eec 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -707,7 +707,7 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
         filter.addDataScheme(Uri.parse(mTestServer.getURL("/")).getScheme());
         final ActivityMonitor monitor =
-                InstrumentationRegistry.getInstrumentation().addMonitor(filter, null, true);
+                InstrumentationRegistry.getInstrumentation().addMonitor(filter, null, false);
         openAppMenuAndAssertMenuShown();
         PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> {
             MenuItem item =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestRule.java
index e832ecf..ff48c21 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestRule.java
@@ -4,20 +4,29 @@
 
 package org.chromium.chrome.browser.customtabs;
 
+import android.app.Activity;
 import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
 
-import androidx.annotation.NonNull;
-
+import org.hamcrest.Matchers;
 import org.junit.Assert;
 
+import org.chromium.base.ApplicationStatus;
 import org.chromium.base.FeatureList;
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.Criteria;
+import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.ScalableTimeout;
+import org.chromium.chrome.browser.DeferredStartupHandler;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabTestUtils;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 
 import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Custom ActivityTestRule for all instrumentation tests that require a {@link CustomTabActivity}.
@@ -45,13 +54,29 @@
     }
 
     @Override
-    public void launchActivity(@NonNull Intent intent) {
+    public void startActivityCompletely(Intent intent) {
         if (!FeatureList.hasTestFeatures()) {
             FeatureList.setTestFeatures(
                     Collections.singletonMap(ChromeFeatureList.SHARE_BY_DEFAULT_IN_CCT, true));
         }
         putCustomTabIdInIntent(intent);
-        super.launchActivity(intent);
+        int currentIntentId = getCustomTabIdFromIntent(intent);
+
+        Activity activity = InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
+        Assert.assertNotNull("Main activity did not start", activity);
+        CriteriaHelper.pollUiThread(() -> {
+            for (Activity runningActivity : ApplicationStatus.getRunningActivities()) {
+                if (runningActivity instanceof CustomTabActivity) {
+                    CustomTabActivity customTabActivity = (CustomTabActivity) runningActivity;
+                    final int customTabIdInActivity =
+                            getCustomTabIdFromIntent(customTabActivity.getIntent());
+                    if (currentIntentId != customTabIdInActivity) continue;
+                    setActivity(customTabActivity);
+                    return true;
+                }
+            }
+            return false;
+        });
     }
 
     /**
@@ -59,8 +84,33 @@
      * initialized.
      */
     public void startCustomTabActivityWithIntent(Intent intent) {
+        DeferredStartupHandler.setExpectingActivityStartupForTesting();
         startActivityCompletely(intent);
+        waitForActivityNativeInitializationComplete();
+        CriteriaHelper.pollUiThread(() -> {
+            Criteria.checkThat(getActivity().getActivityTab(), Matchers.notNullValue());
+        });
         final Tab tab = getActivity().getActivityTab();
+        final CallbackHelper pageLoadFinishedHelper = new CallbackHelper();
+        tab.addObserver(new EmptyTabObserver() {
+            @Override
+            public void onLoadStopped(Tab tab, boolean toDifferentDocument) {
+                pageLoadFinishedHelper.notifyCalled();
+            }
+        });
+        try {
+            if (tab.isLoading()) {
+                pageLoadFinishedHelper.waitForCallback(
+                        0, 1, LONG_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            }
+        } catch (TimeoutException e) {
+            Assert.fail();
+        }
+        Assert.assertTrue("Deferred startup never completed",
+                DeferredStartupHandler.waitForDeferredStartupCompleteForTesting(
+                        STARTUP_TIMEOUT_MS));
+        Assert.assertNotNull(tab);
+        Assert.assertNotNull(tab.getView());
         Assert.assertTrue(TabTestUtils.isCustomTab(tab));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java
index 388d8a1..7a6fbb1a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java
@@ -27,7 +27,7 @@
 import org.chromium.chrome.browser.tab.TabTestUtils;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.external_intents.ExternalNavigationHandler;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.components.external_intents.ExternalNavigationParams;
 import org.chromium.net.test.EmbeddedTestServer;
 
@@ -107,9 +107,9 @@
         final String testUrl = "customtab://customtabtest/intent";
         ExternalNavigationParams params = new ExternalNavigationParams.Builder(testUrl, false)
                 .build();
-        @OverrideUrlLoadingResult
+        @OverrideUrlLoadingResultType
         int result = mUrlHandler.shouldOverrideUrlLoading(params);
-        Assert.assertEquals(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, result);
+        Assert.assertEquals(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, result);
         Assert.assertTrue("A dummy activity should have been started to handle the special url.",
                 mNavigationDelegate.hasExternalActivityStarted());
     }
@@ -124,9 +124,9 @@
         final String testUrl = "http://customtabtest.com";
         ExternalNavigationParams params = new ExternalNavigationParams.Builder(testUrl, false)
                 .build();
-        @OverrideUrlLoadingResult
+        @OverrideUrlLoadingResultType
         int result = mUrlHandler.shouldOverrideUrlLoading(params);
-        Assert.assertEquals(OverrideUrlLoadingResult.NO_OVERRIDE, result);
+        Assert.assertEquals(OverrideUrlLoadingResultType.NO_OVERRIDE, result);
         Assert.assertFalse("External activities should not be started to handle the url",
                 mNavigationDelegate.hasExternalActivityStarted());
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
index 1216b15..a07414a0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
@@ -37,7 +37,7 @@
 import org.chromium.chrome.browser.tab.TabTestUtils;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.components.external_intents.InterceptNavigationDelegateImpl;
 import org.chromium.content_public.browser.test.util.DOMUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -111,7 +111,8 @@
     @Test
     @Feature("CustomTabFromChrome")
     @LargeTest
-    public void testIntentWithRedirectToApp() {
+    public void
+    testIntentWithRedirectToApp() {
         final String redirectUrl = "https://maps.google.com/maps?q=1600+amphitheatre+parkway";
         final String initialUrl =
                 mServerRule.getServer().getURL("/chrome/test/data/android/redirect/js_redirect.html"
@@ -122,7 +123,7 @@
                         + Base64.encodeToString(
                                 ApiCompatibilityUtils.getBytesUtf8(redirectUrl), Base64.URL_SAFE));
 
-        mActivityRule.launchActivity(getCustomTabFromChromeIntent(initialUrl, true));
+        mActivityRule.startActivityCompletely(getCustomTabFromChromeIntent(initialUrl, true));
         mActivityRule.waitForActivityNativeInitializationComplete();
 
         final AtomicReference<InterceptNavigationDelegateImpl> navigationDelegate =
@@ -142,8 +143,9 @@
         }, "Navigation delegate never initialized.");
 
         CriteriaHelper.pollUiThread(() -> {
-            Criteria.checkThat(navigationDelegate.get().getLastOverrideUrlLoadingResultForTests(),
-                    Matchers.is(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT));
+            Criteria.checkThat(
+                    navigationDelegate.get().getLastOverrideUrlLoadingResultTypeForTests(),
+                    Matchers.is(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT));
         });
 
         CriteriaHelper.pollUiThread(() -> {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTest.java
index af9727f..0899713 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTest.java
@@ -9,10 +9,12 @@
 
 import androidx.test.filters.LargeTest;
 
+import org.junit.After;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
@@ -35,6 +37,11 @@
     public DisplayCutoutTestRule mTestRule =
             new DisplayCutoutTestRule<ChromeActivity>(ChromeActivity.class);
 
+    @After
+    public void tearDown() throws Exception {
+        ApplicationTestUtils.finishActivity(mTestRule.getActivity());
+    }
+
     /**
      * Test that no safe area is applied when we have viewport fit auto
      */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
index ed52c68d..3dc82eb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
@@ -13,7 +13,6 @@
 import android.net.Uri;
 import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.lifecycle.Stage;
 import android.text.TextUtils;
 import android.util.Base64;
 
@@ -29,14 +28,10 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.ScalableTimeout;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
@@ -46,7 +41,7 @@
 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.components.external_intents.InterceptNavigationDelegateImpl;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.NavigationHandle;
@@ -272,11 +267,11 @@
             Tab latestTab = latestTabHolder[0];
             InterceptNavigationDelegateImpl delegate = latestDelegateHolder[0];
             if (shouldLaunchExternalIntent) {
-                Criteria.checkThat(delegate.getLastOverrideUrlLoadingResultForTests(),
-                        Matchers.is(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT));
+                Criteria.checkThat(delegate.getLastOverrideUrlLoadingResultTypeForTests(),
+                        Matchers.is(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT));
             } else {
-                Criteria.checkThat(delegate.getLastOverrideUrlLoadingResultForTests(),
-                        Matchers.not(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT));
+                Criteria.checkThat(delegate.getLastOverrideUrlLoadingResultTypeForTests(),
+                        Matchers.not(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT));
             }
             if (expectedFinalUrl == null) return;
             Criteria.checkThat(latestTab.getUrlString(), Matchers.is(expectedFinalUrl));
@@ -429,36 +424,24 @@
 
     @Test
     @SmallTest
-    public void testRedirectionFromIntentCold() throws Exception {
-        Context context = ContextUtils.getApplicationContext();
+    public void testRedirectionFromIntent() {
+        // Test cold-start.
         Intent intent = new Intent(Intent.ACTION_VIEW,
                 Uri.parse(mTestServer.getURL(NAVIGATION_FROM_JAVA_REDIRECTION_PAGE)));
-        intent.setClassName(context, ChromeLauncherActivity.class.getName());
+        Context targetContext = InstrumentationRegistry.getTargetContext();
+        intent.setClassName(targetContext, ChromeLauncherActivity.class.getName());
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        ChromeTabbedActivity activity = ApplicationTestUtils.waitForActivityWithClass(
-                ChromeTabbedActivity.class, Stage.CREATED, () -> context.startActivity(intent));
-        mActivityTestRule.setActivity(activity);
-
-        CriteriaHelper.pollUiThread(() -> {
-            Criteria.checkThat(mActivityMonitor.getHits(), Matchers.is(1));
-        }, ScalableTimeout.scaleTimeout(10000L), CriteriaHelper.DEFAULT_POLLING_INTERVAL);
-        ApplicationTestUtils.waitForActivityState(activity, Stage.STOPPED);
-    }
-
-    @Test
-    @SmallTest
-    public void testRedirectionFromIntentWarm() throws Exception {
-        Context context = ContextUtils.getApplicationContext();
-        mActivityTestRule.startMainActivityOnBlankPage();
-        Intent intent = new Intent(Intent.ACTION_VIEW,
-                Uri.parse(mTestServer.getURL(NAVIGATION_FROM_JAVA_REDIRECTION_PAGE)));
-        intent.setClassName(context, ChromeLauncherActivity.class.getName());
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        context.startActivity(intent);
+        InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
 
         CriteriaHelper.pollUiThread(
                 () -> Criteria.checkThat(mActivityMonitor.getHits(), Matchers.is(1)));
+
+        // Test warm start.
+        mActivityTestRule.startMainActivityOnBlankPage();
+        targetContext.startActivity(intent);
+
+        CriteriaHelper.pollUiThread(
+                () -> Criteria.checkThat(mActivityMonitor.getHits(), Matchers.is(2)));
     }
 
     @Test
@@ -506,6 +489,7 @@
         String originalUrl = mTestServer.getURL(NAVIGATION_TO_FILE_SCHEME_FROM_INTENT_URI);
         loadUrlAndWaitForIntentUrl(originalUrl, true, false, false, null, false, "null_scheme");
     }
+
     @Test
     @LargeTest
     public void testIntentURIWithEmptySchemeDoesNothing() throws TimeoutException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java
index 3579486..7934a16 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java
@@ -16,7 +16,6 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import org.chromium.base.ActivityState;
@@ -65,16 +64,12 @@
 
     private EmbeddedTestServer mTestServer;
 
+    @Rule
     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+    @Rule
     public SettingsActivityTestRule<HomepageSettings> mSettingsActivityTestRule =
             new SettingsActivityTestRule<>(HomepageSettings.class);
 
-    // SettingsActivity has to be finished before the outer CTA can be finished or trying to finish
-    // CTA won't work.
-    @Rule
-    public final RuleChain mRuleChain =
-            RuleChain.outerRule(mActivityTestRule).around(mSettingsActivityTestRule);
-
     @Rule
     public HomepageTestRule mHomepageTestRule = new HomepageTestRule();
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java
index a273db8..703521dd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java
@@ -14,7 +14,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.UserActionTester;
@@ -105,8 +104,9 @@
         Assert.assertNotNull("Custom URI radio button is null.", mCustomUriRadioButton);
     }
 
-    private void finishSettingsActivity() throws Exception {
-        ApplicationTestUtils.finishActivity(mTestRule.getActivity());
+    private void finishSettingsActivity() {
+        mTestRule.getActivity().finish();
+        mTestRule.waitTillActivityIsDestroyed();
     }
 
     @Test
@@ -394,7 +394,7 @@
     @Test
     @SmallTest
     @Feature({"Homepage"})
-    public void testCheckRadioButtons() throws Exception {
+    public void testCheckRadioButtons() {
         mHomepageTestRule.useCustomizedHomepageForTest(TEST_URL_FOO);
         launchSettingsActivity();
         LocationChangedCounter counter = new LocationChangedCounter();
@@ -446,7 +446,7 @@
     @Test
     @SmallTest
     @Feature({"Homepage"})
-    public void testChangeCustomized() throws Exception {
+    public void testChangeCustomized() {
         mHomepageTestRule.useChromeNTPForTest();
         launchSettingsActivity();
         LocationChangedCounter actionCounter = new LocationChangedCounter();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
index 98254843..5c0af74 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
@@ -218,7 +218,7 @@
             // mSlowPage will hang for 2 seconds before sending a response. It should be enough to
             // put Chrome in background before the page is committed.
             mTabbedActivityTestRule.prepareUrlIntent(intent, mSlowPage);
-            mTabbedActivityTestRule.launchActivity(intent);
+            mTabbedActivityTestRule.startActivityCompletely(intent);
 
             // Put Chrome in background before the page is committed.
             ChromeApplicationTestUtils.fireHomeScreenIntent(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java
index 8c2cbab..cdbf6b55 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java
@@ -250,7 +250,6 @@
 
         // Offline indicator should not be shown.
         checkOfflineIndicatorVisibility(downloadActivity, false);
-        downloadActivity.finish();
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java
index 31ce50d..7c174616 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java
@@ -23,6 +23,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -206,6 +207,7 @@
     @Test
     @MediumTest
     @EnableFeatures("OmniboxMostVisitedTiles")
+    @DisabledTest(message = "Test flaky: https://crbug.com/1152246")
     public void keyboardNavigation_highlightingNextTileUpdatesUrlBarText()
             throws InterruptedException {
         // Skip past the 'what-you-typed' suggestion.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchConsentUiTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchConsentUiTest.java
index 012b466..4485b232 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchConsentUiTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchConsentUiTest.java
@@ -13,8 +13,6 @@
 
 import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.ASSISTANT_VOICE_SEARCH_ENABLED;
 
-import android.support.test.runner.lifecycle.Stage;
-
 import androidx.test.filters.MediumTest;
 
 import org.junit.After;
@@ -28,7 +26,6 @@
 import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.Callback;
-import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
@@ -36,7 +33,6 @@
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.settings.SettingsActivity;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
@@ -134,19 +130,16 @@
     public void testDialogInteractivity_LearnMoreButton() {
         showConsentUi();
 
-        SettingsActivity activity = ApplicationTestUtils.waitForActivityWithClass(
-                SettingsActivity.class, Stage.RESUMED, () -> {
-                    ClickUtils.clickButton(
-                            mAssistantVoiceSearchConsentUi.getContentView().findViewById(
-                                    R.id.avs_consent_ui_learn_more));
-                    mBottomSheetTestSupport.endAllAnimations();
-                });
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            ClickUtils.clickButton(mAssistantVoiceSearchConsentUi.getContentView().findViewById(
+                    R.id.avs_consent_ui_learn_more));
+            mBottomSheetTestSupport.endAllAnimations();
+        });
 
         onView(withText(mActivityTestRule.getActivity().getResources().getString(
                        R.string.avs_setting_category_title)))
                 .check(matches(isDisplayed()));
         Mockito.verify(mCallback, Mockito.times(0)).onResult(/* meaningless value */ true);
-        activity.finish();
     }
 
     @Test
@@ -163,4 +156,4 @@
         });
         Mockito.verify(mCallback, Mockito.timeout(1000)).onResult(false);
     }
-}
+}
\ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
index bc91ea83..a7fd8a3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -105,7 +105,7 @@
 
     private void loadUrlAndOpenPageInfo(String url) {
         mActivityTestRule.loadUrl(url);
-        onViewWaiting(allOf(withId(R.id.location_bar_status_icon), isDisplayed())).perform(click());
+        onView(withId(R.id.location_bar_status_icon)).perform(click());
     }
 
     private View getPageInfoView() {
@@ -184,6 +184,8 @@
         // Choose a fixed, "random" port to create stable screenshots.
         mTestServerRule.setServerPort(424242);
         mTestServerRule.setServerUsesHttps(true);
+
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     @After
@@ -207,7 +209,6 @@
     @Feature({"RenderTest"})
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowOnInsecureHttpWebsite() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         mTestServerRule.setServerUsesHttps(false);
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         mRenderTestRule.render(getPageInfoView(), "PageInfo_HttpWebsite");
@@ -221,7 +222,6 @@
     @Feature({"RenderTest"})
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowOnSecureWebsite() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         mRenderTestRule.render(getPageInfoView(), "PageInfo_SecureWebsite");
     }
@@ -235,7 +235,6 @@
     @DisabledTest(message = "https://crbug.com/1133770")
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowOnExpiredCertificateWebsite() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         mTestServerRule.setCertificateType(ServerCertificate.CERT_EXPIRED);
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         mRenderTestRule.render(getPageInfoView(), "PageInfo_ExpiredCertWebsite");
@@ -249,7 +248,6 @@
     @Feature({"RenderTest"})
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testChromePage() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         loadUrlAndOpenPageInfo("chrome://version/");
         mRenderTestRule.render(getPageInfoView(), "PageInfo_InternalSite");
     }
@@ -263,7 +261,6 @@
     @Feature({"RenderTest"})
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowWithPermissions() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         mIsSystemLocationSettingEnabled = false;
         addSomePermissions(mTestServerRule.getServer().getURL("/"));
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
@@ -278,7 +275,6 @@
     @Feature({"RenderTest"})
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowWithCookieBlocking() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY);
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         mRenderTestRule.render(getPageInfoView(), "PageInfo_CookieBlocking");
@@ -292,7 +288,6 @@
     @Feature({"RenderTest"})
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowWithPermissionsAndCookieBlocking() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         addSomePermissions(mTestServerRule.getServer().getURL("/"));
         setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY);
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
@@ -307,7 +302,6 @@
     @Feature({"RenderTest"})
     @Features.DisableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowWithDefaultSettingPermissions() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         addDefaultSettingPermissions(mTestServerRule.getServer().getURL("/"));
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         mRenderTestRule.render(getPageInfoView(), "PageInfo_DefaultSettingPermissions");
@@ -321,7 +315,6 @@
     @Feature({"RenderTest"})
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowOnSecureWebsiteV2() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         mRenderTestRule.render(getPageInfoView(), "PageInfo_SecureWebsiteV2");
     }
@@ -350,7 +343,6 @@
     @Feature({"RenderTest"})
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowConnectionInfoSubpage() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         onView(withId(R.id.page_info_connection_row)).perform(click());
         mRenderTestRule.render(getPageInfoView(), "PageInfo_ConnectionInfoSubpage");
@@ -364,7 +356,6 @@
     @Feature({"RenderTest"})
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowPermissionsSubpage() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         addSomePermissions(mTestServerRule.getServer().getURL("/"));
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         onView(withId(R.id.page_info_permissions_row)).perform(click());
@@ -379,7 +370,6 @@
     @Feature({"RenderTest"})
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testShowCookiesSubpage() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         setThirdPartyCookieBlocking(CookieControlsMode.BLOCK_THIRD_PARTY);
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         onView(withId(R.id.page_info_cookies_row)).perform(click());
@@ -394,7 +384,6 @@
     @MediumTest
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testNoPermissionsSubpage() throws IOException {
-        mActivityTestRule.startMainActivityOnBlankPage();
         loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
         View dialog = (View) getPageInfoView().getParent();
         onView(withId(R.id.page_info_permissions_row))
@@ -409,7 +398,6 @@
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     @FlakyTest(message = "https://crbug.com/1147236")
     public void testClearCookiesOnSubpage() throws Exception {
-        mActivityTestRule.startMainActivityOnBlankPage();
         mActivityTestRule.loadUrl(mTestServerRule.getServer().getURL(sSiteDataHtml));
         // Create cookies.
         expectHasCookies(false);
@@ -435,7 +423,6 @@
     @MediumTest
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
     public void testResetPermissionsOnSubpage() throws Exception {
-        mActivityTestRule.startMainActivityOnBlankPage();
         mActivityTestRule.loadUrl(mTestServerRule.getServer().getURL(sSiteDataHtml));
         String url = mTestServerRule.getServer().getURL("/");
         // Create permissions.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
index 2c90ae80..3b5375ab2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
@@ -1245,7 +1245,6 @@
         @Override
         public void create(PaymentAppFactoryDelegate delegate) {
             Runnable createApp = () -> {
-                if (delegate.getParams().hasClosed()) return;
                 boolean canMakePayment =
                         delegate.getParams().getMethodData().containsKey(mAppMethodName);
                 delegate.onCanMakePaymentCalculated(canMakePayment);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
index 947221f..aa1888d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
@@ -15,7 +15,6 @@
 import static org.mockito.Mockito.verify;
 
 import android.app.Activity;
-import android.support.test.InstrumentationRegistry;
 import android.text.TextUtils;
 import android.view.View;
 
@@ -102,7 +101,7 @@
     private final SyncTestRule mSyncTestRule = new SyncTestRule();
 
     private final SettingsActivityTestRule<MainSettings> mSettingsActivityTestRule =
-            new SettingsActivityTestRule<>(MainSettings.class);
+            new SettingsActivityTestRule<>(MainSettings.class, true);
 
     // SettingsActivity needs to be initialized and destroyed with the mock
     // signin environment setup in SyncTestRule
@@ -134,7 +133,6 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        InstrumentationRegistry.getInstrumentation().setInTouchMode(true);
         PasswordCheckFactory.setPasswordCheckForTesting(mPasswordCheck);
         SigninActivityLauncherImpl.setLauncherForTest(mMockSigninActivityLauncherImpl);
         DeveloperSettings.setIsEnabledForTests(true);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetRenderTest.java
index 67834235..516bc1db0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetRenderTest.java
@@ -22,6 +22,7 @@
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.test.filters.MediumTest;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -33,6 +34,7 @@
 import org.chromium.base.Callback;
 import org.chromium.base.test.params.ParameterAnnotations;
 import org.chromium.base.test.params.ParameterizedRunner;
+import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.CriteriaHelper;
@@ -118,6 +120,11 @@
         mActivityTestRule.startMainActivityOnBlankPage();
     }
 
+    @After
+    public void tearDown() throws Exception {
+        ApplicationTestUtils.finishActivity(mActivityTestRule.getActivity());
+    }
+
     @AfterClass
     public static void tearDownAfterActivityDestroyed() {
         ChromeNightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java
index 056d897..be7b8a5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java
@@ -14,6 +14,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.Batch;
+import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
 import org.chromium.chrome.test.util.browser.signin.MockChangeEventChecker;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ManageSpaceActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ManageSpaceActivityTest.java
index 5383798..16095c4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ManageSpaceActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ManageSpaceActivityTest.java
@@ -100,7 +100,7 @@
     @Test
     @SmallTest
     public void testLaunchActivity() {
-        startManageSpaceActivity().finish();
+        startManageSpaceActivity();
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
index d0a1c47..b42cd0d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
@@ -18,7 +18,6 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.CommandLineFlags;
@@ -41,18 +40,14 @@
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 public class AccountManagementFragmentTest {
+    @Rule
     public final SettingsActivityTestRule<AccountManagementFragment> mSettingsActivityTestRule =
             new SettingsActivityTestRule<>(AccountManagementFragment.class);
 
+    @Rule
     public final ChromeTabbedActivityTestRule mActivityTestRule =
             new ChromeTabbedActivityTestRule();
 
-    // SettingsActivity has to be finished before the outer CTA can be finished or trying to finish
-    // CTA won't work.
-    @Rule
-    public final RuleChain mRuleChain =
-            RuleChain.outerRule(mActivityTestRule).around(mSettingsActivityTestRule);
-
     @Rule
     public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule();
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java
index 9b38421..dc9d76a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java
@@ -16,7 +16,6 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.CommandLineFlags;
@@ -52,17 +51,13 @@
     @Rule
     public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule();
 
+    @Rule
     public final ChromeTabbedActivityTestRule mActivityTestRule =
             new ChromeTabbedActivityTestRule();
 
-    public final SettingsActivityTestRule<GoogleServicesSettings> mSettingsActivityTestRule =
-            new SettingsActivityTestRule<>(GoogleServicesSettings.class);
-
-    // SettingsActivity has to be finished before the outer CTA can be finished or trying to finish
-    // CTA won't work.
     @Rule
-    public final RuleChain mRuleChain =
-            RuleChain.outerRule(mActivityTestRule).around(mSettingsActivityTestRule);
+    public final SettingsActivityTestRule<GoogleServicesSettings> mSettingsActivityTestRule =
+            new SettingsActivityTestRule<>(GoogleServicesSettings.class, true);
 
     @Before
     public void setUp() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
index 2acd095..9c90fe6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
@@ -90,7 +90,7 @@
     private final SyncTestRule mSyncTestRule = new SyncTestRule();
 
     private final SettingsActivityTestRule<ManageSyncSettings> mSettingsActivityTestRule =
-            new SettingsActivityTestRule<>(ManageSyncSettings.class);
+            new SettingsActivityTestRule<>(ManageSyncSettings.class, true);
 
     // SettingsActivity needs to be initialized and destroyed with the mock
     // signin environment setup in SyncTestRule
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java
index 559a75f..76da0b0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java
@@ -62,7 +62,7 @@
 
     @Rule
     public final SettingsActivityTestRule<ManageSyncSettings> mSettingsActivityTestRule =
-            new SettingsActivityTestRule<>(ManageSyncSettings.class);
+            new SettingsActivityTestRule<>(ManageSyncSettings.class, true);
 
     @Rule
     public final ChromeRenderTestRule mRenderTestRule =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
index 458cdfa..cfd5d948 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
@@ -4,12 +4,6 @@
 
 package org.chromium.chrome.browser.sync;
 
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -19,7 +13,6 @@
 
 import androidx.annotation.Nullable;
 import androidx.preference.TwoStatePreference;
-import androidx.test.espresso.contrib.RecyclerViewActions;
 
 import org.junit.Assert;
 import org.junit.runner.Description;
@@ -38,7 +31,6 @@
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
-import org.chromium.components.browser_ui.widget.R;
 import org.chromium.components.signin.base.CoreAccountInfo;
 import org.chromium.components.sync.ModelType;
 import org.chromium.components.sync.protocol.AutofillWalletSpecifics;
@@ -418,9 +410,12 @@
 
     // UI interaction convenience methods.
     public void togglePreference(final TwoStatePreference pref) {
-        onView(withId(R.id.recycler_view))
-                .perform(RecyclerViewActions.actionOnItem(
-                        hasDescendant(withText(pref.getTitle().toString())), click()));
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            boolean newValue = !pref.isChecked();
+            pref.getOnPreferenceChangeListener().onPreferenceChange(pref, newValue);
+            pref.setChecked(newValue);
+        });
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
index 955d291..41f76677 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
@@ -76,10 +76,10 @@
         }
 
         @Override
-        public @OverrideUrlLoadingResult int shouldOverrideUrlLoading(
+        public @OverrideUrlLoadingResultType int shouldOverrideUrlLoading(
                 ExternalNavigationParams params) {
             mExternalNavParamHistory.add(params);
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/LevelDBPersistedTabDataStorageFactoryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/LevelDBPersistedTabDataStorageFactoryTest.java
index c715a63..2611d9a5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/LevelDBPersistedTabDataStorageFactoryTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/LevelDBPersistedTabDataStorageFactoryTest.java
@@ -64,11 +64,9 @@
         LevelDBPersistedTabDataStorage.setSkipNativeAssertionsForTesting(true);
     }
 
-    @UiThreadTest
     @SmallTest
     @Test
     public void testFactoryMethod() {
-        Profile realProfile = Profile.getLastUsedRegularProfile();
         LevelDBPersistedTabDataStorageFactory factory = new LevelDBPersistedTabDataStorageFactory();
         Profile.setLastUsedProfileForTesting(mProfile1);
         LevelDBPersistedTabDataStorage profile1Storage = factory.create();
@@ -78,8 +76,6 @@
         LevelDBPersistedTabDataStorage profile1StorageAgain = factory.create();
         Assert.assertEquals(profile1Storage, profile1StorageAgain);
         Assert.assertNotEquals(profile1Storage, profile2Storage);
-        // Restore the original profile so the Activity can shut down correctly.
-        Profile.setLastUsedProfileForTesting(realProfile);
     }
 
     @UiThreadTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
index cf1a94e0..12907e88 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
@@ -597,7 +597,7 @@
         intent.addCategory(Intent.CATEGORY_LAUNCHER);
         mActivityTestRule.prepareUrlIntent(intent, url);
         Assert.assertFalse(mInflated.get());
-        mActivityTestRule.launchActivity(intent);
+        mActivityTestRule.startActivityCompletely(intent);
         if (mUseInstantStart) {
             CriteriaHelper.pollUiThread(mInflated::get);
         } else {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
index fc5fc02..33af8329 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
@@ -263,7 +263,7 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
         filter.addDataScheme("https");
         final ActivityMonitor monitor =
-                InstrumentationRegistry.getInstrumentation().addMonitor(filter, null, true);
+                InstrumentationRegistry.getInstrumentation().addMonitor(filter, null, false);
 
         RevampedContextMenuUtils.selectContextMenuItem(InstrumentationRegistry.getInstrumentation(),
                 null /* activity to check for focus after click */,
diff --git a/chrome/android/junit/DEPS b/chrome/android/junit/DEPS
index 08cbf0e..4ea03137 100644
--- a/chrome/android/junit/DEPS
+++ b/chrome/android/junit/DEPS
@@ -8,6 +8,7 @@
   "+chrome/browser/performance_hints/android/java",
   "+chrome/browser/profiles/android",
   "+chrome/browser/share",
+  "+chrome/browser/signin/services/android/java",
   "+chrome/browser/tab",
   "+chrome/browser/tabmodel",
   "+chrome/browser/thumbnail/generator/android/java",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java
index 2e2d6a21..2e68e4d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java
@@ -23,6 +23,7 @@
 
 import org.chromium.base.supplier.Supplier;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 
 import java.util.Arrays;
 import java.util.Collections;
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 84f6f83..ad64eb57 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -1218,6 +1218,18 @@
   <message name="IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_FEATURE_UNAVAILABLE" desc="Explains that the password check feature is not available in this version of the browser.">
     Password check is not available in Chromium
   </message>
+  <message name="IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_SAFE" desc="This text explains that the Chrome password check did not find any insecure passwords.">
+    No security issues found
+  </message>
+  <message name="IDS_SETTINGS_SAFETY_CHECK_COMPROMISED_PASSWORDS" desc="This shows the amount of compromised passwords that the Chrome password check found.">
+    {NUM_COMPROMISED, plural, =0 {} =1 {1 compromised password} other {{NUM_COMPROMISED} compromised passwords}}
+  </message>
+  <message name="IDS_SETTINGS_SAFETY_CHECK_WEAK_PASSWORDS" desc="This shows the amount of weak passwords that the Chrome password check found.">
+    {NUM_WEAK, plural, =0 {} =1 {1 weak password} other {{NUM_WEAK} weak passwords}}
+  </message>
+  <message name="IDS_SETTINGS_SAFETY_CHECK_STRING_TUPLE_WITH_COMMA" desc="This string lists two elements, via concatenating them with a comma in the English language.">
+    <ph name="TYPE_1">$1<ex>2 compromised passwords</ex></ph>, <ph name="TYPE_2">$2<ex>7 weak passwords</ex></ph>
+  </message>
   <message name="IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_BUTTON_ARIA_LABEL" desc="Accessibility text for the button that allows users to review their passwords.">
     Review passwords
   </message>
@@ -1316,7 +1328,7 @@
       Something went wrong. Click for more details.
     </message>
   </if>
-  
+
   <message name="IDS_SETTINGS_NETWORK_PREDICTION_ENABLED_LABEL" desc="In the advanced options tab, the text next to the checkbox that enables prediction of network actions.  Actions include browser-initiated DNS prefetching, TCP and SSL preconnection, and prerendering of webpages.">
     Preload pages for faster browsing and searching
   </message>
@@ -1665,6 +1677,9 @@
   <message name="IDS_SETTINGS_SITE_SETTINGS_CUSTOMIZED_BEHAVIORS" desc="Label for the site settings exceptions.">
     Customized behaviors
   </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_CUSTOMIZED_BEHAVIORS_DESCRIPTION" desc="Description for the site settings exceptions.">
+    Sites listed below follow a custom setting instead of the default
+  </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_ADS_DESCRIPTION" desc="Description of the ads content setting.">
     Sites usually show ads so they can provide content or services for free. But, some sites are known to show intrusive or misleading ads.
   </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_COMPROMISED_PASSWORDS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_COMPROMISED_PASSWORDS.png.sha1
new file mode 100644
index 0000000..03ed930
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_COMPROMISED_PASSWORDS.png.sha1
@@ -0,0 +1 @@
+48000c9b3b776cd72ef4b37861123533cef88cb7
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_SAFE.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_SAFE.png.sha1
new file mode 100644
index 0000000..9051e4c
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_SAFE.png.sha1
@@ -0,0 +1 @@
+9337b5cfa3bcef4342156a73d83cf37043f783e9
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_STRING_TUPLE_WITH_COMMA.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_STRING_TUPLE_WITH_COMMA.png.sha1
new file mode 100644
index 0000000..1274908
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_STRING_TUPLE_WITH_COMMA.png.sha1
@@ -0,0 +1 @@
+6139bb64c11e0f921e8d5951367952b62ecb3fcc
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_WEAK_PASSWORDS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_WEAK_PASSWORDS.png.sha1
new file mode 100644
index 0000000..17a7c6cb
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SAFETY_CHECK_WEAK_PASSWORDS.png.sha1
@@ -0,0 +1 @@
+8d987688c08641fee35f117eddeaa63f9769a515
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_CUSTOMIZED_BEHAVIORS_DESCRIPTION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_CUSTOMIZED_BEHAVIORS_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..c567bc37
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_CUSTOMIZED_BEHAVIORS_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+c389010d57a048d2b9cf09eb090cf81284ef1bb6
\ No newline at end of file
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
index 795b311..ed3119a2 100644
--- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc
+++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -109,14 +109,13 @@
     base::android::ScopedJavaLocalRef<jstring> jsublabel_accessibility_hint =
         nullptr;
     if (login_choice.sublabel_accessibility_hint.has_value()) {
-      jsublabel_accessibility_hint = base::android::ConvertUTF8ToJavaString(
+      jsublabel_accessibility_hint = ConvertUTF8ToJavaString(
           env, login_choice.sublabel_accessibility_hint.value());
     }
     Java_AssistantCollectUserDataModel_addLoginChoice(
-        env, jlist,
-        base::android::ConvertUTF8ToJavaString(env, login_choice.identifier),
-        base::android::ConvertUTF8ToJavaString(env, login_choice.label),
-        base::android::ConvertUTF8ToJavaString(env, login_choice.sublabel),
+        env, jlist, ConvertUTF8ToJavaString(env, login_choice.identifier),
+        ConvertUTF8ToJavaString(env, login_choice.label),
+        ConvertUTF8ToJavaString(env, login_choice.sublabel),
         jsublabel_accessibility_hint, login_choice.preselect_priority,
         jinfo_popup);
   }
@@ -143,10 +142,9 @@
         continue;
     }
     Java_AssistantCollectUserDataModel_appendTextInput(
-        env, jinput_list, type,
-        base::android::ConvertUTF8ToJavaString(env, input.hint()),
-        base::android::ConvertUTF8ToJavaString(env, input.value()),
-        base::android::ConvertUTF8ToJavaString(env, input.client_memory_key()));
+        env, jinput_list, type, ConvertUTF8ToJavaString(env, input.hint()),
+        ConvertUTF8ToJavaString(env, input.value()),
+        ConvertUTF8ToJavaString(env, input.client_memory_key()));
   }
   return jinput_list;
 }
@@ -161,15 +159,12 @@
     switch (section.section_case()) {
       case UserFormSectionProto::kStaticTextSection:
         Java_AssistantCollectUserDataModel_appendStaticTextSection(
-            env, jsection_list,
-            base::android::ConvertUTF8ToJavaString(env, section.title()),
-            base::android::ConvertUTF8ToJavaString(
-                env, section.static_text_section().text()));
+            env, jsection_list, ConvertUTF8ToJavaString(env, section.title()),
+            ConvertUTF8ToJavaString(env, section.static_text_section().text()));
         break;
       case UserFormSectionProto::kTextInputSection: {
         Java_AssistantCollectUserDataModel_appendTextInputSection(
-            env, jsection_list,
-            base::android::ConvertUTF8ToJavaString(env, section.title()),
+            env, jsection_list, ConvertUTF8ToJavaString(env, section.title()),
             CreateJavaTextInputsForSection(env, section.text_input_section()));
         break;
       }
@@ -183,15 +178,14 @@
                   section.popup_list_section().initial_selection().end(),
                   std::back_inserter(initial_selections));
         Java_AssistantCollectUserDataModel_appendPopupListSection(
-            env, jsection_list,
-            base::android::ConvertUTF8ToJavaString(env, section.title()),
-            base::android::ConvertUTF8ToJavaString(
+            env, jsection_list, ConvertUTF8ToJavaString(env, section.title()),
+            ConvertUTF8ToJavaString(
                 env, section.popup_list_section().additional_value_key()),
             base::android::ToJavaArrayOfStrings(env, items),
             base::android::ToJavaIntArray(env, initial_selections),
             section.popup_list_section().allow_multiselect(),
             section.popup_list_section().selection_mandatory(),
-            base::android::ConvertUTF8ToJavaString(
+            ConvertUTF8ToJavaString(
                 env,
                 section.popup_list_section().no_selection_error_message()));
         break;
@@ -534,8 +528,7 @@
   JNIEnv* env = AttachCurrentThread();
   Java_AutofillAssistantUiController_showFeedback(
       env, java_object_,
-      base::android::ConvertUTF8ToJavaString(env,
-                                             ui_delegate_->GetDebugContext()));
+      ConvertUTF8ToJavaString(env, ui_delegate_->GetDebugContext()));
 }
 
 void UiControllerAndroid::OnViewEvent(const EventHandler::EventKey& key) {
@@ -570,7 +563,7 @@
   snackbar_action_ = std::move(action);
   Java_AutofillAssistantUiController_showSnackbar(
       env, java_object_, static_cast<jint>(delay.InMilliseconds()),
-      base::android::ConvertUTF8ToJavaString(env, message));
+      ConvertUTF8ToJavaString(env, message));
 }
 
 void UiControllerAndroid::SnackbarResult(
@@ -1221,19 +1214,19 @@
       env, jmodel, collect_user_data_options->request_login_choice);
   Java_AssistantCollectUserDataModel_setLoginSectionTitle(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
-          env, collect_user_data_options->login_section_title));
+      ConvertUTF8ToJavaString(env,
+                              collect_user_data_options->login_section_title));
   Java_AssistantCollectUserDataModel_setContactSectionTitle(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
+      ConvertUTF8ToJavaString(
           env, collect_user_data_options->contact_details_section_title));
   Java_AssistantCollectUserDataModel_setShippingSectionTitle(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
+      ConvertUTF8ToJavaString(
           env, collect_user_data_options->shipping_address_section_title));
   Java_AssistantCollectUserDataModel_setAcceptTermsAndConditionsText(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
+      ConvertUTF8ToJavaString(
           env, collect_user_data_options->accept_terms_and_conditions_text));
   Java_AssistantCollectUserDataModel_setShowTermsAsCheckbox(
       env, jmodel, collect_user_data_options->show_terms_as_checkbox);
@@ -1241,11 +1234,11 @@
       env, jmodel, collect_user_data_options->require_billing_postal_code);
   Java_AssistantCollectUserDataModel_setBillingPostalCodeMissingText(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
+      ConvertUTF8ToJavaString(
           env, collect_user_data_options->billing_postal_code_missing_text));
   Java_AssistantCollectUserDataModel_setCreditCardExpiredText(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
+      ConvertUTF8ToJavaString(
           env, collect_user_data_options->credit_card_expired_text));
   Java_AssistantCollectUserDataModel_setSupportedBasicCardNetworks(
       env, jmodel,
@@ -1275,46 +1268,46 @@
         env, jmodel, jmin_date, jmax_date, jtime_slots);
     Java_AssistantCollectUserDataModel_setDateTimeRangeStartDateLabel(
         env, jmodel,
-        base::android::ConvertUTF8ToJavaString(
+        ConvertUTF8ToJavaString(
             env,
             collect_user_data_options->date_time_range.start_date_label()));
     Java_AssistantCollectUserDataModel_setDateTimeRangeStartTimeLabel(
         env, jmodel,
-        base::android::ConvertUTF8ToJavaString(
+        ConvertUTF8ToJavaString(
             env,
             collect_user_data_options->date_time_range.start_time_label()));
     Java_AssistantCollectUserDataModel_setDateTimeRangeEndDateLabel(
         env, jmodel,
-        base::android::ConvertUTF8ToJavaString(
+        ConvertUTF8ToJavaString(
             env, collect_user_data_options->date_time_range.end_date_label()));
     Java_AssistantCollectUserDataModel_setDateTimeRangeEndTimeLabel(
         env, jmodel,
-        base::android::ConvertUTF8ToJavaString(
+        ConvertUTF8ToJavaString(
             env, collect_user_data_options->date_time_range.end_time_label()));
     Java_AssistantCollectUserDataModel_setDateTimeRangeDateNotSetErrorMessage(
         env, jmodel,
-        base::android::ConvertUTF8ToJavaString(
+        ConvertUTF8ToJavaString(
             env,
             collect_user_data_options->date_time_range.date_not_set_error()));
     Java_AssistantCollectUserDataModel_setDateTimeRangeTimeNotSetErrorMessage(
         env, jmodel,
-        base::android::ConvertUTF8ToJavaString(
+        ConvertUTF8ToJavaString(
             env,
             collect_user_data_options->date_time_range.time_not_set_error()));
   }
   Java_AssistantCollectUserDataModel_setTermsRequireReviewText(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
+      ConvertUTF8ToJavaString(
           env, collect_user_data_options->terms_require_review_text));
   Java_AssistantCollectUserDataModel_setInfoSectionText(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
-          env, collect_user_data_options->info_section_text),
+      ConvertUTF8ToJavaString(env,
+                              collect_user_data_options->info_section_text),
       collect_user_data_options->info_section_text_center);
   Java_AssistantCollectUserDataModel_setPrivacyNoticeText(
       env, jmodel,
-      base::android::ConvertUTF8ToJavaString(
-          env, collect_user_data_options->privacy_notice_text));
+      ConvertUTF8ToJavaString(env,
+                              collect_user_data_options->privacy_notice_text));
 
   Java_AssistantCollectUserDataModel_setPrependedSections(
       env, jmodel,
@@ -1582,12 +1575,9 @@
           Java_AssistantFormInput_addCounter(
               env, jcounters,
               Java_AssistantFormInput_createCounter(
-                  env,
-                  base::android::ConvertUTF8ToJavaString(env, counter.label()),
-                  base::android::ConvertUTF8ToJavaString(
-                      env, counter.description_line_1()),
-                  base::android::ConvertUTF8ToJavaString(
-                      env, counter.description_line_2()),
+                  env, ConvertUTF8ToJavaString(env, counter.label()),
+                  ConvertUTF8ToJavaString(env, counter.description_line_1()),
+                  ConvertUTF8ToJavaString(env, counter.description_line_2()),
                   result_value.has_value() ? result_value.value()
                                            : counter.initial_value(),
                   counter.min_value(), counter.max_value(),
@@ -1597,13 +1587,9 @@
         Java_AssistantFormModel_addInput(
             env, jinput_list,
             Java_AssistantFormInput_createCounterInput(
-                env, i,
-                base::android::ConvertUTF8ToJavaString(env,
-                                                       counter_input.label()),
-                base::android::ConvertUTF8ToJavaString(
-                    env, counter_input.expand_text()),
-                base::android::ConvertUTF8ToJavaString(
-                    env, counter_input.minimize_text()),
+                env, i, ConvertUTF8ToJavaString(env, counter_input.label()),
+                ConvertUTF8ToJavaString(env, counter_input.expand_text()),
+                ConvertUTF8ToJavaString(env, counter_input.minimize_text()),
                 jcounters, counter_input.minimized_count(),
                 counter_input.min_counters_sum(),
                 counter_input.max_counters_sum(),
@@ -1622,12 +1608,9 @@
           Java_AssistantFormInput_addChoice(
               env, jchoices,
               Java_AssistantFormInput_createChoice(
-                  env,
-                  base::android::ConvertUTF8ToJavaString(env, choice.label()),
-                  base::android::ConvertUTF8ToJavaString(
-                      env, choice.description_line_1()),
-                  base::android::ConvertUTF8ToJavaString(
-                      env, choice.description_line_2()),
+                  env, ConvertUTF8ToJavaString(env, choice.label()),
+                  ConvertUTF8ToJavaString(env, choice.description_line_1()),
+                  ConvertUTF8ToJavaString(env, choice.description_line_2()),
                   result_value.has_value() ? result_value.value()
                                            : choice.selected()));
         }
@@ -1635,9 +1618,7 @@
         Java_AssistantFormModel_addInput(
             env, jinput_list,
             Java_AssistantFormInput_createSelectionInput(
-                env, i,
-                base::android::ConvertUTF8ToJavaString(env,
-                                                       selection_input.label()),
+                env, i, ConvertUTF8ToJavaString(env, selection_input.label()),
                 jchoices, selection_input.allow_multiple(),
                 form_delegate_.GetJavaObject()));
         break;
@@ -1653,8 +1634,7 @@
 
   if (form->has_info_label()) {
     Java_AssistantFormModel_setInfoLabel(
-        env, GetFormModel(),
-        base::android::ConvertUTF8ToJavaString(env, form->info_label()));
+        env, GetFormModel(), ConvertUTF8ToJavaString(env, form->info_label()));
   } else {
     Java_AssistantFormModel_clearInfoLabel(env, GetFormModel());
   }
@@ -1695,7 +1675,7 @@
             env, jcontext, image.image_drawable(),
             ui_delegate_->GetUserModel()),
         image_size, top_margin, bottom_margin,
-        base::android::ConvertUTF8ToJavaString(env, image.text()),
+        ConvertUTF8ToJavaString(env, image.text()),
         ui_controller_android_utils::GetJavaColor(env, image.text_color()),
         text_size);
   } else {
@@ -1762,26 +1742,25 @@
   base::android::ScopedJavaLocalRef<jstring> jimage_accessibility_hint =
       nullptr;
   if (opt_image_accessibility_hint.has_value()) {
-    jimage_accessibility_hint = base::android::ConvertUTF8ToJavaString(
-        env, opt_image_accessibility_hint.value());
+    jimage_accessibility_hint =
+        ConvertUTF8ToJavaString(env, opt_image_accessibility_hint.value());
   }
   auto jdetails = Java_AssistantDetails_create(
-      env, base::android::ConvertUTF8ToJavaString(env, details->title()),
+      env, ConvertUTF8ToJavaString(env, details->title()),
       details->titleMaxLines(),
-      base::android::ConvertUTF8ToJavaString(env, details->imageUrl()),
+      ConvertUTF8ToJavaString(env, details->imageUrl()),
       jimage_accessibility_hint, details->imageAllowClickthrough(),
-      base::android::ConvertUTF8ToJavaString(env, details->imageDescription()),
-      base::android::ConvertUTF8ToJavaString(env, details->imagePositiveText()),
-      base::android::ConvertUTF8ToJavaString(env, details->imageNegativeText()),
-      base::android::ConvertUTF8ToJavaString(env,
-                                             details->imageClickthroughUrl()),
+      ConvertUTF8ToJavaString(env, details->imageDescription()),
+      ConvertUTF8ToJavaString(env, details->imagePositiveText()),
+      ConvertUTF8ToJavaString(env, details->imageNegativeText()),
+      ConvertUTF8ToJavaString(env, details->imageClickthroughUrl()),
       details->showImagePlaceholder(),
-      base::android::ConvertUTF8ToJavaString(env, details->totalPriceLabel()),
-      base::android::ConvertUTF8ToJavaString(env, details->totalPrice()),
-      base::android::ConvertUTF8ToJavaString(env, details->descriptionLine1()),
-      base::android::ConvertUTF8ToJavaString(env, details->descriptionLine2()),
-      base::android::ConvertUTF8ToJavaString(env, details->descriptionLine3()),
-      base::android::ConvertUTF8ToJavaString(env, details->priceAttribution()),
+      ConvertUTF8ToJavaString(env, details->totalPriceLabel()),
+      ConvertUTF8ToJavaString(env, details->totalPrice()),
+      ConvertUTF8ToJavaString(env, details->descriptionLine1()),
+      ConvertUTF8ToJavaString(env, details->descriptionLine2()),
+      ConvertUTF8ToJavaString(env, details->descriptionLine3()),
+      ConvertUTF8ToJavaString(env, details->priceAttribution()),
       details->userApprovalRequired(), details->highlightTitle(),
       details->highlightLine1(), details->highlightLine2(),
       details->highlightLine3(), details->animatePlaceholders());
@@ -1805,8 +1784,8 @@
 
   const InfoBoxProto& proto = info_box->proto().info_box();
   auto jinfo_box = Java_AssistantInfoBox_create(
-      env, base::android::ConvertUTF8ToJavaString(env, proto.image_path()),
-      base::android::ConvertUTF8ToJavaString(env, proto.explanation()));
+      env, ConvertUTF8ToJavaString(env, proto.image_path()),
+      ConvertUTF8ToJavaString(env, proto.explanation()));
   Java_AssistantInfoBoxModel_setInfoBox(env, jmodel, jinfo_box);
 }
 
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 0246f53..718ee03 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -766,6 +766,8 @@
     "arc/session/arc_app_id_provider_impl.h",
     "arc/session/arc_play_store_enabled_preference_handler.cc",
     "arc/session/arc_play_store_enabled_preference_handler.h",
+    "arc/session/arc_provisioning_result.cc",
+    "arc/session/arc_provisioning_result.h",
     "arc/session/arc_service_launcher.cc",
     "arc/session/arc_service_launcher.h",
     "arc/session/arc_session_manager.cc",
@@ -3335,6 +3337,7 @@
     "arc/policy/arc_policy_bridge_unittest.cc",
     "arc/process/arc_process_unittest.cc",
     "arc/session/arc_play_store_enabled_preference_handler_unittest.cc",
+    "arc/session/arc_provisioning_result_unittest.cc",
     "arc/session/arc_session_manager_unittest.cc",
     "arc/tracing/arc_app_performance_tracing_unittest.cc",
     "arc/tracing/arc_cpu_event_unittest.cc",
diff --git a/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc b/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc
index ffe76a8..3a19b027 100644
--- a/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/timer/timer.h"
+#include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/ui/browser.h"
@@ -158,8 +159,15 @@
   DISALLOW_COPY_AND_ASSIGN(MagnificationControllerTest);
 };
 
+// Test is flaky on ChromeOS: crbug.com/1150753
+#if defined(OS_CHROMEOS)
+#define MAYBE_FollowFocusOnWebButtonContained \
+  DISABLED_FollowFocusOnWebButtonContained
+#else
+#define MAYBE_FollowFocusOnWebButtonContained FollowFocusOnWebButtonContained
+#endif
 IN_PROC_BROWSER_TEST_F(MagnificationControllerTest,
-                       FollowFocusOnWebButtonContained) {
+                       MAYBE_FollowFocusOnWebButtonContained) {
   DCHECK(IsMagnifierEnabled());
   ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
       browser(), GURL(std::string(kDataURIPrefix) + kTestHtmlContent)));
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.cc b/chrome/browser/chromeos/arc/arc_optin_uma.cc
index 4ca78e5..6828016d 100644
--- a/chrome/browser/chromeos/arc/arc_optin_uma.cc
+++ b/chrome/browser/chromeos/arc/arc_optin_uma.cc
@@ -10,6 +10,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h"
+#include "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -74,9 +75,9 @@
   base::UmaHistogramEnumeration("Arc.OptInResult", result);
 }
 
-void UpdateProvisioningResultUMA(ProvisioningResult result,
+void UpdateProvisioningResultUMA(ProvisioningResultUMA result,
                                  const Profile* profile) {
-  DCHECK_NE(result, ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR);
+  DCHECK_NE(result, ProvisioningResultUMA::CHROME_SERVER_COMMUNICATION_ERROR);
   base::UmaHistogramEnumeration(
       GetHistogramNameByUserType("Arc.Provisioning.Result", profile), result);
 }
@@ -88,7 +89,7 @@
       error);
 }
 
-void UpdateSecondarySigninResultUMA(ProvisioningResult result) {
+void UpdateSecondarySigninResultUMA(ProvisioningResultUMA result) {
   base::UmaHistogramEnumeration("Arc.Secondary.Signin.Result", result);
 }
 
@@ -105,7 +106,7 @@
       base::TimeDelta::FromSeconds(1), base::TimeDelta::FromMinutes(6), 50);
 }
 
-void UpdateReauthorizationResultUMA(ProvisioningResult result,
+void UpdateReauthorizationResultUMA(ProvisioningResultUMA result,
                                     const Profile* profile) {
   base::UmaHistogramEnumeration(
       GetHistogramNameByUserType("Arc.Reauthorization.Result", profile),
@@ -205,9 +206,80 @@
                            static_cast<int>(state));
 }
 
-std::ostream& operator<<(std::ostream& os, const ProvisioningResult& result) {
+ProvisioningResultUMA GetProvisioningResultUMA(
+    const ArcProvisioningResult& provisioning_result) {
+  if (provisioning_result.is_stopped())
+    return ProvisioningResultUMA::ARC_STOPPED;
+
+  if (provisioning_result.is_timedout())
+    return ProvisioningResultUMA::OVERALL_SIGN_IN_TIMEOUT;
+
+  const mojom::ArcSignInResult* result = provisioning_result.signin_result();
+  if (result->is_success()) {
+    if (result->get_success() == mojom::ArcSignInSuccess::SUCCESS)
+      return ProvisioningResultUMA::SUCCESS;
+    else
+      return ProvisioningResultUMA::SUCCESS_ALREADY_PROVISIONED;
+  }
+
+  if (result->get_error()->is_cloud_provision_flow_error())
+    return ProvisioningResultUMA::CLOUD_PROVISION_FLOW_ERROR;
+
+  if (result->get_error()->is_general_error()) {
+#define MAP_GENERAL_ERROR(name)         \
+  case mojom::GeneralSignInError::name: \
+    return ProvisioningResultUMA::name
+
+    switch (result->get_error()->get_general_error()) {
+      MAP_GENERAL_ERROR(UNKNOWN_ERROR);
+      MAP_GENERAL_ERROR(MOJO_VERSION_MISMATCH);
+      MAP_GENERAL_ERROR(PROVISIONING_TIMEOUT);
+      MAP_GENERAL_ERROR(NO_NETWORK_CONNECTION);
+      MAP_GENERAL_ERROR(CHROME_SERVER_COMMUNICATION_ERROR);
+      MAP_GENERAL_ERROR(ARC_DISABLED);
+      MAP_GENERAL_ERROR(UNSUPPORTED_ACCOUNT_TYPE);
+      MAP_GENERAL_ERROR(CHROME_ACCOUNT_NOT_FOUND);
+    }
+#undef MAP_GENERAL_ERROR
+  }
+
+  if (result->get_error()->is_checkin_error()) {
+#define MAP_CHECKIN_ERROR(name)         \
+  case mojom::DeviceCheckInError::name: \
+    return ProvisioningResultUMA::name
+
+    switch (result->get_error()->get_checkin_error()) {
+      MAP_CHECKIN_ERROR(DEVICE_CHECK_IN_FAILED);
+      MAP_CHECKIN_ERROR(DEVICE_CHECK_IN_TIMEOUT);
+      MAP_CHECKIN_ERROR(DEVICE_CHECK_IN_INTERNAL_ERROR);
+    }
+#undef MAP_CHECKIN_ERROR
+  }
+
+  if (result->get_error()->is_gms_error()) {
+#define MAP_GMS_ERROR(name)   \
+  case mojom::GMSError::name: \
+    return ProvisioningResultUMA::name
+
+    switch (result->get_error()->get_gms_error()) {
+      MAP_GMS_ERROR(GMS_NETWORK_ERROR);
+      MAP_GMS_ERROR(GMS_SERVICE_UNAVAILABLE);
+      MAP_GMS_ERROR(GMS_BAD_AUTHENTICATION);
+      MAP_GMS_ERROR(GMS_SIGN_IN_FAILED);
+      MAP_GMS_ERROR(GMS_SIGN_IN_TIMEOUT);
+      MAP_GMS_ERROR(GMS_SIGN_IN_INTERNAL_ERROR);
+    }
+#undef MAP_GMS_ERROR
+  }
+
+  NOTREACHED() << "unknown sign result";
+  return ProvisioningResultUMA::UNKNOWN_ERROR;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ProvisioningResultUMA& result) {
 #define MAP_PROVISIONING_RESULT(name) \
-  case ProvisioningResult::name:      \
+  case ProvisioningResultUMA::name:   \
     return os << #name
 
   switch (result) {
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.h b/chrome/browser/chromeos/arc/arc_optin_uma.h
index cc02cd5..7326fb5 100644
--- a/chrome/browser/chromeos/arc/arc_optin_uma.h
+++ b/chrome/browser/chromeos/arc/arc_optin_uma.h
@@ -18,6 +18,8 @@
 
 namespace arc {
 
+class ArcProvisioningResult;
+
 // These enums are used to define the buckets for an enumerated UMA histogram
 // and need to be synced with tools/metrics/histograms/enums.xml. Note that
 // values 0, 1, 2, 3 and 4 are now deprecated.
@@ -103,7 +105,7 @@
 // The values should be listed in ascending order. They are also persisted to
 // logs, and their values should therefore never be renumbered nor reused. For
 // detailed meaning, please consult auth.mojom.
-enum class ProvisioningResult : int {
+enum class ProvisioningResultUMA : int {
   // Provisioning was successful. Note, SUCCESS_ALREADY_PROVISIONED is also
   // successful state.
   SUCCESS = 0,
@@ -224,15 +226,15 @@
 void UpdateOptInActionUMA(OptInActionType type);
 void UpdateOptInCancelUMA(OptInCancelReason reason);
 void UpdateOptInFlowResultUMA(OptInFlowResult result);
-void UpdateProvisioningResultUMA(ProvisioningResult result,
+void UpdateProvisioningResultUMA(ProvisioningResultUMA result,
                                  const Profile* profile);
 void UpdateCloudProvisionFlowErrorUMA(mojom::CloudProvisionFlowError error,
                                       const Profile* profile);
-void UpdateSecondarySigninResultUMA(ProvisioningResult result);
+void UpdateSecondarySigninResultUMA(ProvisioningResultUMA result);
 void UpdateProvisioningTiming(const base::TimeDelta& elapsed_time,
                               bool success,
                               const Profile* profile);
-void UpdateReauthorizationResultUMA(ProvisioningResult result,
+void UpdateReauthorizationResultUMA(ProvisioningResultUMA result,
                                     const Profile* profile);
 void UpdatePlayAutoInstallRequestState(mojom::PaiFlowState state,
                                        const Profile* profile);
@@ -261,8 +263,14 @@
     const Profile* profile,
     mojom::MainAccountResolutionStatus status);
 
+// Returns the enum for use in UMA stat and displaying error code on the UI.
+// This enum should not be used anywhere else. Please work with the object
+// instead.
+ProvisioningResultUMA GetProvisioningResultUMA(
+    const ArcProvisioningResult& provisioning_result);
+
 // Outputs the stringified |result| to |os|. This is only for logging purposes.
-std::ostream& operator<<(std::ostream& os, const ProvisioningResult& result);
+std::ostream& operator<<(std::ostream& os, const ProvisioningResultUMA& result);
 
 }  // namespace arc
 
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
index 7729f508..4680e3f9 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/chromeos/arc/auth/arc_background_auth_code_fetcher.h"
 #include "chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher.h"
 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h"
+#include "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
@@ -71,63 +72,6 @@
   ~ArcAuthServiceFactory() override = default;
 };
 
-// Converts mojom::ArcSignInResult into ProvisiningResult.
-ProvisioningResult ConvertArcSignInResultToProvisioningResult(
-    mojom::ArcSignInResult* result) {
-  if (result->is_success()) {
-    if (result->get_success() == mojom::ArcSignInSuccess::SUCCESS)
-      return ProvisioningResult::SUCCESS;
-    else
-      return ProvisioningResult::SUCCESS_ALREADY_PROVISIONED;
-  } else if (result->get_error()->is_cloud_provision_flow_error()) {
-    return ProvisioningResult::CLOUD_PROVISION_FLOW_ERROR;
-  } else if (result->get_error()->is_general_error()) {
-#define MAP_GENERAL_ERROR(name)         \
-  case mojom::GeneralSignInError::name: \
-    return ProvisioningResult::name
-
-    switch (result->get_error()->get_general_error()) {
-      MAP_GENERAL_ERROR(UNKNOWN_ERROR);
-      MAP_GENERAL_ERROR(MOJO_VERSION_MISMATCH);
-      MAP_GENERAL_ERROR(PROVISIONING_TIMEOUT);
-      MAP_GENERAL_ERROR(NO_NETWORK_CONNECTION);
-      MAP_GENERAL_ERROR(CHROME_SERVER_COMMUNICATION_ERROR);
-      MAP_GENERAL_ERROR(ARC_DISABLED);
-      MAP_GENERAL_ERROR(UNSUPPORTED_ACCOUNT_TYPE);
-      MAP_GENERAL_ERROR(CHROME_ACCOUNT_NOT_FOUND);
-    }
-#undef MAP_GENERAL_ERROR
-  } else if (result->get_error()->is_checkin_error()) {
-#define MAP_CHECKIN_ERROR(name)         \
-  case mojom::DeviceCheckInError::name: \
-    return ProvisioningResult::name
-
-    switch (result->get_error()->get_checkin_error()) {
-      MAP_CHECKIN_ERROR(DEVICE_CHECK_IN_FAILED);
-      MAP_CHECKIN_ERROR(DEVICE_CHECK_IN_TIMEOUT);
-      MAP_CHECKIN_ERROR(DEVICE_CHECK_IN_INTERNAL_ERROR);
-    }
-#undef MAP_CHECKIN_ERROR
-  } else if (result->get_error()->is_gms_error()) {
-#define MAP_GMS_ERROR(name)   \
-  case mojom::GMSError::name: \
-    return ProvisioningResult::name
-
-    switch (result->get_error()->get_gms_error()) {
-      MAP_GMS_ERROR(GMS_NETWORK_ERROR);
-      MAP_GMS_ERROR(GMS_SERVICE_UNAVAILABLE);
-      MAP_GMS_ERROR(GMS_BAD_AUTHENTICATION);
-      MAP_GMS_ERROR(GMS_SIGN_IN_FAILED);
-      MAP_GMS_ERROR(GMS_SIGN_IN_TIMEOUT);
-      MAP_GMS_ERROR(GMS_SIGN_IN_INTERNAL_ERROR);
-    }
-#undef MAP_GMS_ERROR
-  }
-
-  NOTREACHED() << "unknown sign result";
-  return ProvisioningResult::UNKNOWN_ERROR;
-}
-
 mojom::ChromeAccountType GetAccountType(const Profile* profile) {
   if (profile->IsChild())
     return mojom::ChromeAccountType::CHILD_ACCOUNT;
@@ -368,14 +312,11 @@
 
 void ArcAuthService::OnAuthorizationResult(mojom::ArcSignInResultPtr result,
                                            mojom::ArcSignInAccountPtr account) {
-  const ProvisioningResult provisioning_result =
-      ConvertArcSignInResultToProvisioningResult(result.get());
+  ArcProvisioningResult provisioning_result(std::move(result));
 
   if (account->is_initial_signin()) {
     // UMA for initial signin is updated from ArcSessionManager.
-    ArcSessionManager::Get()->OnProvisioningFinished(
-        provisioning_result,
-        result->is_error() ? std::move(result->get_error()) : nullptr);
+    ArcSessionManager::Get()->OnProvisioningFinished(provisioning_result);
     return;
   }
 
@@ -385,6 +326,9 @@
     return;
   }
 
+  ProvisioningResultUMA provisioning_result_enum =
+      GetProvisioningResultUMA(provisioning_result);
+
   if (!account->is_account_name() || !account->get_account_name() ||
       account->get_account_name().value().empty() ||
       IsPrimaryOrDeviceLocalAccount(identity_manager_,
@@ -393,11 +337,11 @@
     // The check for |!account_name.has_value()| is for backwards compatibility
     // with older ARC versions, for which Mojo will set |account_name| to
     // empty/null.
-    DCHECK_NE(ProvisioningResult::SUCCESS_ALREADY_PROVISIONED,
-              provisioning_result);
-    UpdateReauthorizationResultUMA(provisioning_result, profile_);
+    DCHECK_NE(ProvisioningResultUMA::SUCCESS_ALREADY_PROVISIONED,
+              provisioning_result_enum);
+    UpdateReauthorizationResultUMA(provisioning_result_enum, profile_);
   } else {
-    UpdateSecondarySigninResultUMA(provisioning_result);
+    UpdateSecondarySigninResultUMA(provisioning_result_enum);
   }
 }
 
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_unittest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_unittest.cc
index e87fe9b..7c656fdd 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
+#include "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
 #include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
@@ -162,8 +163,11 @@
   EXPECT_FALSE(
       profile()->GetPrefs()->GetBoolean(prefs::kArcInitialSettingsPending));
 
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
 
   EXPECT_TRUE(
       profile()->GetPrefs()->GetBoolean(prefs::kArcInitialSettingsPending));
@@ -201,8 +205,11 @@
                   ->GetBroadcastsForAction(kActionLocaionEnabled)
                   .empty());
 
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
 
   EXPECT_FALSE(
       profile()->GetPrefs()->GetBoolean(prefs::kArcInitialSettingsPending));
diff --git a/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc b/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc
index 31a1ad4a..263d8ec 100644
--- a/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/notification/arc_provision_notification_service_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/values.h"
 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
 #include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/chromeos/login/ui/fake_login_display_host.h"
@@ -125,7 +126,11 @@
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager_->state());
 
   // Emulate successful provisioning. The notification gets removed.
-  arc_session_manager_->OnProvisioningFinished(ProvisioningResult::SUCCESS, {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager_->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 }
@@ -156,7 +161,11 @@
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager_->state());
-  arc_session_manager_->OnProvisioningFinished(ProvisioningResult::SUCCESS, {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager_->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 }
@@ -187,8 +196,11 @@
 
   // Emulate provisioning failure that leads to stopping ARC. The notification
   // gets removed.
+  arc::mojom::ArcSignInResultPtr result = arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGeneralError(
+          arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR));
   arc_session_manager_->OnProvisioningFinished(
-      ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR, {});
+      ArcProvisioningResult(std::move(result)));
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 }
@@ -219,8 +231,11 @@
 
   // Emulate provisioning failure that leads to showing an error screen without
   // shutting ARC down. The notification gets removed.
+  arc::mojom::ArcSignInResultPtr result = arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGeneralError(
+          arc::mojom::GeneralSignInError::NO_NETWORK_CONNECTION));
   arc_session_manager_->OnProvisioningFinished(
-      ProvisioningResult::NO_NETWORK_CONNECTION, {});
+      ArcProvisioningResult(std::move(result)));
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 }
@@ -251,7 +266,11 @@
   // Emulate successful provisioning.
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
-  arc_session_manager_->OnProvisioningFinished(ProvisioningResult::SUCCESS, {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager_->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 }
@@ -314,7 +333,11 @@
   // Emulate successful provisioning.
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
-  arc_session_manager_->OnProvisioningFinished(ProvisioningResult::SUCCESS, {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager_->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 }
diff --git a/chrome/browser/chromeos/arc/session/arc_provisioning_result.cc b/chrome/browser/chromeos/arc/session/arc_provisioning_result.cc
new file mode 100644
index 0000000..d8d1263
--- /dev/null
+++ b/chrome/browser/chromeos/arc/session/arc_provisioning_result.cc
@@ -0,0 +1,68 @@
+// 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 "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
+
+#include "base/check.h"
+#include "chrome/browser/chromeos/arc/arc_optin_uma.h"
+
+namespace arc {
+
+ArcProvisioningResult::ArcProvisioningResult(mojom::ArcSignInResultPtr result)
+    : result_(std::move(result)) {}
+ArcProvisioningResult::ArcProvisioningResult(ArcStopReason reason)
+    : result_(reason) {}
+ArcProvisioningResult::ArcProvisioningResult(OverallSignInTimeout timeout)
+    : result_(timeout) {}
+ArcProvisioningResult::ArcProvisioningResult(ArcProvisioningResult&& other) =
+    default;
+ArcProvisioningResult::~ArcProvisioningResult() = default;
+
+bool ArcProvisioningResult::has_signin_result() const {
+  return absl::holds_alternative<mojom::ArcSignInResultPtr>(result_);
+}
+
+const mojom::ArcSignInResult* ArcProvisioningResult::signin_result() const {
+  DCHECK(has_signin_result());
+  return absl::get<mojom::ArcSignInResultPtr>(result_).get();
+}
+
+bool ArcProvisioningResult::has_signin_error() const {
+  return has_signin_result() && signin_result()->is_error();
+}
+
+const mojom::ArcSignInError* ArcProvisioningResult::signin_error() const {
+  DCHECK(has_signin_error());
+  return signin_result()->get_error().get();
+}
+
+bool ArcProvisioningResult::is_success() const {
+  return has_signin_result() && signin_result()->is_success();
+}
+
+bool ArcProvisioningResult::has_general_error(
+    mojom::GeneralSignInError error) const {
+  return has_signin_error() && signin_error()->is_general_error() &&
+         signin_error()->get_general_error() == error;
+}
+
+bool ArcProvisioningResult::is_stopped() const {
+  return absl::holds_alternative<ArcStopReason>(result_);
+}
+
+ArcStopReason ArcProvisioningResult::stop_reason() const {
+  DCHECK(is_stopped());
+  return absl::get<ArcStopReason>(result_);
+}
+
+bool ArcProvisioningResult::is_timedout() const {
+  return absl::holds_alternative<OverallSignInTimeout>(result_);
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ArcProvisioningResult& result) {
+  return os << GetProvisioningResultUMA(result);
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/session/arc_provisioning_result.h b/chrome/browser/chromeos/arc/session/arc_provisioning_result.h
new file mode 100644
index 0000000..5edd44c6
--- /dev/null
+++ b/chrome/browser/chromeos/arc/session/arc_provisioning_result.h
@@ -0,0 +1,67 @@
+// 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 CHROME_BROWSER_CHROMEOS_ARC_SESSION_ARC_PROVISIONING_RESULT_H_
+#define CHROME_BROWSER_CHROMEOS_ARC_SESSION_ARC_PROVISIONING_RESULT_H_
+
+#include <ostream>
+
+#include "components/arc/mojom/auth.mojom.h"
+#include "components/arc/session/arc_stop_reason.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
+
+enum class ProvisioningResultUMA : int;
+
+namespace arc {
+
+// A struct that represents timeout of ARC provisioning from Chrome.
+struct OverallSignInTimeout {};
+
+// A class that encapsulates the result of provisioning ARC.
+class ArcProvisioningResult {
+ public:
+  explicit ArcProvisioningResult(mojom::ArcSignInResultPtr result);
+  explicit ArcProvisioningResult(ArcStopReason reason);
+  explicit ArcProvisioningResult(OverallSignInTimeout timeout);
+  ArcProvisioningResult(ArcProvisioningResult&& other);
+  ~ArcProvisioningResult();
+
+  // Returns true if signin_result from ARC is present.
+  bool has_signin_result() const;
+
+  // Returns the result of provisioning from inside ARC.
+  const mojom::ArcSignInResult* signin_result() const;
+
+  // Returns true if signin_result is present with an error.
+  bool has_signin_error() const;
+
+  // Returns the error of signin_result coming from ARC.
+  const mojom::ArcSignInError* signin_error() const;
+
+  // Returns true if result has given general sign-in error.
+  bool has_general_error(mojom::GeneralSignInError error) const;
+
+  // Returns true if provisioning was successful.
+  bool is_success() const;
+
+  // Returns true if ARC provisioning was stopped pre-maturely.
+  bool is_stopped() const;
+
+  // Returns the reason for ARC stopped event.
+  ArcStopReason stop_reason() const;
+
+  // Returns true if ARC provisioning timed out in Chrome.
+  bool is_timedout() const;
+
+ private:
+  absl::variant<mojom::ArcSignInResultPtr, ArcStopReason, OverallSignInTimeout>
+      result_;
+};
+
+// Outputs the stringified |result| to |os|. This is only for logging purposes.
+std::ostream& operator<<(std::ostream& os, const ArcProvisioningResult& result);
+
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_CHROMEOS_ARC_SESSION_ARC_PROVISIONING_RESULT_H_
diff --git a/chrome/browser/chromeos/arc/session/arc_provisioning_result_unittest.cc b/chrome/browser/chromeos/arc/session/arc_provisioning_result_unittest.cc
new file mode 100644
index 0000000..20d7dafb
--- /dev/null
+++ b/chrome/browser/chromeos/arc/session/arc_provisioning_result_unittest.cc
@@ -0,0 +1,96 @@
+// 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 "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
+
+#include "chrome/browser/chromeos/arc/arc_optin_uma.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+TEST(ArcProvisioningResultTest, HasSignInResult) {
+  ArcProvisioningResult result1(ArcStopReason::CRASH);
+  EXPECT_FALSE(result1.has_signin_result());
+
+  ArcProvisioningResult result2(arc::mojom::ArcSignInResult::NewSuccess(
+      arc::mojom::ArcSignInSuccess::SUCCESS));
+  EXPECT_TRUE(result2.has_signin_result());
+}
+
+TEST(ArcProvisioningResultTest, HasSignInError) {
+  ArcProvisioningResult result1(ArcStopReason::CRASH);
+  EXPECT_FALSE(result1.has_signin_error());
+
+  ArcProvisioningResult result2(arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGeneralError(
+          arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR)));
+  EXPECT_TRUE(result2.has_signin_error());
+}
+
+TEST(ArcProvisioningResultTest, Success) {
+  ArcProvisioningResult result1(ArcStopReason::CRASH);
+  EXPECT_FALSE(result1.is_success());
+
+  ArcProvisioningResult result2(arc::mojom::ArcSignInResult::NewSuccess(
+      arc::mojom::ArcSignInSuccess::SUCCESS));
+  EXPECT_TRUE(result2.is_success());
+
+  ArcProvisioningResult result3(arc::mojom::ArcSignInResult::NewSuccess(
+      arc::mojom::ArcSignInSuccess::SUCCESS_ALREADY_PROVISIONED));
+  EXPECT_TRUE(result3.is_success());
+}
+
+TEST(ArcProvisioningResultTest, Stopped) {
+  ArcProvisioningResult result1(arc::mojom::ArcSignInResult::NewSuccess(
+      arc::mojom::ArcSignInSuccess::SUCCESS));
+  EXPECT_FALSE(result1.is_stopped());
+
+  ArcProvisioningResult result2(ArcStopReason::CRASH);
+  EXPECT_TRUE(result2.is_stopped());
+
+  ArcProvisioningResult result3(ArcStopReason::SHUTDOWN);
+  EXPECT_TRUE(result3.is_stopped());
+
+  ArcProvisioningResult result4(ArcStopReason::GENERIC_BOOT_FAILURE);
+  EXPECT_TRUE(result4.is_stopped());
+
+  ArcProvisioningResult result5(ArcStopReason::LOW_DISK_SPACE);
+  EXPECT_TRUE(result5.is_stopped());
+}
+
+TEST(ArcProvisioningResultTest, Timedout) {
+  ArcProvisioningResult result1(ArcStopReason::CRASH);
+  EXPECT_FALSE(result1.is_timedout());
+
+  ArcProvisioningResult result2(OverallSignInTimeout{});
+  EXPECT_TRUE(result2.is_timedout());
+}
+
+TEST(ArcProvisioningResultTest, HasGeneralError) {
+  ArcProvisioningResult result1(ArcStopReason::CRASH);
+  EXPECT_FALSE(result1.has_general_error(
+      arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR));
+
+  ArcProvisioningResult result2(arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGeneralError(
+          arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR)));
+  EXPECT_TRUE(result2.has_general_error(
+      arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR));
+}
+
+TEST(ArcProvisioningResultTest, StopReason) {
+  ArcProvisioningResult result1(ArcStopReason::CRASH);
+  EXPECT_EQ(ArcStopReason::CRASH, result1.stop_reason());
+
+  ArcProvisioningResult result2(ArcStopReason::SHUTDOWN);
+  EXPECT_EQ(ArcStopReason::SHUTDOWN, result2.stop_reason());
+
+  ArcProvisioningResult result3(ArcStopReason::GENERIC_BOOT_FAILURE);
+  EXPECT_EQ(ArcStopReason::GENERIC_BOOT_FAILURE, result3.stop_reason());
+
+  ArcProvisioningResult result4(ArcStopReason::LOW_DISK_SPACE);
+  EXPECT_EQ(ArcStopReason::LOW_DISK_SPACE, result4.stop_reason());
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.cc b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
index 2ef4f2e4..89b0083 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager.cc
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
@@ -32,6 +32,7 @@
 #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator.h"
 #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_oobe_negotiator.h"
 #include "chrome/browser/chromeos/arc/policy/arc_android_management_checker.h"
+#include "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_resources.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
 #include "chrome/browser/chromeos/policy/powerwash_requirements_checker.h"
@@ -291,7 +292,7 @@
   return true;
 }
 
-int GetSignInErrorCode(arc::mojom::ArcSignInErrorPtr signin_error) {
+int GetSignInErrorCode(const arc::mojom::ArcSignInError* signin_error) {
   if (!signin_error)
     return 0;
 
@@ -549,7 +550,7 @@
   state_ = State::STOPPED;
 
   if (arc_sign_in_timer_.IsRunning())
-    OnProvisioningFinished(ProvisioningResult::ARC_STOPPED, reason);
+    OnProvisioningFinished(ArcProvisioningResult(reason));
 
   for (auto& observer : observer_list_)
     observer.OnArcSessionStopped(reason);
@@ -563,8 +564,7 @@
 }
 
 void ArcSessionManager::OnProvisioningFinished(
-    ProvisioningResult result,
-    absl::variant<mojom::ArcSignInErrorPtr, ArcStopReason> error) {
+    const ArcProvisioningResult& result) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // If the Mojo message to notify finishing the provisioning is already sent
@@ -574,27 +574,22 @@
   // does not support the case of re-enabling.
   if (!enable_requested_) {
     LOG(WARNING) << "Provisioning result received after ARC was disabled. "
-                 << "Ignoring result " << static_cast<int>(result) << ".";
+                 << "Ignoring result " << result << ".";
     return;
   }
 
-  mojom::ArcSignInErrorPtr signin_error =
-      absl::holds_alternative<mojom::ArcSignInErrorPtr>(error)
-          ? std::move(absl::get<mojom::ArcSignInErrorPtr>(error))
-          : nullptr;
+  const mojom::ArcSignInError* signin_error =
+      result.has_signin_error() ? result.signin_error() : nullptr;
 
   // Due asynchronous nature of stopping the ARC instance,
   // OnProvisioningFinished may arrive after setting the |State::STOPPED| state
   // and |State::Active| is not guaranteed to be set here.
   // prefs::kArcDataRemoveRequested also can be active for now.
 
-  const bool provisioning_successful =
-      result == ProvisioningResult::SUCCESS ||
-      result == ProvisioningResult::SUCCESS_ALREADY_PROVISIONED;
+  const bool provisioning_successful = result.is_success();
   if (provisioning_reported_) {
-    // We don't expect ProvisioningResult::SUCCESS or
-    // ProvisioningResult::SUCCESS_ALREADY_PROVISIONED to be reported twice or
-    // reported after an error.
+    // We don't expect success ArcProvisnioningResult to be reported twice
+    // or reported after an error.
     DCHECK(!provisioning_successful);
     // TODO(khmel): Consider changing LOG to NOTREACHED once we guaranty that
     // no double message can happen in production.
@@ -606,7 +601,8 @@
   if (scoped_opt_in_tracker_ && !provisioning_successful)
     scoped_opt_in_tracker_->TrackError();
 
-  if (result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) {
+  if (result.has_general_error(
+          mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR)) {
     // TODO(poromov): Consider ARC PublicSession offline mode.
     // Currently ARC session will be exited below, while the main user session
     // will be kept alive without Android apps.
@@ -628,7 +624,7 @@
 
     UpdateProvisioningTiming(base::TimeTicks::Now() - sign_in_start_time_,
                              provisioning_successful, profile_);
-    UpdateProvisioningResultUMA(result, profile_);
+    UpdateProvisioningResultUMA(GetProvisioningResultUMA(result), profile_);
     if (signin_error && signin_error->is_cloud_provision_flow_error()) {
       UpdateCloudProvisionFlowErrorUMA(
           signin_error->get_cloud_provision_flow_error(), profile_);
@@ -674,78 +670,66 @@
 
   ArcSupportHost::Error support_error;
   VLOG(1) << "ARC provisioning failed: " << result << ".";
-  switch (result) {
-    case ProvisioningResult::GMS_NETWORK_ERROR:
-      support_error = ArcSupportHost::Error::SIGN_IN_NETWORK_ERROR;
-      break;
-    case ProvisioningResult::GMS_SERVICE_UNAVAILABLE:
-    case ProvisioningResult::GMS_SIGN_IN_FAILED:
-    case ProvisioningResult::GMS_SIGN_IN_TIMEOUT:
-    case ProvisioningResult::GMS_SIGN_IN_INTERNAL_ERROR:
-      support_error = ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR;
-      break;
-    case ProvisioningResult::GMS_BAD_AUTHENTICATION:
-      support_error = ArcSupportHost::Error::SIGN_IN_BAD_AUTHENTICATION_ERROR;
-      break;
-    case ProvisioningResult::DEVICE_CHECK_IN_FAILED:
-    case ProvisioningResult::DEVICE_CHECK_IN_TIMEOUT:
-    case ProvisioningResult::DEVICE_CHECK_IN_INTERNAL_ERROR:
-      support_error = ArcSupportHost::Error::SIGN_IN_GMS_NOT_AVAILABLE_ERROR;
-      break;
-    case ProvisioningResult::CLOUD_PROVISION_FLOW_ERROR:
-      DCHECK(signin_error && signin_error->is_cloud_provision_flow_error());
-      support_error = GetCloudProvisionFlowError(
-          signin_error->get_cloud_provision_flow_error());
-      break;
-    case ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR:
-      support_error = ArcSupportHost::Error::SERVER_COMMUNICATION_ERROR;
-      break;
-    case ProvisioningResult::NO_NETWORK_CONNECTION:
-      support_error = ArcSupportHost::Error::NETWORK_UNAVAILABLE_ERROR;
-      break;
-    case ProvisioningResult::ARC_DISABLED:
-      support_error = ArcSupportHost::Error::ANDROID_MANAGEMENT_REQUIRED_ERROR;
-      break;
-    case ProvisioningResult::ARC_STOPPED:
-      DCHECK(absl::holds_alternative<ArcStopReason>(error));
-      support_error =
-          absl::get<ArcStopReason>(error) == ArcStopReason::LOW_DISK_SPACE
-              ? ArcSupportHost::Error::LOW_DISK_SPACE_ERROR
-              : ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR;
-      break;
-    default:
-      support_error = ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR;
-      break;
+  if (signin_error && signin_error->is_gms_error() &&
+      signin_error->get_gms_error() == mojom::GMSError::GMS_NETWORK_ERROR) {
+    support_error = ArcSupportHost::Error::SIGN_IN_NETWORK_ERROR;
+  } else if (signin_error && signin_error->is_gms_error() &&
+             signin_error->get_gms_error() ==
+                 mojom::GMSError::GMS_BAD_AUTHENTICATION) {
+    support_error = ArcSupportHost::Error::SIGN_IN_BAD_AUTHENTICATION_ERROR;
+  } else if (signin_error && signin_error->is_gms_error()) {
+    support_error = ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR;
+  } else if (signin_error && signin_error->is_checkin_error()) {
+    support_error = ArcSupportHost::Error::SIGN_IN_GMS_NOT_AVAILABLE_ERROR;
+  } else if (signin_error && signin_error->is_cloud_provision_flow_error()) {
+    support_error = GetCloudProvisionFlowError(
+        signin_error->get_cloud_provision_flow_error());
+  } else if (result.has_general_error(mojom::GeneralSignInError::
+                                          CHROME_SERVER_COMMUNICATION_ERROR)) {
+    support_error = ArcSupportHost::Error::SERVER_COMMUNICATION_ERROR;
+  } else if (result.has_general_error(
+                 mojom::GeneralSignInError::NO_NETWORK_CONNECTION)) {
+    support_error = ArcSupportHost::Error::NETWORK_UNAVAILABLE_ERROR;
+  } else if (result.has_general_error(
+                 mojom::GeneralSignInError::ARC_DISABLED)) {
+    support_error = ArcSupportHost::Error::ANDROID_MANAGEMENT_REQUIRED_ERROR;
+  } else if (result.is_stopped()) {
+    support_error = result.stop_reason() == ArcStopReason::LOW_DISK_SPACE
+                        ? ArcSupportHost::Error::LOW_DISK_SPACE_ERROR
+                        : ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR;
+  } else {
+    support_error = ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR;
   }
 
   // When ARC provisioning fails due to Chrome failing to talk to server, we
   // don't need to keep the ARC session running as the logs necessary to
   // investigate are already present. ARC session will not provide any useful
   // context.
-  if (result == ProvisioningResult::ARC_STOPPED ||
-      result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) {
+  if (result.is_stopped() ||
+      result.has_general_error(
+          mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR)) {
     if (profile_->GetPrefs()->HasPrefPath(prefs::kArcSignedIn))
       profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, false);
     VLOG(1) << "Stopping ARC due to provisioning failure";
     ShutdownSession();
   }
 
-  if (result == ProvisioningResult::CLOUD_PROVISION_FLOW_ERROR ||
+  if ((signin_error && signin_error->is_cloud_provision_flow_error()) ||
       // OVERALL_SIGN_IN_TIMEOUT might be an indication that ARC believes it is
       // fully setup, but Chrome does not.
-      result == ProvisioningResult::OVERALL_SIGN_IN_TIMEOUT ||
+      result.is_timedout() ||
       // Just to be safe, remove data if we don't know the cause.
-      result == ProvisioningResult::UNKNOWN_ERROR) {
+      result.has_general_error(mojom::GeneralSignInError::UNKNOWN_ERROR)) {
     VLOG(1) << "ARC provisioning failed permanently. Removing user data";
     RequestArcDataRemoval();
   }
 
   base::Optional<int> error_code;
   if (support_error == ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR) {
-    error_code =
-        static_cast<std::underlying_type_t<ProvisioningResult>>(result);
+    error_code = static_cast<std::underlying_type_t<ProvisioningResultUMA>>(
+        GetProvisioningResultUMA(result));
   } else if (signin_error) {
-    error_code = GetSignInErrorCode(std::move(signin_error));
+    error_code = GetSignInErrorCode(signin_error);
   }
   ShowArcSupportHostError({support_error, error_code} /* error_info */,
                           true /* should_show_send_feedback */);
@@ -933,7 +917,7 @@
 
 void ArcSessionManager::OnArcSignInTimeout() {
   LOG(ERROR) << "Timed out waiting for first sign in.";
-  OnProvisioningFinished(ProvisioningResult::OVERALL_SIGN_IN_TIMEOUT, {});
+  OnProvisioningFinished(ArcProvisioningResult(OverallSignInTimeout()));
 }
 
 void ArcSessionManager::CancelAuthCode() {
@@ -1265,8 +1249,8 @@
 
   // State::STOPPED appears here in following scenario.
   // Initial provisioning finished with state
-  // ProvisioningResult::ArcStop or
-  // ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR.
+  // ProvisioningResultUMA::ArcStop or
+  // ProvisioningResultUMA::CHROME_SERVER_COMMUNICATION_ERROR.
   // At this moment |prefs::kArcTermsAccepted| is set to true, once user
   // confirmed ToS prior to provisioning flow. Once user presses "Try Again"
   // button, OnRetryClicked calls this immediately.
@@ -1551,10 +1535,9 @@
   } else {
     // Otherwise, we start ARC once it is stopped now. Usually ARC container is
     // left active after provisioning failure but in case
-    // ProvisioningResult::ARC_STOPPED and
-    // ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR failures container
-    // is stopped.
-    // At this point ToS is already accepted and
+    // ProvisioningResultUMA::ARC_STOPPED and
+    // ProvisioningResultUMA::CHROME_SERVER_COMMUNICATION_ERROR failures
+    // container is stopped. At this point ToS is already accepted and
     // IsArcTermsOfServiceNegotiationNeeded returns true or ToS needs not to be
     // shown at all. However there is an exception when this does not happen in
     // case an error page is shown when re-opt-in right after opt-out (this is a
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.h b/chrome/browser/chromeos/arc/session/arc_session_manager.h
index 77f5b1ef..78eeb26 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager.h
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager.h
@@ -41,10 +41,11 @@
 class ArcDataRemover;
 class ArcFastAppReinstallStarter;
 class ArcPaiStarter;
+class ArcProvisioningResult;
 class ArcTermsOfServiceNegotiator;
 class ArcUiAvailabilityReporter;
 
-enum class ProvisioningResult : int;
+enum class ProvisioningResultUMA : int;
 enum class ArcStopReason;
 
 // This class is responsible for handing stages of ARC life-cycle.
@@ -210,14 +211,13 @@
   ArcSupportHost* support_host() { return support_host_.get(); }
 
   // On provisioning completion (regardless of whether successfully done or
-  // not), this is called with its status. On success, called with
-  // ProvisioningResult::SUCCESS, otherwise |result| is the error reason.
-  // |error| either contains the sign-in error that came from ARC or it may
-  // indicate that ARC stopped prematurely and provisioning could not finish
-  // successfully.
-  void OnProvisioningFinished(
-      ProvisioningResult result,
-      absl::variant<mojom::ArcSignInErrorPtr, ArcStopReason> error);
+  // not), this is called with its status. On success, is_success() of
+  // |result| returns true, otherwise ArcSignInResult can be retrieved from
+  // get() if sign-in result came from ARC or is_stopped()
+  // will indicate that ARC stopped prematurely and provisioning could
+  // not finish successfully. is_timedout() indicates that operation timed
+  // out.
+  void OnProvisioningFinished(const ArcProvisioningResult& result);
 
   // A helper function that calls ArcSessionRunner's SetUserInfo.
   void SetUserInfo();
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
index 28e91eb..b9f90bcd 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
@@ -26,6 +26,7 @@
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_oobe_negotiator.h"
 #include "chrome/browser/chromeos/arc/session/arc_play_store_enabled_preference_handler.h"
+#include "chrome/browser/chromeos/arc/session/arc_provisioning_result.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager_observer.h"
 #include "chrome/browser/chromeos/arc/test/arc_data_removed_waiter.h"
@@ -452,8 +453,12 @@
 
   EXPECT_FALSE(start_handler.was_called());
 
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
+
   EXPECT_TRUE(start_handler.was_called());
 
   arc_session_manager()->Shutdown();
@@ -474,8 +479,12 @@
   ArcInitialStartHandler start_handler(arc_session_manager());
 
   arc_session_manager()->RequestEnable();
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
+
   EXPECT_FALSE(start_handler.was_called());
 
   arc_session_manager()->Shutdown();
@@ -601,8 +610,12 @@
   EXPECT_FALSE(arc_session_manager()->IsPlaystoreLaunchRequestedForTesting());
 
   // Emulate successful provisioning.
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
+
   EXPECT_TRUE(prefs->GetBoolean(prefs::kArcSignedIn));
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
   EXPECT_TRUE(arc_session_manager()->IsPlaystoreLaunchRequestedForTesting());
@@ -625,8 +638,12 @@
   // Second start, no fetching code is expected.
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
   EXPECT_FALSE(arc_session_manager()->IsPlaystoreLaunchRequestedForTesting());
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
+
   // Completing the provisioning resets this flag.
   EXPECT_FALSE(prefs->GetBoolean(prefs::kArcProvisioningInitiatedFromOobe));
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
@@ -673,8 +690,12 @@
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
 
   // Report failure.
+  arc::mojom::ArcSignInResultPtr result = arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGmsError(
+          arc::mojom::GMSError::GMS_NETWORK_ERROR));
   arc_session_manager()->OnProvisioningFinished(
-      ProvisioningResult::GMS_NETWORK_ERROR, {});
+      ArcProvisioningResult(std::move(result)));
+
   // On error, UI to send feedback is showing. In that case,
   // the ARC is still necessary to run on background for gathering the logs.
   EXPECT_TRUE(prefs->GetBoolean(prefs::kArcSignedIn));
@@ -806,8 +827,11 @@
             arc_session_manager()->state());
   arc_session_manager()->OnTermsOfServiceNegotiatedForTesting(true);
   arc_session_manager()->StartArcForTesting();
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
 
   EXPECT_EQ(
       static_cast<int>(ArcSupervisionTransition::NO_TRANSITION),
@@ -842,8 +866,11 @@
             arc_session_manager()->state());
   arc_session_manager()->OnTermsOfServiceNegotiatedForTesting(true);
   arc_session_manager()->StartArcForTesting();
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
 
   EXPECT_EQ(ArcSupervisionTransition::NO_TRANSITION,
             arc::GetSupervisionTransition(profile()));
@@ -869,14 +896,20 @@
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
 
   // Report some failure that does not stop the bridge.
+  arc::mojom::ArcSignInResultPtr result = arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGmsError(
+          arc::mojom::GMSError::GMS_SIGN_IN_FAILED));
   arc_session_manager()->OnProvisioningFinished(
-      ProvisioningResult::GMS_SIGN_IN_FAILED, {});
+      ArcProvisioningResult(std::move(result)));
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
 
   // Try to send another error that stops the bridge if sent first. It should
   // be ignored.
+  result = arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGeneralError(
+          arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR));
   arc_session_manager()->OnProvisioningFinished(
-      ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR, {});
+      ArcProvisioningResult(std::move(result)));
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
 
   arc_session_manager()->Shutdown();
@@ -896,8 +929,12 @@
             arc_session_manager()->state());
   arc_session_manager()->OnTermsOfServiceNegotiatedForTesting(true);
   arc_session_manager()->StartArcForTesting();
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
+
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
   EXPECT_FALSE(arc_session_manager()->is_directly_started());
   arc_session_manager()->Shutdown();
@@ -936,8 +973,12 @@
             arc_session_manager()->state());
   arc_session_manager()->OnTermsOfServiceNegotiatedForTesting(true);
   arc_session_manager()->StartArcForTesting();
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
+
   EXPECT_FALSE(arc_session_manager()->is_directly_started());
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
   EXPECT_FALSE(arc_session_manager()->is_directly_started());
@@ -1146,8 +1187,8 @@
 TEST_P(ProvisioningErrorDisplayTest, ArcStopped) {
   ShowErrorObserver observer(arc_session_manager());
 
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::ARC_STOPPED,
-                                                GetParam().stop_reason);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(GetParam().stop_reason));
 
   ASSERT_TRUE(observer.error_info());
   EXPECT_EQ(GetParam().error, observer.error_info().value().error);
@@ -1307,8 +1348,11 @@
 
   arc_session_manager()->StartArcForTesting();
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
 
   // Play Store app is launched unless the Terms screen was suppressed or Tos is
   // accepted during OOBE.
@@ -1386,8 +1430,11 @@
       base::BindRepeating([](bool* terminated) { *terminated = true; },
                           &terminated));
 
+  arc::mojom::ArcSignInResultPtr result = arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGeneralError(
+          arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR));
   arc_session_manager()->OnProvisioningFinished(
-      ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR, {});
+      ArcProvisioningResult(std::move(result)));
   EXPECT_TRUE(terminated);
 }
 
@@ -1422,8 +1469,11 @@
       base::BindRepeating([](bool* terminated) { *terminated = true; },
                           &terminated));
 
+  arc::mojom::ArcSignInResultPtr result = arc::mojom::ArcSignInResult::NewError(
+      arc::mojom::ArcSignInError::NewGeneralError(
+          arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR));
   arc_session_manager()->OnProvisioningFinished(
-      ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR, {});
+      ArcProvisioningResult(std::move(result)));
   EXPECT_FALSE(terminated);
   EXPECT_EQ(ArcSessionManager::State::STOPPED, arc_session_manager()->state());
 }
@@ -1579,108 +1629,60 @@
 
   Negotiation negotiation;
 
-  // Provisioning error to test.
-  ProvisioningResult result;
-
   // Whether ARC++ container is alive on error.
   bool container_alive;
 
   // Whether data is removed on error.
   bool data_removed;
 
-  absl::variant<absl::monostate,
+  absl::variant<arc::mojom::GeneralSignInError,
+                arc::mojom::GMSError,
+                arc::mojom::DeviceCheckInError,
                 arc::mojom::CloudProvisionFlowError,
-                ArcStopReason>
+                ArcStopReason,
+                OverallSignInTimeout>
       error;
 };
 
-constexpr ArcSessionRetryTestParam kRetryTestCases[] = {
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::UNKNOWN_ERROR,
-     true,
-     true,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::GMS_NETWORK_ERROR,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::GMS_SERVICE_UNAVAILABLE,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::GMS_BAD_AUTHENTICATION,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::DEVICE_CHECK_IN_FAILED,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::SKIPPED,
-     ProvisioningResult::CLOUD_PROVISION_FLOW_ERROR, true, true,
+ArcSessionRetryTestParam kRetryTestCases[] = {
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, true,
+     arc::mojom::GeneralSignInError::UNKNOWN_ERROR},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GMSError::GMS_NETWORK_ERROR},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GMSError::GMS_SERVICE_UNAVAILABLE},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GMSError::GMS_BAD_AUTHENTICATION},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::DeviceCheckInError::DEVICE_CHECK_IN_FAILED},
+    {ArcSessionRetryTestParam::Negotiation::SKIPPED, true, true,
      arc::mojom::CloudProvisionFlowError::ERROR_OTHER},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::MOJO_VERSION_MISMATCH,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::PROVISIONING_TIMEOUT,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::DEVICE_CHECK_IN_TIMEOUT,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::DEVICE_CHECK_IN_INTERNAL_ERROR,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::GMS_SIGN_IN_FAILED,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::GMS_SIGN_IN_TIMEOUT,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::GMS_SIGN_IN_INTERNAL_ERROR,
-     true,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::SKIPPED,
-     ProvisioningResult::CLOUD_PROVISION_FLOW_ERROR, true, true,
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GeneralSignInError::MOJO_VERSION_MISMATCH},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GeneralSignInError::PROVISIONING_TIMEOUT},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::DeviceCheckInError::DEVICE_CHECK_IN_TIMEOUT},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::DeviceCheckInError::DEVICE_CHECK_IN_INTERNAL_ERROR},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GMSError::GMS_SIGN_IN_FAILED},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GMSError::GMS_SIGN_IN_TIMEOUT},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GMSError::GMS_SIGN_IN_INTERNAL_ERROR},
+    {ArcSessionRetryTestParam::Negotiation::SKIPPED, true, true,
      arc::mojom::CloudProvisionFlowError::ERROR_TIMEOUT},
-    {ArcSessionRetryTestParam::Negotiation::SKIPPED,
-     ProvisioningResult::CLOUD_PROVISION_FLOW_ERROR, true, true,
+    {ArcSessionRetryTestParam::Negotiation::SKIPPED, true, true,
      arc::mojom::CloudProvisionFlowError::ERROR_JSON},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::ARC_STOPPED, false, false, ArcStopReason::CRASH},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::OVERALL_SIGN_IN_TIMEOUT,
-     true,
-     true,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR,
-     false,
-     false,
-     {}},
-    {ArcSessionRetryTestParam::Negotiation::REQUIRED,
-     ProvisioningResult::NO_NETWORK_CONNECTION,
-     true,
-     false,
-     {}},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, false, false,
+     ArcStopReason::CRASH},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, true,
+     OverallSignInTimeout{}},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, false, false,
+     arc::mojom::GeneralSignInError::CHROME_SERVER_COMMUNICATION_ERROR},
+    {ArcSessionRetryTestParam::Negotiation::REQUIRED, true, false,
+     arc::mojom::GeneralSignInError::NO_NETWORK_CONNECTION},
 };
 
 class ArcSessionRetryTest
@@ -1750,21 +1752,39 @@
   arc_session_manager()->StartArcForTesting();
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
 
-  absl::variant<absl::monostate, arc::mojom::CloudProvisionFlowError,
-                ArcStopReason>
+  absl::variant<arc::mojom::GeneralSignInError, arc::mojom::GMSError,
+                arc::mojom::DeviceCheckInError,
+                arc::mojom::CloudProvisionFlowError, ArcStopReason,
+                OverallSignInTimeout>
       error = std::move(GetParam().error);
-  absl::variant<mojom::ArcSignInErrorPtr, ArcStopReason> param;
-  if (absl::holds_alternative<arc::mojom::CloudProvisionFlowError>(error)) {
-    param = arc::mojom::ArcSignInError::NewCloudProvisionFlowError(
-        absl::get<arc::mojom::CloudProvisionFlowError>(error));
-  } else if (absl::holds_alternative<ArcStopReason>(error)) {
-    param = absl::get<ArcStopReason>(error);
-  } else if (!absl::holds_alternative<absl::monostate>(error)) {
-    FAIL() << "Unexpected value";
-  }
 
-  arc_session_manager()->OnProvisioningFinished(GetParam().result,
-                                                std::move(param));
+  if (absl::holds_alternative<arc::mojom::CloudProvisionFlowError>(error)) {
+    ArcProvisioningResult result(arc::mojom::ArcSignInResult::NewError(
+        arc::mojom::ArcSignInError::NewCloudProvisionFlowError(
+            absl::get<arc::mojom::CloudProvisionFlowError>(error))));
+    arc_session_manager()->OnProvisioningFinished(result);
+  } else if (absl::holds_alternative<ArcStopReason>(error)) {
+    ArcProvisioningResult result(absl::get<ArcStopReason>(error));
+    arc_session_manager()->OnProvisioningFinished(result);
+  } else if (absl::holds_alternative<arc::mojom::GeneralSignInError>(error)) {
+    ArcProvisioningResult result(arc::mojom::ArcSignInResult::NewError(
+        arc::mojom::ArcSignInError::NewGeneralError(
+            absl::get<arc::mojom::GeneralSignInError>(error))));
+    arc_session_manager()->OnProvisioningFinished(result);
+  } else if (absl::holds_alternative<arc::mojom::GMSError>(error)) {
+    ArcProvisioningResult result(arc::mojom::ArcSignInResult::NewError(
+        arc::mojom::ArcSignInError::NewGmsError(
+            absl::get<arc::mojom::GMSError>(error))));
+    arc_session_manager()->OnProvisioningFinished(result);
+  } else if (absl::holds_alternative<arc::mojom::DeviceCheckInError>(error)) {
+    ArcProvisioningResult result(arc::mojom::ArcSignInResult::NewError(
+        arc::mojom::ArcSignInError::NewCheckinError(
+            absl::get<arc::mojom::DeviceCheckInError>(error))));
+    arc_session_manager()->OnProvisioningFinished(result);
+  } else if (absl::holds_alternative<OverallSignInTimeout>(error)) {
+    arc_session_manager()->OnProvisioningFinished(
+        ArcProvisioningResult(OverallSignInTimeout{}));
+  }
 
   // In case of permanent error data removal request is scheduled.
   EXPECT_EQ(GetParam().data_removed,
@@ -1792,8 +1812,11 @@
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
 
   // Successful retry keeps ARC++ container running.
-  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS,
-                                                {});
+  arc::mojom::ArcSignInResultPtr result =
+      arc::mojom::ArcSignInResult::NewSuccess(
+          arc::mojom::ArcSignInSuccess::SUCCESS);
+  arc_session_manager()->OnProvisioningFinished(
+      ArcProvisioningResult(std::move(result)));
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
 
   arc_session_manager()->Shutdown();
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc
index 9b7b9923..ec7b642 100644
--- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc
+++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h"
 
+#include <string>
+
 #include "base/callback_helpers.h"
 #include "base/notreached.h"
 #include "base/optional.h"
@@ -90,19 +92,27 @@
 //===================== CertProfile ============================================
 
 CertProfile::CertProfile(CertProfileId profile_id,
+                         std::string name,
                          std::string policy_version,
                          bool is_va_enabled,
                          base::TimeDelta renewal_period)
     : profile_id(profile_id),
-      policy_version(policy_version),
+      name(std::move(name)),
+      policy_version(std::move(policy_version)),
       is_va_enabled(is_va_enabled),
       renewal_period(renewal_period) {}
 
+CertProfile::CertProfile(const CertProfile& other) = default;
+
+CertProfile::CertProfile() = default;
+CertProfile::~CertProfile() = default;
+
 base::Optional<CertProfile> CertProfile::MakeFromValue(
     const base::Value& value) {
-  static_assert(kVersion == 4, "This function should be updated");
+  static_assert(kVersion == 5, "This function should be updated");
 
   const std::string* id = value.FindStringKey(kCertProfileIdKey);
+  const std::string* name = value.FindStringKey(kCertProfileNameKey);
   const std::string* policy_version =
       value.FindStringKey(kCertProfilePolicyVersionKey);
   base::Optional<bool> is_va_enabled =
@@ -116,6 +126,7 @@
 
   CertProfile result;
   result.profile_id = *id;
+  result.name = name ? *name : std::string();
   result.policy_version = *policy_version;
   result.is_va_enabled = is_va_enabled.value_or(true);
   result.renewal_period =
@@ -125,8 +136,8 @@
 }
 
 bool CertProfile::operator==(const CertProfile& other) const {
-  static_assert(kVersion == 4, "This function should be updated");
-  return ((profile_id == other.profile_id) &&
+  static_assert(kVersion == 5, "This function should be updated");
+  return ((profile_id == other.profile_id) && (name == other.name) &&
           (policy_version == other.policy_version) &&
           (is_va_enabled == other.is_va_enabled) &&
           (renewal_period == other.renewal_period));
@@ -138,8 +149,8 @@
 
 bool CertProfileComparator::operator()(const CertProfile& a,
                                        const CertProfile& b) const {
-  static_assert(CertProfile::kVersion == 4, "This function should be updated");
-  return ((a.profile_id < b.profile_id) ||
+  static_assert(CertProfile::kVersion == 5, "This function should be updated");
+  return ((a.profile_id < b.profile_id) || (a.name < b.name) ||
           (a.policy_version < b.policy_version) ||
           (a.is_va_enabled < b.is_va_enabled) ||
           (a.renewal_period < b.renewal_period));
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h
index dd66bf7..ef9b8a9 100644
--- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h
+++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h
@@ -75,6 +75,7 @@
 // with definitions of RequiredClientCertificateForDevice and
 // RequiredClientCertificateForUser policies in policy_templates.json file.
 const char kCertProfileIdKey[] = "cert_profile_id";
+const char kCertProfileNameKey[] = "name";
 const char kCertProfileRenewalPeroidSec[] = "renewal_period_seconds";
 const char kCertProfilePolicyVersionKey[] = "policy_version";
 const char kCertProfileIsVaEnabledKey[] = "enable_remote_attestation_check";
@@ -82,14 +83,19 @@
 struct CertProfile {
   static base::Optional<CertProfile> MakeFromValue(const base::Value& value);
 
-  CertProfile() = default;
+  CertProfile();
   // For tests.
   CertProfile(CertProfileId profile_id,
+              std::string name,
               std::string policy_version,
               bool is_va_enabled,
               base::TimeDelta renewal_period);
+  CertProfile(const CertProfile& other);
+  ~CertProfile();
 
   CertProfileId profile_id;
+  // Human-readable name (UTF-8).
+  std::string name;
   std::string policy_version;
   bool is_va_enabled = true;
   // Default renewal period 0 means that a certificate will be renewed only
@@ -99,7 +105,7 @@
   // IMPORTANT:
   // Increment this when you add/change any member in CertProfile (and update
   // all functions that fail to compile because of it).
-  static constexpr int kVersion = 4;
+  static constexpr int kVersion = 5;
 
   bool operator==(const CertProfile& other) const;
   bool operator!=(const CertProfile& other) const;
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc
index 7222a982..6b71039 100644
--- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc
+++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc
@@ -44,6 +44,7 @@
 
 constexpr char kWifiServiceGuid[] = "wifi_guid";
 constexpr char kCertProfileId[] = "cert_profile_id_1";
+constexpr char kCertProfileName[] = "Certificate Profile 1";
 constexpr char kCertProfileVersion[] = "cert_profile_version_1";
 constexpr TimeDelta kCertProfileRenewalPeriod = TimeDelta::FromSeconds(0);
 
@@ -209,7 +210,8 @@
   VerifyDeleteKeysByPrefixCalledOnce(kCertScope);
 
   // One worker will be created on prefs update.
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   MockCertProvisioningWorker* worker =
       mock_factory_.ExpectCreateReturnMock(kCertScope, cert_profile);
@@ -263,7 +265,8 @@
   VerifyDeleteKeysByPrefixCalledOnce(kCertScope);
 
   // One worker will be created on prefs update.
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   MockCertProvisioningWorker* worker =
       mock_factory_.ExpectCreateReturnMock(kCertScope, cert_profile);
@@ -302,7 +305,8 @@
 TEST_F(CertProvisioningSchedulerTest, InitialAndDailyUpdates) {
   const CertScope kCertScope = CertScope::kUser;
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   // Add 1 certificate profile to the policy (the values are the same as
@@ -378,16 +382,22 @@
 
   // New workers will be created on prefs update.
   const char kCertProfileId0[] = "cert_profile_id_0";
+  const char kCertProfileName0[] = "Certificate Profile 0";
   const char kCertProfileVersion0[] = "cert_profile_version_0";
-  CertProfile cert_profile0(kCertProfileId0, kCertProfileVersion0,
+  CertProfile cert_profile0(kCertProfileId0, kCertProfileName0,
+                            kCertProfileVersion0,
                             /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   const char kCertProfileId1[] = "cert_profile_id_1";
+  const char kCertProfileName1[] = "Certificate Profile 1";
   const char kCertProfileVersion1[] = "cert_profile_version_1";
-  CertProfile cert_profile1(kCertProfileId1, kCertProfileVersion1,
+  CertProfile cert_profile1(kCertProfileId1, kCertProfileName1,
+                            kCertProfileVersion1,
                             /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   const char kCertProfileId2[] = "cert_profile_id_2";
+  const char kCertProfileName2[] = "Certificate Profile 2";
   const char kCertProfileVersion2[] = "cert_profile_version_2";
-  CertProfile cert_profile2(kCertProfileId2, kCertProfileVersion2,
+  CertProfile cert_profile2(kCertProfileId2, kCertProfileName2,
+                            kCertProfileVersion2,
                             /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   MockCertProvisioningWorker* worker0 =
       mock_factory_.ExpectCreateReturnMock(kCertScope, cert_profile0);
@@ -483,7 +493,8 @@
 TEST_F(CertProvisioningSchedulerTest, DeserializeWorkers) {
   const CertScope kCertScope = CertScope::kUser;
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   // Add 1 certificate profile to the policy (the values are the same as
@@ -548,9 +559,9 @@
   // From CertProvisioningScheduler::CleanVaKeysIfIdle.
   VerifyDeleteKeysByPrefixCalledOnce(kCertScope);
 
-  CertProfile cert_profile_v1(kCertProfileId, kCertProfileVersion1,
-                              /*is_va_enabled=*/true,
-                              kCertProfileRenewalPeriod);
+  CertProfile cert_profile_v1(
+      kCertProfileId, kCertProfileName, kCertProfileVersion1,
+      /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockCertProvisioningWorker* worker =
       mock_factory_.ExpectCreateReturnMock(kCertScope, cert_profile_v1);
@@ -597,9 +608,9 @@
   EXPECT_TRUE(scheduler.GetFailedCertProfileIds().empty());
 
   // Add a new worker to the factory.
-  CertProfile cert_profile_v2(kCertProfileId, kCertProfileVersion2,
-                              /*is_va_enabled=*/true,
-                              kCertProfileRenewalPeriod);
+  CertProfile cert_profile_v2(
+      kCertProfileId, kCertProfileName, kCertProfileVersion2,
+      /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   worker = mock_factory_.ExpectCreateReturnMock(kCertScope, cert_profile_v2);
   worker->SetExpectations(/*do_step_times=*/AtLeast(1), /*is_waiting=*/false,
                           cert_profile_v2);
@@ -644,7 +655,8 @@
   const CertScope kCertScope = CertScope::kDevice;
   SetWifiNetworkState(shill::kStateIdle);
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   // Add 1 certificate profile to the policy (the values are the same as
   // in |cert_profile|).
@@ -681,7 +693,8 @@
 TEST_F(CertProvisioningSchedulerTest, DeleteWorkerWithoutPolicy) {
   const CertScope kCertScope = CertScope::kDevice;
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   // Add 1 certificate profile to the policy (the values are the same as
   // in |cert_profile|).
@@ -748,7 +761,8 @@
       ->ClearDeleteKeysHistory();
 
   {
-    CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+    CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                             kCertProfileVersion,
                              /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
     // Add 1 serialized worker for the profile (the values are the same as
@@ -799,7 +813,8 @@
       network_state_test_helper_.network_state_handler(),
       MakeFakeInvalidationFactory());
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   FastForwardBy(TimeDelta::FromSeconds(1));
@@ -886,7 +901,8 @@
   // 1 day == 86400 seconds.
   const TimeDelta kRenewalPeriod = TimeDelta::FromDays(1);
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kRenewalPeriod);
 
   const Time t1 = Time::Now() - TimeDelta::FromDays(1);
@@ -959,7 +975,8 @@
   // Same as in the policy.
   const char kCertProfileId[] = "cert_profile_id_1";
   const char kCertProfileVersion[] = "cert_profile_version_1";
-  CertProfile cert_profile{kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile{kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod};
 
   MockCertProvisioningWorker* worker =
@@ -1006,12 +1023,16 @@
   // Two new workers will be created on prefs update.
   // Expect a state change notification for this.
   const char kCertProfileId0[] = "cert_profile_id_0";
+  const char kCertProfileName0[] = "Certificate Profile 0";
   const char kCertProfileVersion0[] = "cert_profile_version_0";
-  CertProfile cert_profile0(kCertProfileId0, kCertProfileVersion0,
+  CertProfile cert_profile0(kCertProfileId0, kCertProfileName0,
+                            kCertProfileVersion0,
                             /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   const char kCertProfileId1[] = "cert_profile_id_1";
+  const char kCertProfileName1[] = "Certificate Profile 1";
   const char kCertProfileVersion1[] = "cert_profile_version_1";
-  CertProfile cert_profile1(kCertProfileId1, kCertProfileVersion1,
+  CertProfile cert_profile1(kCertProfileId1, kCertProfileName1,
+                            kCertProfileVersion1,
                             /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockCertProvisioningWorker* worker0 =
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_serializer.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_serializer.cc
index 4b0b6f45..99c4fa77 100644
--- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_serializer.cc
+++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_serializer.cc
@@ -24,6 +24,7 @@
 constexpr char kKeyNameInvalidationTopic[] = "invalidation_topic";
 
 constexpr char kKeyNameCertProfileId[] = "profile_id";
+constexpr char kKeyNameCertProfileName[] = "name";
 constexpr char kKeyNameCertProfileVersion[] = "policy_version";
 constexpr char kKeyNameCertProfileVaEnabled[] = "va_enabled";
 constexpr char kKeyNameCertProfileRenewalPeriod[] = "renewal_period";
@@ -82,10 +83,11 @@
 }
 
 base::Value SerializeCertProfile(const CertProfile& profile) {
-  static_assert(CertProfile::kVersion == 4, "This function should be updated");
+  static_assert(CertProfile::kVersion == 5, "This function should be updated");
 
   base::Value result(base::Value::Type::DICTIONARY);
   result.SetStringKey(kKeyNameCertProfileId, profile.profile_id);
+  result.SetStringKey(kKeyNameCertProfileName, profile.name);
   result.SetStringKey(kKeyNameCertProfileVersion, profile.policy_version);
   result.SetBoolKey(kKeyNameCertProfileVaEnabled, profile.is_va_enabled);
 
@@ -100,7 +102,7 @@
 bool DeserializeCertProfile(const base::Value& parent_value,
                             const char* value_name,
                             CertProfile* dst) {
-  static_assert(CertProfile::kVersion == 4, "This function should be updated");
+  static_assert(CertProfile::kVersion == 5, "This function should be updated");
 
   const base::Value* serialized_profile =
       parent_value.FindKeyOfType(value_name, base::Value::Type::DICTIONARY);
@@ -113,6 +115,9 @@
   is_ok = is_ok &&
           DeserializeStringValue(*serialized_profile, kKeyNameCertProfileId,
                                  &(dst->profile_id));
+  is_ok =
+      is_ok && DeserializeStringValue(*serialized_profile,
+                                      kKeyNameCertProfileName, &(dst->name));
   is_ok = is_ok && DeserializeStringValue(*serialized_profile,
                                           kKeyNameCertProfileVersion,
                                           &(dst->policy_version));
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc
index 6ae13c6..14202f6 100644
--- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc
+++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc
@@ -90,6 +90,7 @@
     "TLaN7pwQx68PK5pd/lv58B7jjxCIAai0BX1rV6bl/Am3EukhTSuIcQiTr5c1G4E6bKwIDAQAB";
 
 constexpr char kCertProfileId[] = "cert_profile_1";
+constexpr char kCertProfileName[] = "Certificate Profile 1";
 constexpr char kCertProfileVersion[] = "cert_profile_version_1";
 constexpr base::TimeDelta kCertProfileRenewalPeriod =
     base::TimeDelta::FromSeconds(0);
@@ -468,7 +469,8 @@
 TEST_F(CertProvisioningWorkerTest, Success) {
   base::HistogramTester histogram_tester;
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -559,7 +561,8 @@
 // Checks that the worker makes all necessary requests to other modules during
 // success scenario when VA challenge is not received.
 TEST_F(CertProvisioningWorkerTest, NoVaSuccess) {
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/false, kCertProfileRenewalPeriod);
 
   CertProvisioningWorkerImpl worker(
@@ -619,7 +622,8 @@
 // Checks that when the server returns try_again_later field, the worker will
 // retry a request when it asked to continue the provisioning.
 TEST_F(CertProvisioningWorkerTest, TryLaterManualRetry) {
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -730,7 +734,8 @@
 // Checks that when the server returns try_again_later field, the worker will
 // automatically retry a request after some time.
 TEST_F(CertProvisioningWorkerTest, TryLaterWait) {
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -849,7 +854,8 @@
 // Checks that when the server returns try_again_later field, the worker will
 // retry when the invalidation is triggered.
 TEST_F(CertProvisioningWorkerTest, InvalidationRespected) {
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -972,7 +978,8 @@
 // error state and stop the provisioning.
 TEST_F(CertProvisioningWorkerTest, StatusErrorHandling) {
   const CertScope kCertScope = CertScope::kUser;
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -1015,7 +1022,8 @@
   const CertScope kCertScope = CertScope::kUser;
   base::HistogramTester histogram_tester;
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -1059,7 +1067,8 @@
 
 TEST_F(CertProvisioningWorkerTest, InconsistentDataErrorHandling) {
   const CertScope kCertScope = CertScope::kUser;
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -1098,7 +1107,8 @@
 // Checks that when the server returns TEMPORARY_UNAVAILABLE status code, the
 // worker will automatically retry a request using exponential backoff strategy.
 TEST_F(CertProvisioningWorkerTest, BackoffStrategy) {
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -1165,7 +1175,8 @@
 TEST_F(CertProvisioningWorkerTest, RemoveRegisteredKey) {
   base::HistogramTester histogram_tester;
 
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
   MockCertProvisioningInvalidator* mock_invalidator = nullptr;
@@ -1262,7 +1273,8 @@
 
 TEST_F(CertProvisioningWorkerTest, SerializationSuccess) {
   const base::TimeDelta kRenewalPeriod = base::TimeDelta::FromSeconds(1200300);
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kRenewalPeriod);
   const CertScope kCertScope = CertScope::kUser;
 
@@ -1300,6 +1312,7 @@
           "cert_profile_1": {
             "cert_profile": {
               "policy_version": "cert_profile_version_1",
+              "name": "Certificate Profile 1",
               "profile_id": "cert_profile_1",
               "va_enabled": true,
               "renewal_period": 1200300
@@ -1382,6 +1395,7 @@
           "cert_profile_1": {
             "cert_profile": {
               "policy_version": "cert_profile_version_1",
+              "name": "Certificate Profile 1",
               "profile_id": "cert_profile_1",
               "va_enabled": true,
               "renewal_period": 1200300
@@ -1449,7 +1463,8 @@
 
 TEST_F(CertProvisioningWorkerTest, SerializationOnFailure) {
   const CertScope kCertScope = CertScope::kUser;
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -1480,6 +1495,7 @@
           "cert_profile_1": {
             "cert_profile": {
               "policy_version": "cert_profile_version_1",
+              "name": "Certificate Profile 1",
               "profile_id": "cert_profile_1",
               "va_enabled": true
             },
@@ -1510,7 +1526,8 @@
 
 TEST_F(CertProvisioningWorkerTest, InformationalGetters) {
   const CertScope kCertScope = CertScope::kUser;
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   MockTpmChallengeKeySubtle* mock_tpm_challenge_key = PrepareTpmChallengeKey();
@@ -1564,7 +1581,8 @@
   base::HistogramTester histogram_tester;
 
   const CertScope kCertScope = CertScope::kDevice;
-  CertProfile cert_profile(kCertProfileId, kCertProfileVersion,
+  CertProfile cert_profile(kCertProfileId, kCertProfileName,
+                           kCertProfileVersion,
                            /*is_va_enabled=*/true, kCertProfileRenewalPeriod);
 
   EXPECT_CALL(state_change_callback_observer_, StateChangeCallback)
@@ -1597,6 +1615,7 @@
           "cert_profile_1": {
             "cert_profile": {
               "policy_version": "cert_profile_version_1",
+              "name": "Certificate Profile 1",
               "profile_id": "cert_profile_1",
               "va_enabled": true
             },
diff --git a/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc b/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc
index c64b4eb0..9a5a8fa 100644
--- a/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc
+++ b/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc
@@ -77,6 +77,13 @@
                      weak_ptr_factory_.GetWeakPtr()));
   exported_object->ExportMethod(
       kChromeFeaturesServiceInterface,
+      kChromeFeaturesServiceIsCrostiniEnabledMethod,
+      base::BindRepeating(&ChromeFeaturesServiceProvider::IsCrostiniEnabled,
+                          weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&ChromeFeaturesServiceProvider::OnExported,
+                     weak_ptr_factory_.GetWeakPtr()));
+  exported_object->ExportMethod(
+      kChromeFeaturesServiceInterface,
       kChromeFeaturesServiceIsPluginVmEnabledMethod,
       base::BindRepeating(&ChromeFeaturesServiceProvider::IsPluginVmEnabled,
                           weak_ptr_factory_.GetWeakPtr()),
@@ -173,6 +180,19 @@
                base::FeatureList::IsEnabled(**it));
 }
 
+void ChromeFeaturesServiceProvider::IsCrostiniEnabled(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  Profile* profile = GetSenderProfile(method_call, &response_sender);
+  if (!profile)
+    return;
+
+  SendResponse(method_call, std::move(response_sender),
+               profile
+                   ? crostini::CrostiniFeatures::Get()->IsAllowedNow(profile)
+                   : false);
+}
+
 void ChromeFeaturesServiceProvider::IsCryptohomeDistributedModelEnabled(
     dbus::MethodCall* method_call,
     dbus::ExportedObject::ResponseSender response_sender) {
diff --git a/chrome/browser/chromeos/dbus/chrome_features_service_provider.h b/chrome/browser/chromeos/dbus/chrome_features_service_provider.h
index 6b01bcc..8a54dfd6e6 100644
--- a/chrome/browser/chromeos/dbus/chrome_features_service_provider.h
+++ b/chrome/browser/chromeos/dbus/chrome_features_service_provider.h
@@ -20,6 +20,16 @@
 
 // This class exports D-Bus methods for querying Chrome Features enablement.
 //
+// IsCrostiniEnabled:
+// % dbus-send --system --type=method_call --print-reply
+//     --dest=org.chromium.ChromeFeaturesService
+//     /org/chromium/ChromeFeaturesService
+//     org.chromium.ChromeFeaturesServiceInterface.IsCrostiniEnabled
+//     string:"|user id hash|"
+//
+// % (If |user id hash| is set correctly, returns true if Crostini is enabled
+//    for the user identified by the hash, and false otherwise)
+//
 // IsPluginVmEnabled:
 // % dbus-send --system --type=method_call --print-reply
 //     --dest=org.chromium.ChromeFeaturesService
@@ -44,7 +54,8 @@
   void Start(scoped_refptr<dbus::ExportedObject> exported_object) override;
 
  private:
-  // Called from ExportedObject when a D-Bus method is exported.
+  // Called from ExportedObject when IsCrostiniEnabled() is exported as a D-Bus
+  // method or failed to be exported.
   void OnExported(const std::string& interface_name,
                   const std::string& method_name,
                   bool success);
@@ -52,6 +63,8 @@
   // Called on UI thread in response to a D-Bus request.
   void IsFeatureEnabled(dbus::MethodCall* method_call,
                         dbus::ExportedObject::ResponseSender response_sender);
+  void IsCrostiniEnabled(dbus::MethodCall* method_call,
+                         dbus::ExportedObject::ResponseSender response_sender);
   void IsCryptohomeDistributedModelEnabled(
       dbus::MethodCall* method_call,
       dbus::ExportedObject::ResponseSender response_sender);
diff --git a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
index 4300f79..b9d028d 100644
--- a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
+++ b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
@@ -349,6 +349,12 @@
         return false;
       }
 
+      if (flags & FLAGS_LAZY_FILE_HANDLER) {
+        // Ensures the file handler extension's background page closes in a
+        // timely manner to avoid test timeouts.
+        extensions::ProcessManager::SetEventPageIdleTimeForTesting(1);
+      }
+
       BackgroundObserver page_complete;
       const Extension* file_handler =
           LoadExtension(test_data_dir_.AppendASCII(filehandler_path));
@@ -808,9 +814,8 @@
       FLAGS_USE_FILE_HANDLER)) << message_;
 }
 
-// Failing: http://crbug.com/1150689
 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest,
-                       DISABLED_FileBrowserHandlersLazy) {
+                       FileBrowserHandlersLazy) {
   EXPECT_TRUE(RunFileSystemExtensionApiTest(
       "file_browser/handler_test_runner",
       FILE_PATH_LITERAL("manifest.json"),
diff --git a/chrome/browser/chromeos/file_system_provider/queue.cc b/chrome/browser/chromeos/file_system_provider/queue.cc
index 321d482..bb5b1f6 100644
--- a/chrome/browser/chromeos/file_system_provider/queue.cc
+++ b/chrome/browser/chromeos/file_system_provider/queue.cc
@@ -65,15 +65,16 @@
 
   CHECK_GT(max_in_parallel_, executed_.size());
   Task task = std::move(pending_.front());
+  const size_t token = task.token;
   pending_.pop_front();
 
   auto callback = std::move(task.callback);
-  executed_[task.token] = std::move(task);
+  executed_[token] = std::move(task);
   AbortCallback abort_callback = std::move(callback).Run();
 
   // It may happen that the task is completed and removed synchronously. Hence,
   // we need to check if the task is still in the executed collection.
-  const auto executed_task_it = executed_.find(task.token);
+  const auto executed_task_it = executed_.find(token);
   if (executed_task_it != executed_.end())
     executed_task_it->second.abort_callback = std::move(abort_callback);
 }
diff --git a/chrome/browser/chromeos/input_method/autocorrect_manager.cc b/chrome/browser/chromeos/input_method/autocorrect_manager.cc
index 519471e..e475b71 100644
--- a/chrome/browser/chromeos/input_method/autocorrect_manager.cc
+++ b/chrome/browser/chromeos/input_method/autocorrect_manager.cc
@@ -39,9 +39,8 @@
     SuggestionHandlerInterface* suggestion_handler)
     : suggestion_handler_(suggestion_handler) {}
 
-void AutocorrectManager::MarkAutocorrectRange(
-    gfx::Range autocorrect_range,
-    const std::string& original_text) {
+void AutocorrectManager::HandleAutocorrect(gfx::Range autocorrect_range,
+                                           const std::string& original_text) {
   // TODO(crbug/1111135): call setAutocorrectTime() (for metrics)
   // TODO(crbug/1111135): record metric (coverage)
   ui::IMEInputContextHandlerInterface* input_context =
diff --git a/chrome/browser/chromeos/input_method/autocorrect_manager.h b/chrome/browser/chromeos/input_method/autocorrect_manager.h
index ba3c420..8c284b0b 100644
--- a/chrome/browser/chromeos/input_method/autocorrect_manager.h
+++ b/chrome/browser/chromeos/input_method/autocorrect_manager.h
@@ -27,8 +27,8 @@
 
   // Mark `autocorrect_range` with an underline. `autocorrect_range` is based on
   // the current text contents.
-  void MarkAutocorrectRange(gfx::Range autocorrect_range,
-                            const std::string& original_text);
+  void HandleAutocorrect(gfx::Range autocorrect_range,
+                         const std::string& original_text);
 
   // To hide the underline after enough keypresses, this class intercepts
   // keystrokes. Returns whether the keypress has now been handled.
diff --git a/chrome/browser/chromeos/input_method/autocorrect_manager_unittest.cc b/chrome/browser/chromeos/input_method/autocorrect_manager_unittest.cc
index ab1e72a..7f9c2b2b 100644
--- a/chrome/browser/chromeos/input_method/autocorrect_manager_unittest.cc
+++ b/chrome/browser/chromeos/input_method/autocorrect_manager_unittest.cc
@@ -71,14 +71,14 @@
               (override));
 };
 
-TEST(AutocorrectManagerTest, MarkAutocorrectRangeSetsAutocorrectRange) {
+TEST(AutocorrectManagerTest, HandleAutocorrectSetsAutocorrectRange) {
   ui::IMEBridge::Initialize();
   ui::MockIMEInputContextHandler mock_ime_input_context_handler;
   ui::IMEBridge::Get()->SetInputContextHandler(&mock_ime_input_context_handler);
   MockSuggestionHandler mock_suggestion_handler;
   AutocorrectManager manager(&mock_suggestion_handler);
 
-  manager.MarkAutocorrectRange(gfx::Range(0, 3), "teh");
+  manager.HandleAutocorrect(gfx::Range(0, 3), "teh");
 
   EXPECT_EQ(mock_ime_input_context_handler.GetAutocorrectRange(),
             gfx::Range(0, 3));
@@ -90,7 +90,7 @@
   ui::IMEBridge::Get()->SetInputContextHandler(&mock_ime_input_context_handler);
   MockSuggestionHandler mock_suggestion_handler;
   AutocorrectManager manager(&mock_suggestion_handler);
-  manager.MarkAutocorrectRange(gfx::Range(0, 3), "teh");
+  manager.HandleAutocorrect(gfx::Range(0, 3), "teh");
 
   const auto key_event = CreateKeyEvent("a", "KeyA");
   EXPECT_FALSE(manager.OnKeyEvent(key_event));
@@ -110,7 +110,7 @@
   AutocorrectManager manager(&mock_suggestion_handler);
   manager.OnSurroundingTextChanged(base::ASCIIToUTF16("the "), /*cursor_pos=*/4,
                                    /*anchor_pos=*/4);
-  manager.MarkAutocorrectRange(gfx::Range(0, 3), "teh");
+  manager.HandleAutocorrect(gfx::Range(0, 3), "teh");
 
   AssistiveWindowProperties properties;
   properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
@@ -133,7 +133,7 @@
   AutocorrectManager manager(&mock_suggestion_handler);
   manager.OnSurroundingTextChanged(base::ASCIIToUTF16("the "), /*cursor_pos=*/4,
                                    /*anchor_pos=*/4);
-  manager.MarkAutocorrectRange(gfx::Range(0, 3), "teh");
+  manager.HandleAutocorrect(gfx::Range(0, 3), "teh");
 
   {
     ::testing::InSequence seq;
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine.cc b/chrome/browser/chromeos/input_method/native_input_method_engine.cc
index 3196a08..564339db 100644
--- a/chrome/browser/chromeos/input_method/native_input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/native_input_method_engine.cc
@@ -151,7 +151,7 @@
 void NativeInputMethodEngine::OnAutocorrect(std::string typed_word,
                                             std::string corrected_word,
                                             int start_index) {
-  autocorrect_manager_->MarkAutocorrectRange(
+  autocorrect_manager_->HandleAutocorrect(
       gfx::Range(start_index, start_index + corrected_word.length()),
       typed_word);
 }
@@ -429,6 +429,13 @@
       /*length=*/num_bytes_before_cursor + num_bytes_after_cursor);
 }
 
+void NativeInputMethodEngine::ImeObserver::HandleAutocorrect(
+    ime::mojom::AutocorrectSpanPtr autocorrect_span) {
+  autocorrect_manager_->HandleAutocorrect(
+      autocorrect_span->autocorrect_range,
+      std::move(autocorrect_span->original_text));
+}
+
 void NativeInputMethodEngine::ImeObserver::FlushForTesting() {
   remote_manager_.FlushForTesting();
   if (remote_to_engine_.is_bound())
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine.h b/chrome/browser/chromeos/input_method/native_input_method_engine.h
index 05fe3f8..d8149eb7 100644
--- a/chrome/browser/chromeos/input_method/native_input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/native_input_method_engine.h
@@ -123,6 +123,8 @@
                              uint32_t end_byte_index) override;
     void FinishComposition() override;
     void DeleteSurroundingText(uint32_t before, uint32_t after) override;
+    void HandleAutocorrect(
+        ime::mojom::AutocorrectSpanPtr autocorrect_span) override;
 
     // Flush all relevant Mojo pipes.
     void FlushForTesting();
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc
index bcdfcba5..825e1f7d 100644
--- a/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc
@@ -18,6 +18,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/ime/chromeos/ime_bridge.h"
+#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
 #include "ui/base/ime/chromeos/mock_input_method_manager.h"
 #include "ui/base/ime/text_input_flags.h"
 
@@ -30,14 +31,16 @@
 
 using input_method::InputMethodManager;
 using input_method::StubInputMethodEngineObserver;
+using testing::NiceMock;
 using testing::StrictMock;
 
 constexpr char kEngineIdUs[] = "xkb:us::eng";
 
 class TestInputEngineManager : public ime::mojom::InputEngineManager {
  public:
-  explicit TestInputEngineManager(ime::mojom::InputChannel* engine)
-      : receiver_(engine) {}
+  TestInputEngineManager(ime::mojom::InputChannel* engine,
+                         mojo::Remote<ime::mojom::InputChannel>* remote)
+      : receiver_(engine), remote_(remote) {}
 
   void ConnectToImeEngine(
       const std::string& ime_spec,
@@ -46,19 +49,25 @@
       const std::vector<uint8_t>& extra,
       ConnectToImeEngineCallback callback) override {
     receiver_.Bind(std::move(to_engine_request));
-    remote_.Bind(std::move(from_engine));
+    if (remote_) {
+      remote_->Bind(std::move(from_engine));
+    }
     std::move(callback).Run(/*bound=*/true);
   }
 
  private:
   mojo::Receiver<ime::mojom::InputChannel> receiver_;
-  mojo::Remote<ime::mojom::InputChannel> remote_;
+  mojo::Remote<ime::mojom::InputChannel>* remote_;
 };
 
 class TestInputMethodManager : public input_method::MockInputMethodManager {
  public:
-  explicit TestInputMethodManager(ime::mojom::InputChannel* engine)
-      : test_input_engine_manager_(engine),
+  // TestInputMethodManager is responsible for connecting
+  // NativeInputMethodEngine with an InputChannel.
+  TestInputMethodManager(
+      ime::mojom::InputChannel* engine,
+      mojo::Remote<ime::mojom::InputChannel>* remote = nullptr)
+      : test_input_engine_manager_(engine, remote),
         receiver_(&test_input_engine_manager_) {}
 
   void ConnectInputEngineManager(
@@ -144,5 +153,33 @@
   InputMethodManager::Shutdown();
 }
 
+TEST_F(NativeInputMethodEngineTest, HandleAutocorrectChangesAutocorrectRange) {
+  testing::NiceMock<ime::MockInputChannel> mock_input_channel;
+  mojo::Remote<ime::mojom::InputChannel> remote;
+  input_method::InputMethodManager::Initialize(
+      new TestInputMethodManager(&mock_input_channel, &remote));
+  NativeInputMethodEngine engine;
+  TestingProfile testing_profile;
+  engine.Initialize(std::make_unique<StubInputMethodEngineObserver>(),
+                    /*extension_id=*/"", &testing_profile);
+  ui::IMEEngineHandlerInterface::InputContext input_context(
+      ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT,
+      ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_MOUSE,
+      /*should_do_learning=*/true);
+  engine.Enable(kEngineIdUs);
+  engine.FocusIn(input_context);
+  engine.FlushForTesting();
+  ui::MockIMEInputContextHandler mock_handler;
+  ui::IMEBridge::Get()->SetInputContextHandler(&mock_handler);
+
+  remote->HandleAutocorrect(
+      ime::mojom::AutocorrectSpan::New(gfx::Range(0, 5), "teh"));
+  engine.FlushForTesting();
+
+  EXPECT_EQ(mock_handler.GetAutocorrectRange(), gfx::Range(0, 5));
+
+  InputMethodManager::Shutdown();
+}
+
 }  // namespace
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/DIR_METADATA b/chrome/browser/chromeos/login/DIR_METADATA
new file mode 100644
index 0000000..d7952fd
--- /dev/null
+++ b/chrome/browser/chromeos/login/DIR_METADATA
@@ -0,0 +1,14 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Shell>OOBE"
+}
+
+team_email: "cros-oac@google.com"
+os: CHROME_OS
diff --git a/chrome/browser/chromeos/login/OWNERS b/chrome/browser/chromeos/login/OWNERS
index a03d198..0cb8af2 100644
--- a/chrome/browser/chromeos/login/OWNERS
+++ b/chrome/browser/chromeos/login/OWNERS
@@ -9,5 +9,3 @@
 
 per-file *challenge_response*=emaxx@chromium.org
 per-file *security_token*=emaxx@chromium.org
-
-# COMPONENT: UI>Shell>OOBE
diff --git a/chrome/browser/chromeos/login/app_mode/DIR_METADATA b/chrome/browser/chromeos/login/app_mode/DIR_METADATA
new file mode 100644
index 0000000..44f8e8c4
--- /dev/null
+++ b/chrome/browser/chromeos/login/app_mode/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Shell>Kiosk"
+}
diff --git a/chrome/browser/chromeos/login/app_mode/OWNERS b/chrome/browser/chromeos/login/app_mode/OWNERS
index b51f7fc9..48247aa8 100644
--- a/chrome/browser/chromeos/login/app_mode/OWNERS
+++ b/chrome/browser/chromeos/login/app_mode/OWNERS
@@ -1,3 +1 @@
 file://chrome/browser/chromeos/app_mode/OWNERS
-
-# COMPONENT: UI>Shell>Kiosk
diff --git a/chrome/browser/chromeos/login/easy_unlock/DIR_METADATA b/chrome/browser/chromeos/login/easy_unlock/DIR_METADATA
new file mode 100644
index 0000000..fbffeca17
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "OS>Systems>Multidevice>SmartLock"
+}
diff --git a/chrome/browser/chromeos/login/easy_unlock/OWNERS b/chrome/browser/chromeos/login/easy_unlock/OWNERS
index 4843dad..df774b8 100644
--- a/chrome/browser/chromeos/login/easy_unlock/OWNERS
+++ b/chrome/browser/chromeos/login/easy_unlock/OWNERS
@@ -1,4 +1,3 @@
 hansberry@chromium.org
 file://chromeos/components/multidevice/OWNERS
 
-# COMPONENT: OS>Systems>Multidevice>SmartLock
diff --git a/chrome/browser/chromeos/login/enrollment/DIR_METADATA b/chrome/browser/chromeos/login/enrollment/DIR_METADATA
new file mode 100644
index 0000000..7ac3467
--- /dev/null
+++ b/chrome/browser/chromeos/login/enrollment/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Enterprise>Enrollment"
+}
diff --git a/chrome/browser/chromeos/login/enrollment/OWNERS b/chrome/browser/chromeos/login/enrollment/OWNERS
index fab14679..08a8c0b 100644
--- a/chrome/browser/chromeos/login/enrollment/OWNERS
+++ b/chrome/browser/chromeos/login/enrollment/OWNERS
@@ -11,4 +11,3 @@
 per-file *auto_enrollment*=mpolzer@google.com
 per-file *auto_enrollment*=vsavu@google.com
 
-# COMPONENT: Enterprise>Enrollment
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc
index 50a7897..52ab65eb9 100644
--- a/chrome/browser/chromeos/login/test/oobe_base_test.cc
+++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -39,6 +39,7 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "google_apis/gaia/gaia_switches.h"
@@ -106,6 +107,12 @@
     command_line->AppendSwitch(::switches::kDisableBackgroundNetworking);
   command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
 
+  // Blink features are controlled via a command line switch. Disable HTML
+  // imports which are deprecated. OOBE uses a polyfill for imports that will
+  // be replaced once the migration to JS modules is complete.
+  command_line->AppendSwitchASCII(::switches::kDisableBlinkFeatures,
+                                  "HTMLImports");
+
   MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line);
 }
 
diff --git a/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc
index 1822195..1054301 100644
--- a/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc
+++ b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc
@@ -127,6 +127,7 @@
   if (status != Status::kSuccess) {
     LOG(ERROR) << "Key locations retrieval failed: " << StatusToString(status);
     std::move(callback).Run(/*corporate=*/false);
+    return;
   }
 
   for (const auto key_location : key_locations) {
diff --git a/chrome/browser/chromeos/policy/arc_app_install_event_log_uploader_unittest.cc b/chrome/browser/chromeos/policy/arc_app_install_event_log_uploader_unittest.cc
index 0f19a8c..2b90628 100644
--- a/chrome/browser/chromeos/policy/arc_app_install_event_log_uploader_unittest.cc
+++ b/chrome/browser/chromeos/policy/arc_app_install_event_log_uploader_unittest.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <memory>
 #include <string>
+#include <utility>
 
 #include "base/json/json_string_value_serializer.h"
 #include "base/memory/ref_counted.h"
@@ -126,8 +127,9 @@
   void CompleteUpload(bool success) {
     ClearReportDict();
     base::Value context = reporting::GetContext(/*profile=*/nullptr);
+    base::Value events = ConvertArcAppProtoToValue(&log_, context);
     value_report_ = RealtimeReportingJobConfiguration::BuildReport(
-        ConvertArcAppProtoToValue(&log_, context), std::move(context));
+        std::move(events), std::move(context));
 
     EXPECT_CALL(client_, UploadAppInstallReport_(MatchValue(&value_report_), _))
         .WillOnce(WithArgs<1>(
@@ -139,8 +141,9 @@
   void CaptureUpload(CloudPolicyClient::StatusCallback* callback) {
     ClearReportDict();
     base::Value context = reporting::GetContext(/*profile=*/nullptr);
+    base::Value events = ConvertArcAppProtoToValue(&log_, context);
     value_report_ = RealtimeReportingJobConfiguration::BuildReport(
-        ConvertArcAppProtoToValue(&log_, context), std::move(context));
+        std::move(events), std::move(context));
 
     CloudPolicyClient::StatusCallback status_callback;
     EXPECT_CALL(client_, UploadAppInstallReport_(MatchValue(&value_report_), _))
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc b/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc
index 2165ac30..1b2132984 100644
--- a/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc
+++ b/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc
@@ -27,6 +27,7 @@
 #include "components/user_manager/user_names.h"
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/browser/extension_system.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
 #include "extensions/common/extension_builder.h"
 #include "net/base/net_errors.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -524,7 +525,9 @@
   // One extension failed.
   tracker->ReportSandboxedUnpackerFailureReason(
       kExtensionId1,
-      extensions::SandboxedUnpackerFailureReason::CRX_HEADER_INVALID);
+      extensions::CrxInstallError(
+          extensions::SandboxedUnpackerFailureReason::CRX_HEADER_INVALID,
+          base::string16()));
   ASSERT_TRUE(VerifyEventAddedSuccessfully(1 /*expected_add_count*/,
                                            0 /*expected_add_all_count*/));
   EXPECT_EQ(em::ExtensionInstallReportLogEvent::INSTALLATION_FAILED,
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_uploader_unittest.cc b/chrome/browser/chromeos/policy/extension_install_event_log_uploader_unittest.cc
index b1d9fd6..8b58e88 100644
--- a/chrome/browser/chromeos/policy/extension_install_event_log_uploader_unittest.cc
+++ b/chrome/browser/chromeos/policy/extension_install_event_log_uploader_unittest.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <memory>
 #include <string>
+#include <utility>
 
 #include "base/json/json_string_value_serializer.h"
 #include "base/memory/ref_counted.h"
@@ -180,8 +181,9 @@
   void CompleteUpload(bool success) {
     ClearReportDict();
     base::Value context = reporting::GetContext(/*profile=*/nullptr);
+    base::Value events = ConvertExtensionProtoToValue(&log_, context);
     value_report_ = RealtimeReportingJobConfiguration::BuildReport(
-        ConvertExtensionProtoToValue(&log_, context), std::move(context));
+        std::move(events), std::move(context));
 
     waiter_.IncreaseCounterLimit();
 
@@ -208,8 +210,9 @@
   void CaptureUpload(reporting::MockReportQueue::EnqueueCallback* callback) {
     ClearReportDict();
     base::Value context = reporting::GetContext(/*profile=*/nullptr);
+    base::Value events = ConvertExtensionProtoToValue(&log_, context);
     value_report_ = RealtimeReportingJobConfiguration::BuildReport(
-        ConvertExtensionProtoToValue(&log_, context), std::move(context));
+        std::move(events), std::move(context));
 
     EXPECT_CALL(*mock_report_queue_,
                 ValueEnqueue_(MatchEvents(&value_report_), _, _))
diff --git a/chrome/browser/chromeos/web_applications/media_app_integration_browsertest.cc b/chrome/browser/chromeos/web_applications/media_app_integration_browsertest.cc
index 2a64e03..d9e190a 100644
--- a/chrome/browser/chromeos/web_applications/media_app_integration_browsertest.cc
+++ b/chrome/browser/chromeos/web_applications/media_app_integration_browsertest.cc
@@ -213,7 +213,14 @@
 }
 
 // Test that the MediaApp can load RAW files passed on launch params.
-IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, HandleRawFiles) {
+// Disabled on ChromeOS because it fails randomly on linux-chromeos-chrome.
+// See: https://crbug.com/1152318
+#if defined(OS_CHROMEOS)
+#define MAYBE_HandleRawFiles DISABLED_HandleRawFiles
+#else
+#define MAYBE_HandleRawFiles HandleRawFiles
+#endif
+IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MAYBE_HandleRawFiles) {
   WaitForTestSystemAppInstall();
 
   content::WebContents* web_ui;
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index c43a681..70b208e 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -1101,7 +1101,7 @@
         break;
       case CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE:
         install_stage_tracker->ReportSandboxedUnpackerFailureReason(
-            extension_id, error->sandbox_failure_detail());
+            extension_id, error.value());
         break;
       case CrxInstallErrorType::OTHER:
         install_stage_tracker->ReportCrxInstallError(
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
index 3f9445a..9f25f8d 100644
--- a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
+++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
@@ -15,6 +15,7 @@
 #include "extensions/browser/disable_reason.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/install/crx_install_error.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
 #include "extensions/browser/updater/extension_downloader.h"
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
index a4b9cb4..ac04155 100644
--- a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
+++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
@@ -21,6 +21,7 @@
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/install/crx_install_error.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
 #include "extensions/browser/pref_names.h"
 #include "extensions/browser/updater/safe_manifest_parser.h"
 #include "extensions/common/extension.h"
@@ -520,9 +521,13 @@
        ExtensionsCrxInstallErrorSandboxUnpackFailure) {
   SetupForceList(true /*is_from_store */);
   install_stage_tracker()->ReportSandboxedUnpackerFailureReason(
-      kExtensionId1, SandboxedUnpackerFailureReason::CRX_FILE_NOT_READABLE);
+      kExtensionId1,
+      CrxInstallError(SandboxedUnpackerFailureReason::CRX_FILE_NOT_READABLE,
+                      base::string16()));
   install_stage_tracker()->ReportSandboxedUnpackerFailureReason(
-      kExtensionId2, SandboxedUnpackerFailureReason::UNZIP_FAILED);
+      kExtensionId2,
+      CrxInstallError(SandboxedUnpackerFailureReason::UNZIP_FAILED,
+                      base::string16()));
   // ForceInstalledMetrics shuts down timer because all extension are either
   // loaded or failed.
   EXPECT_FALSE(fake_timer_->IsRunning());
@@ -542,7 +547,9 @@
   install_stage_tracker()->ReportDownloadingCacheStatus(
       kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT);
   install_stage_tracker()->ReportSandboxedUnpackerFailureReason(
-      kExtensionId1, SandboxedUnpackerFailureReason::CRX_HEADER_INVALID);
+      kExtensionId1,
+      CrxInstallError(SandboxedUnpackerFailureReason::CRX_HEADER_INVALID,
+                      base::string16()));
   auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build();
   registry()->AddEnabled(ext2.get());
   force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get());
@@ -565,7 +572,9 @@
   install_stage_tracker()->ReportDownloadingCacheStatus(
       kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_MISS);
   install_stage_tracker()->ReportSandboxedUnpackerFailureReason(
-      kExtensionId1, SandboxedUnpackerFailureReason::CRX_HEADER_INVALID);
+      kExtensionId1,
+      CrxInstallError(SandboxedUnpackerFailureReason::CRX_HEADER_INVALID,
+                      base::string16()));
   auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build();
   registry()->AddEnabled(ext2.get());
   force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get());
@@ -589,7 +598,9 @@
   install_stage_tracker()->ReportDownloadingCacheStatus(
       kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_MISS);
   install_stage_tracker()->ReportSandboxedUnpackerFailureReason(
-      kExtensionId1, SandboxedUnpackerFailureReason::CRX_HEADER_INVALID);
+      kExtensionId1,
+      CrxInstallError(SandboxedUnpackerFailureReason::CRX_HEADER_INVALID,
+                      base::string16()));
   auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build();
   registry()->AddEnabled(ext2.get());
   force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get());
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc b/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc
index bc95e5c..322f3bbe 100644
--- a/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc
+++ b/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "components/prefs/pref_service.h"
 #include "extensions/browser/install/crx_install_error.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
 #include "extensions/browser/pref_names.h"
 #include "extensions/common/extension_urls.h"
 
diff --git a/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc b/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc
index aed43e3..16f304a 100644
--- a/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc
+++ b/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc
@@ -7,6 +7,7 @@
 #include "base/check_op.h"
 #include "chrome/browser/extensions/forced_extensions/install_stage_tracker_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
 #include "net/base/net_errors.h"
 
 #if defined(OS_CHROMEOS)
@@ -43,6 +44,7 @@
 // InstallStageTracker::InstallationData implementation.
 
 InstallStageTracker::InstallationData::InstallationData() = default;
+InstallStageTracker::InstallationData::~InstallationData() = default;
 
 InstallStageTracker::InstallationData::InstallationData(
     const InstallationData&) = default;
@@ -303,11 +305,18 @@
 
 void InstallStageTracker::ReportSandboxedUnpackerFailureReason(
     const ExtensionId& id,
-    SandboxedUnpackerFailureReason unpacker_failure_reason) {
+    const CrxInstallError& crx_install_error) {
+  base::Optional<SandboxedUnpackerFailureReason> unpacker_failure_reason =
+      crx_install_error.sandbox_failure_detail();
+  DCHECK(unpacker_failure_reason);
   InstallationData& data = installation_data_map_[id];
   data.failure_reason =
       FailureReason::CRX_INSTALL_ERROR_SANDBOXED_UNPACKER_FAILURE;
   data.unpacker_failure_reason = unpacker_failure_reason;
+  if (data.unpacker_failure_reason ==
+      SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED) {
+    data.unpacker_client_failed_error = crx_install_error.message();
+  }
   NotifyObserversOfFailure(
       id, FailureReason::CRX_INSTALL_ERROR_SANDBOXED_UNPACKER_FAILURE, data);
 }
diff --git a/chrome/browser/extensions/forced_extensions/install_stage_tracker.h b/chrome/browser/extensions/forced_extensions/install_stage_tracker.h
index 4bb16168..0887686 100644
--- a/chrome/browser/extensions/forced_extensions/install_stage_tracker.h
+++ b/chrome/browser/extensions/forced_extensions/install_stage_tracker.h
@@ -11,9 +11,9 @@
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
 #include "base/optional.h"
+#include "base/strings/string16.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "extensions/browser/install/crx_install_error.h"
-#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
 #include "extensions/browser/install_stage.h"
 #include "extensions/browser/updater/extension_downloader_delegate.h"
 #include "extensions/browser/updater/safe_manifest_parser.h"
@@ -289,6 +289,7 @@
   // installation stage if known.
   struct InstallationData {
     InstallationData();
+    ~InstallationData();
     InstallationData(const InstallationData&);
 
     base::Optional<Stage> install_stage;
@@ -346,6 +347,9 @@
     base::Optional<base::TimeTicks> finalizing_started_time;
     // Time at which the installation process is complete.
     base::Optional<base::TimeTicks> installation_complete_time;
+    // Detailed error description when extension failed to install with
+    // SandboxedUnpackerFailureReason equal to UNPACKER_CLIENT FAILED.
+    base::Optional<base::string16> unpacker_client_failed_error;
   };
 
   class Observer : public base::CheckedObserver {
@@ -436,7 +440,7 @@
                              CrxInstallErrorDetail crx_install_error);
   void ReportSandboxedUnpackerFailureReason(
       const ExtensionId& id,
-      SandboxedUnpackerFailureReason unpacker_failure_reason);
+      const CrxInstallError& crx_install_error);
 
   // Retrieves known information for installation of extension |id|.
   // Returns empty data if not found.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index f3d8b5b..a7753e8 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -4124,7 +4124,7 @@
       "msramek",
       "chrome-friendly-settings@google.com"
     ],
-    "expiry_milestone": 88
+    "expiry_milestone": 90
   },
   {
     "name": "safety-check-chrome-cleaner-child",
@@ -4143,7 +4143,7 @@
       "msramek",
       "chrome-friendly-settings@google.com"
     ],
-    "expiry_milestone": 88
+    "expiry_milestone": 90
   },
   {
     "name": "safety-tips",
diff --git a/chrome/browser/media/audio_service_util.cc b/chrome/browser/media/audio_service_util.cc
index 7da7a06..96f68b6 100644
--- a/chrome/browser/media/audio_service_util.cc
+++ b/chrome/browser/media/audio_service_util.cc
@@ -10,6 +10,7 @@
 #include "base/optional.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "components/policy/core/common/policy_map.h"
@@ -20,8 +21,10 @@
 
 bool IsAudioServiceSandboxEnabled() {
   base::Optional<bool> force_enable_audio_sandbox;
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
 #if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   const policy::PolicyMap& policies =
       g_browser_process->browser_policy_connector()
           ->GetPolicyService()
diff --git a/chrome/browser/media/capture_access_handler_base.cc b/chrome/browser/media/capture_access_handler_base.cc
index 086fbeb8..fd27b4b2 100644
--- a/chrome/browser/media/capture_access_handler_base.cc
+++ b/chrome/browser/media/capture_access_handler_base.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
@@ -20,10 +21,10 @@
 #include "ui/aura/window.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/hash/sha1.h"
 #include "base/strings/string_number_conversions.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 using content::BrowserThread;
 
@@ -312,7 +313,7 @@
   if (!extension)
     return false;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::string hash = base::SHA1HashString(extension->id());
   std::string hex_hash = base::HexEncode(hash.c_str(), hash.length());
 
@@ -323,7 +324,7 @@
          hex_hash == "81986D4F846CEDDDB962643FA501D1780DD441BB";
 #else
   return false;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 bool CaptureAccessHandlerBase::IsBuiltInExtension(const GURL& origin) {
diff --git a/chrome/browser/media/cast_mirroring_performance_browsertest.cc b/chrome/browser/media/cast_mirroring_performance_browsertest.cc
index d34fe580..ab0c19e3c 100644
--- a/chrome/browser/media/cast_mirroring_performance_browsertest.cc
+++ b/chrome/browser/media/cast_mirroring_performance_browsertest.cc
@@ -25,6 +25,7 @@
 #include "base/time/default_tick_clock.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/cast_mirroring_service_host.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/chrome_paths.h"
@@ -1077,7 +1078,7 @@
   AnalyzeLatency(analyzer.get());
 }
 
-#if !defined(OS_CHROMEOS) || !defined(MEMORY_SANITIZER)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) || !defined(MEMORY_SANITIZER)
 // TODO(b/161545049): reenable FPS value features.
 INSTANTIATE_TEST_SUITE_P(All,
                          CastV2PerformanceTest,
diff --git a/chrome/browser/media/cdm_storage_id.cc b/chrome/browser/media/cdm_storage_id.cc
index 49957c4..7d6dbcb8 100644
--- a/chrome/browser/media/cdm_storage_id.cc
+++ b/chrome/browser/media/cdm_storage_id.cc
@@ -7,6 +7,7 @@
 #include "base/callback.h"
 #include "base/logging.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/cdm_storage_id_key.h"
 #include "chrome/browser/media/media_storage_id_salt.h"
 #include "crypto/secure_hash.h"
@@ -15,7 +16,7 @@
 #include "rlz/buildflags/buildflags.h"
 #include "url/origin.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/bind.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
@@ -80,7 +81,7 @@
   return result;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void ComputeAndReturnStorageId(const std::vector<uint8_t>& profile_salt,
                                const url::Origin& origin,
                                CdmStorageIdCallback callback,
@@ -89,7 +90,7 @@
   std::move(callback).Run(
       CalculateStorageId(storage_id_key, profile_salt, origin, machine_id));
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace
 
@@ -103,7 +104,7 @@
   std::move(callback).Run(
       CalculateStorageId(storage_id_key, profile_salt, origin, machine_id));
 
-#elif defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
   CdmStorageIdCallback scoped_callback =
       mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback),
                                                   std::vector<uint8_t>());
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index 913828b..7506e849 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -14,6 +14,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/media_browsertest.h"
 #include "chrome/browser/media/test_license_server.h"
 #include "chrome/browser/media/wv_test_license_server_config.h"
@@ -372,7 +373,7 @@
     // Make sure the Clear Key CDM is properly registered in CdmRegistry.
     EXPECT_TRUE(IsLibraryCdmRegistered(media::kClearKeyCdmGuid));
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     // QueryOutputProtectionStatus() is known to fail on Linux Chrome OS builds.
     std::string expected_title = kEmeUnitTestFailure;
 #else
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
index 18220f3..7ea28cf0 100644
--- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_paths.h"
@@ -1153,7 +1154,7 @@
   auto result =
       IsSessionTypeSupported(kWidevine, SessionType::kPersistentLicense);
 
-#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MAC)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_WIN) || defined(OS_MAC)
   // Persistent license session supported by Widevine key system on Windows and
   // Mac. On ChromeOS, it is supported when the protected media identifier
   // permission is allowed. See kUnsafelyAllowProtectedMediaIdentifierForDomain
@@ -1177,7 +1178,7 @@
   EXPECT_WV(IsVideoRobustnessSupported(kWidevine, "SW_SECURE_DECODE"));
   EXPECT_WV(IsVideoRobustnessSupported(kWidevine, "SW_SECURE_CRYPTO"));
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // "HW_SECURE_ALL" supported on ChromeOS when the protected media identifier
   // permission is allowed. See kUnsafelyAllowProtectedMediaIdentifierForDomain
   // used above.
@@ -1193,7 +1194,7 @@
   EXPECT_UNSUPPORTED(IsAudioRobustnessSupported(kWidevine, "Invalid String"));
   EXPECT_WV(IsAudioRobustnessSupported(kWidevine, "SW_SECURE_CRYPTO"));
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the
   // protected media identifier permission is allowed. See
   // kUnsafelyAllowProtectedMediaIdentifierForDomain used above.
@@ -1249,7 +1250,7 @@
   // Audio robustness.
   EXPECT_WV(IsAudioRobustnessSupported(kWidevine, "SW_SECURE_CRYPTO"));
   EXPECT_WV(IsAudioRobustnessSupported(kWidevine, "HW_SECURE_CRYPTO"));
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the
   // protected media identifier permission is allowed. See
   // kUnsafelyAllowProtectedMediaIdentifierForDomain used above.
@@ -1265,7 +1266,7 @@
       IsVideoMp4RobustnessSupported(kWidevine, "SW_SECURE_CRYPTO"));
   EXPECT_WV_PROPRIETARY(
       IsVideoMp4RobustnessSupported(kWidevine, "SW_SECURE_DECODE"));
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the
   // protected media identifier permission is allowed. See
   // kUnsafelyAllowProtectedMediaIdentifierForDomain used above.
@@ -1288,7 +1289,7 @@
       IsAudioMp4RobustnessSupported(kWidevine, "SW_SECURE_CRYPTO"));
   EXPECT_WV_PROPRIETARY(
       IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_CRYPTO"));
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the
   // protected media identifier permission is allowed. See
   // kUnsafelyAllowProtectedMediaIdentifierForDomain used above.
@@ -1334,7 +1335,7 @@
       IsAudioEncryptionSchemeSupported(kWidevine, "cenc", "HW_SECURE_CRYPTO"));
   EXPECT_WV(
       IsVideoEncryptionSchemeSupported(kWidevine, "cenc", "HW_SECURE_ALL"));
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   EXPECT_WV(
       IsAudioEncryptionSchemeSupported(kWidevine, "cbcs", "HW_SECURE_CRYPTO"));
   EXPECT_WV(IsAudioEncryptionSchemeSupported(kWidevine, "cbcs-1-9",
diff --git a/chrome/browser/media/feeds/media_feeds_browsertest.cc b/chrome/browser/media/feeds/media_feeds_browsertest.cc
index d24b164..2d651b8 100644
--- a/chrome/browser/media/feeds/media_feeds_browsertest.cc
+++ b/chrome/browser/media/feeds/media_feeds_browsertest.cc
@@ -921,7 +921,7 @@
 }
 
 // Flaky on lacros: crbug.com/1124983
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
 #define MAYBE_ResetMediaFeed_WebContentsDestroyed \
   DISABLED_ResetMediaFeed_WebContentsDestroyed
 #else
diff --git a/chrome/browser/media/media_engagement_browsertest.cc b/chrome/browser/media/media_engagement_browsertest.cc
index 08040c99..7532fe3 100644
--- a/chrome/browser/media/media_engagement_browsertest.cc
+++ b/chrome/browser/media/media_engagement_browsertest.cc
@@ -12,6 +12,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/component_updater/mei_preload_component_installer.h"
 #include "chrome/browser/media/media_engagement_contents_observer.h"
@@ -42,10 +43,10 @@
 #include "media/base/media_switches.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/sessions/session_service_test_helper.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 namespace {
 
@@ -334,7 +335,7 @@
 }
 
 // Flaky tests on CrOS: http://crbug.com/1020131.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_RecordEngagement_AudioOnly DISABLED_RecordEngagement_AudioOnly
 #else
 #define MAYBE_RecordEngagement_AudioOnly RecordEngagement_AudioOnly
@@ -356,7 +357,7 @@
 }
 
 // Flaky tests on CrOS: http://crbug.com/1019671.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_DoNotRecordEngagement_NotTime_AudioOnly \
   DISABLED_DoNotRecordEngagement_NotTime_AudioOnly
 #else
@@ -380,7 +381,7 @@
 }
 
 // Flaky tests on CrOS: http://crbug.com/1019671.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_DoNotRecordEngagement_TabMuted_AudioOnly \
   DISABLED_DoNotRecordEngagement_TabMuted_AudioOnly
 #else
@@ -424,7 +425,7 @@
 }
 
 // Flaky tests on CrOS: http://crbug.com/1019671.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_DoNotRecordEngagement_PlaybackStopped_AudioOnly \
   DISABLED_DoNotRecordEngagement_PlaybackStopped_AudioOnly
 #else
@@ -451,7 +452,7 @@
 }
 
 // Flaky tests on CrOS: http://crbug.com/1019671.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_RecordEngagement_NotVisible_AudioOnly \
   DISABLED_RecordEngagement_NotVisible_AudioOnly
 #else
@@ -543,7 +544,7 @@
 }
 
 // Flaky tests on CrOS: http://crbug.com/1019671.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_DoNotRecordEngagement_SilentAudioTrack_AudioOnly \
   DISABLED_DoNotRecordEngagement_SilentAudioTrack_AudioOnly
 #else
@@ -598,7 +599,7 @@
 }
 
 // Flaky tests on CrOS: http://crbug.com/1019671.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_MultipleElements DISABLED_MultipleElements
 #else
 #define MAYBE_MultipleElements MultipleElements
@@ -780,12 +781,12 @@
 
     SessionStartupPref::SetStartupPref(
         profile, SessionStartupPref(SessionStartupPref::LAST));
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     SessionServiceTestHelper helper(
         SessionServiceFactory::GetForProfile(profile));
     helper.SetForceBrowserNotAliveWithNoWindows(true);
     helper.ReleaseService();
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
     std::unique_ptr<ScopedKeepAlive> keep_alive(new ScopedKeepAlive(
         KeepAliveOrigin::SESSION_RESTORE, KeepAliveRestartOption::DISABLED));
diff --git a/chrome/browser/media/output_protection_proxy.cc b/chrome/browser/media/output_protection_proxy.cc
index 0cad410c..d62d32b 100644
--- a/chrome/browser/media/output_protection_proxy.cc
+++ b/chrome/browser/media/output_protection_proxy.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
@@ -27,12 +28,12 @@
                                              int render_frame_id)
     : render_process_id_(render_process_id),
       render_frame_id_(render_frame_id)
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
       ,
       output_protection_delegate_(
           // On OS_CHROMEOS, NativeView and NativeWindow are both aura::Window*.
           GetRenderFrameView(render_process_id, render_frame_id))
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 {
 }
 
@@ -44,13 +45,13 @@
   DVLOG(1) << __func__;
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   output_protection_delegate_.QueryStatus(
       base::BindOnce(&OutputProtectionProxy::ProcessQueryStatusResult,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-#else  // defined(OS_CHROMEOS)
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
   ProcessQueryStatusResult(std::move(callback), true, 0, 0);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void OutputProtectionProxy::EnableProtection(
@@ -59,13 +60,13 @@
   DVLOG(1) << __func__;
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   output_protection_delegate_.SetProtection(desired_method_mask,
                                             std::move(callback));
-#else   // defined(OS_CHROMEOS)
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
   NOTIMPLEMENTED();
   std::move(callback).Run(false);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void OutputProtectionProxy::ProcessQueryStatusResult(
diff --git a/chrome/browser/media/output_protection_proxy.h b/chrome/browser/media/output_protection_proxy.h
index c428196..adcca1dc 100644
--- a/chrome/browser/media/output_protection_proxy.h
+++ b/chrome/browser/media/output_protection_proxy.h
@@ -8,9 +8,10 @@
 #include <stdint.h>
 
 #include "base/memory/weak_ptr.h"
+#include "build/chromeos_buildflags.h"
 #include "content/public/browser/browser_thread.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/display/output_protection_delegate.h"
 #endif
 
@@ -51,7 +52,7 @@
   int render_process_id_;
   int render_frame_id_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   ash::OutputProtectionDelegate output_protection_delegate_;
 #endif
 
diff --git a/chrome/browser/media/platform_verification_impl.cc b/chrome/browser/media/platform_verification_impl.cc
index 61378c7..afce308 100644
--- a/chrome/browser/media/platform_verification_impl.cc
+++ b/chrome/browser/media/platform_verification_impl.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "build/chromeos_buildflags.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "media/media_buildflags.h"
@@ -17,15 +18,15 @@
 #include "content/public/browser/render_process_host.h"
 #endif
 
-#if BUILDFLAG(ENABLE_CDM_STORAGE_ID) || defined(OS_CHROMEOS)
+#if BUILDFLAG(ENABLE_CDM_STORAGE_ID) || BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/render_frame_host.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chromeos/settings/cros_settings_names.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 using media::mojom::PlatformVerification;
 
@@ -84,7 +85,7 @@
 // TODO(crbug.com/676224). This should be commented out at the mojom
 // level so that it's only available for ChromeOS.
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (!platform_verification_flow_)
     platform_verification_flow_ =
         base::MakeRefCounted<chromeos::attestation::PlatformVerificationFlow>();
@@ -97,10 +98,10 @@
 #else
   // Not supported, so return failure.
   std::move(callback).Run(false, std::string(), std::string(), std::string());
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void PlatformVerificationImpl::OnPlatformChallenged(
     ChallengePlatformCallback callback,
     PlatformVerificationResult result,
@@ -125,7 +126,7 @@
   std::move(callback).Run(true, signed_data, signature,
                           platform_key_certificate);
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 void PlatformVerificationImpl::GetStorageId(uint32_t version,
                                             GetStorageIdCallback callback) {
@@ -163,7 +164,7 @@
 }
 #endif  // BUILDFLAG(ENABLE_CDM_STORAGE_ID)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void PlatformVerificationImpl::IsVerifiedAccessEnabled(
     IsVerifiedAccessEnabledCallback callback) {
   // If we are in guest/incognito mode, then verified access is effectively
@@ -185,4 +186,4 @@
   }
   std::move(callback).Run(enabled_for_device);
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/media/platform_verification_impl.h b/chrome/browser/media/platform_verification_impl.h
index a13311d..7ac294c 100644
--- a/chrome/browser/media/platform_verification_impl.h
+++ b/chrome/browser/media/platform_verification_impl.h
@@ -9,11 +9,12 @@
 
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
+#include "build/chromeos_buildflags.h"
 #include "content/public/browser/frame_service_base.h"
 #include "media/mojo/mojom/platform_verification.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/attestation/platform_verification_flow.h"
 #endif
 
@@ -35,15 +36,15 @@
                          const std::string& challenge,
                          ChallengePlatformCallback callback) final;
   void GetStorageId(uint32_t version, GetStorageIdCallback callback) final;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void IsVerifiedAccessEnabled(IsVerifiedAccessEnabledCallback callback) final;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
  private:
   // |this| can only be destructed as a FrameServiceBase.
   ~PlatformVerificationImpl() final;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   using PlatformVerificationResult =
       chromeos::attestation::PlatformVerificationFlow::Result;
 
@@ -57,7 +58,7 @@
   void OnStorageIdResponse(GetStorageIdCallback callback,
                            const std::vector<uint8_t>& storage_id);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   scoped_refptr<chromeos::attestation::PlatformVerificationFlow>
       platform_verification_flow_;
 #endif
diff --git a/chrome/browser/media/protected_media_identifier_permission_context.cc b/chrome/browser/media/protected_media_identifier_permission_context.cc
index b9d0d80..8a77389 100644
--- a/chrome/browser/media/protected_media_identifier_permission_context.cc
+++ b/chrome/browser/media/protected_media_identifier_permission_context.cc
@@ -10,6 +10,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/strings/string_split.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -21,7 +22,7 @@
 #include "content/public/browser/web_contents.h"
 #include "media/base/media_switches.h"
 #include "net/base/url_util.h"
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include <utility>
 
 #include "base/metrics/histogram_macros.h"
@@ -36,7 +37,7 @@
 #error This file currently only supports Chrome OS and Android.
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 using chromeos::attestation::PlatformVerificationDialog;
 #endif
 
@@ -46,7 +47,7 @@
     : PermissionContextBase(browser_context,
                             ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER,
                             blink::mojom::FeaturePolicyFeature::kEncryptedMedia)
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 
 #endif
 {
@@ -56,7 +57,7 @@
     ~ProtectedMediaIdentifierPermissionContext() {
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void ProtectedMediaIdentifierPermissionContext::DecidePermission(
     content::WebContents* web_contents,
     const permissions::PermissionRequestID& id,
@@ -99,7 +100,7 @@
   pending_requests_.insert(
       std::make_pair(web_contents, std::make_pair(widget, id)));
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 ContentSetting
 ProtectedMediaIdentifierPermissionContext::GetPermissionStatusInternal(
@@ -178,7 +179,7 @@
 // across platforms.
 bool ProtectedMediaIdentifierPermissionContext::
     IsProtectedMediaIdentifierEnabled() const {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   Profile* profile = Profile::FromBrowserContext(browser_context());
   // Platform verification is not allowed in incognito or guest mode.
   if (profile->IsOffTheRecord() || profile->IsGuestSession()) {
@@ -210,7 +211,7 @@
   return true;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 
 static void ReportPermissionActionUMA(permissions::PermissionAction action) {
   UMA_HISTOGRAM_ENUMERATION("Permissions.Action.ProtectedMedia", action,
diff --git a/chrome/browser/media/protected_media_identifier_permission_context.h b/chrome/browser/media/protected_media_identifier_permission_context.h
index 5ecfc22..d81f418f 100644
--- a/chrome/browser/media/protected_media_identifier_permission_context.h
+++ b/chrome/browser/media/protected_media_identifier_permission_context.h
@@ -7,10 +7,11 @@
 
 #include "base/macros.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "components/permissions/permission_context_base.h"
 #include "components/permissions/permission_request_id.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include <map>
 
 #include "base/memory/weak_ptr.h"
@@ -36,7 +37,7 @@
   ~ProtectedMediaIdentifierPermissionContext() override;
 
   // PermissionContextBase implementation.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void DecidePermission(
       content::WebContents* web_contents,
       const permissions::PermissionRequestID& id,
@@ -44,7 +45,7 @@
       const GURL& embedding_origin,
       bool user_gesture,
       permissions::BrowserPermissionCallback callback) override;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   ContentSetting GetPermissionStatusInternal(
       content::RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
@@ -65,7 +66,7 @@
   // guest mode, or by the device policy.
   bool IsProtectedMediaIdentifierEnabled() const;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void OnPlatformVerificationConsentResponse(
       content::WebContents* web_contents,
       const permissions::PermissionRequestID& id,
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn
index b93c296f..c42c5cf 100644
--- a/chrome/browser/media/router/BUILD.gn
+++ b/chrome/browser/media/router/BUILD.gn
@@ -41,6 +41,7 @@
   if (enable_extensions) {
     deps += [
       "discovery",
+      "//build:chromeos_buildflags",
       "//components/mirroring/mojom:host",
       "//components/mirroring/mojom:service",
 
diff --git a/chrome/browser/media/router/discovery/BUILD.gn b/chrome/browser/media/router/discovery/BUILD.gn
index 42ab2152..d7c22fe 100644
--- a/chrome/browser/media/router/discovery/BUILD.gn
+++ b/chrome/browser/media/router/discovery/BUILD.gn
@@ -9,6 +9,7 @@
   deps = [
     "//base",
     "//base:i18n",
+    "//build:chromeos_buildflags",
     "//chrome/app:generated_resources",
     "//chrome/common:constants",
     "//components/cast_channel",
diff --git a/chrome/browser/media/router/discovery/dial/dial_service.cc b/chrome/browser/media/router/discovery/dial/dial_service.cc
index 378b87b..930b0fcc 100644
--- a/chrome/browser/media/router/discovery/dial/dial_service.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_service.cc
@@ -18,6 +18,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -35,7 +36,7 @@
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "url/gurl.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/task_runner_util.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
@@ -56,7 +57,7 @@
 
 namespace media_router {
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
 void PostSendNetworkList(
     base::WeakPtr<DialServiceImpl> impl,
     const base::Optional<net::NetworkInterfaceList>& networks) {
@@ -65,7 +66,7 @@
       FROM_HERE, base::BindOnce(&DialServiceImpl::SendNetworkList,
                                 std::move(impl), networks));
 }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
 namespace {
 
@@ -126,7 +127,7 @@
   return request;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Finds the IP address of the preferred interface of network type |type|
 // to bind the socket and inserts the address into |bind_address_list|. This
 // ChromeOS version can prioritize wifi and ethernet interfaces.
@@ -175,7 +176,7 @@
       net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
       base::BindOnce(&PostSendNetworkList, std::move(impl)));
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace
 
@@ -432,7 +433,7 @@
 
   auto task_runner = content::GetUIThreadTaskRunner({});
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   task_tracker_.PostTaskAndReplyWithResult(
       task_runner.get(), FROM_HERE,
       base::BindOnce(&GetBestBindAddressOnUIThread),
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
index 12d3741..64a1adeb 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -16,6 +16,7 @@
 #include "base/observer_list.h"
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/cast_mirroring_service_host.h"
 #include "chrome/browser/media/cast_remoting_connector.h"
 #include "chrome/browser/media/router/event_page_request_manager.h"
@@ -98,7 +99,7 @@
 
 DesktopMediaPickerController::Params MakeDesktopPickerParams(
     content::WebContents* web_contents) {
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   DCHECK(web_contents);
 #endif
 
@@ -1131,7 +1132,7 @@
   DCHECK(!pending_stream_request_);
   pending_stream_request_.emplace();
   PendingStreamRequest& request = *pending_stream_request_;
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   DCHECK(web_contents);
   content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
   request.render_process_id = main_frame->GetProcess()->GetID();
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
index 7dec2a2..04530ce 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/desktop_capture_devices_util.h"
 #include "chrome/browser/media/webrtc/desktop_media_picker_factory_impl.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
@@ -54,11 +55,11 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "url/origin.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/shell.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
 #include "ui/base/ui_base_features.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if defined(OS_MAC)
 #include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
@@ -231,7 +232,7 @@
 
     if (is_approved) {
       content::DesktopMediaID screen_id;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
       screen_id = content::DesktopMediaID::RegisterNativeWindow(
           content::DesktopMediaID::TYPE_SCREEN,
           primary_root_window_for_testing_
@@ -244,10 +245,10 @@
             std::move(ui));
         return;
       }
-#else   // defined(OS_CHROMEOS)
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
       screen_id = content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
                                           webrtc::kFullDesktopScreenId);
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
       bool capture_audio =
           (request.audio_type ==
@@ -378,7 +379,7 @@
         std::move(ui));
     return;
   }
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   {
     if (policy::DlpContentManager::Get()->IsScreenCaptureRestricted(media_id)) {
       std::move(callback).Run(
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.h b/chrome/browser/media/webrtc/desktop_capture_access_handler.h
index 2fda1ba..17ada98 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler.h
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.h
@@ -12,6 +12,7 @@
 
 #include "base/containers/flat_map.h"
 #include "base/macros.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/capture_access_handler_base.h"
 #include "chrome/browser/media/media_access_handler.h"
 #include "chrome/browser/media/webrtc/desktop_media_list.h"
@@ -21,7 +22,7 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 namespace aura {
 class Window;
 }
@@ -105,7 +106,7 @@
   RequestsQueues pending_requests_;
   content::NotificationRegistrar notifications_registrar_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   aura::Window* primary_root_window_for_testing_ = nullptr;
 #endif
 
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
index 89c92e6..14d69aa7 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/fake_desktop_media_picker_factory.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
@@ -30,7 +31,7 @@
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/dlp/mock_dlp_content_manager.h"
 #include "ui/aura/window.h"
 #endif
@@ -145,7 +146,7 @@
     return access_handler_->pending_requests_;
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void SetPrimaryRootWindow(aura::Window* window) {
     access_handler_->primary_root_window_for_testing_ = window;
   }
@@ -352,7 +353,7 @@
   extensionBuilder.SetLocation(extensions::Manifest::COMPONENT);
   auto extension = extensionBuilder.Build();
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<aura::Window> primary_root_window =
       std::make_unique<aura::Window>(/*delegate=*/nullptr);
   primary_root_window->Init(ui::LAYER_NOT_DRAWN);
@@ -370,7 +371,7 @@
   EXPECT_EQ(1u, devices.size());
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(DesktopCaptureAccessHandlerTest, ScreenCaptureAccessDlpRestricted) {
   // Setup Data Leak Prevention restriction.
   policy::MockDlpContentManager mock_dlp_content_manager;
diff --git a/chrome/browser/media/webrtc/desktop_media_picker_factory_impl.cc b/chrome/browser/media/webrtc/desktop_media_picker_factory_impl.cc
index b4c479c..d55e7ace 100644
--- a/chrome/browser/media/webrtc/desktop_media_picker_factory_impl.cc
+++ b/chrome/browser/media/webrtc/desktop_media_picker_factory_impl.cc
@@ -6,6 +6,7 @@
 
 #include "base/no_destructor.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/desktop_media_list_ash.h"
 #include "chrome/browser/media/webrtc/native_desktop_media_list.h"
 #include "chrome/browser/media/webrtc/tab_desktop_media_list.h"
@@ -48,10 +49,10 @@
         if (have_screen_list)
           continue;
         std::unique_ptr<DesktopMediaList> screen_list;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
         screen_list = std::make_unique<DesktopMediaListAsh>(
             content::DesktopMediaID::TYPE_SCREEN);
-#else   // !defined(OS_CHROMEOS)
+#else   // !BUILDFLAG(IS_CHROMEOS_ASH)
         // If screen capture is not supported on the platform, then we should
         // not attempt to create an instance of NativeDesktopMediaList. Doing so
         // will hit a DCHECK.
@@ -62,7 +63,7 @@
 
         screen_list = std::make_unique<NativeDesktopMediaList>(
             content::DesktopMediaID::TYPE_SCREEN, std::move(capturer));
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
         have_screen_list = true;
         source_lists.push_back(std::move(screen_list));
         break;
@@ -71,10 +72,10 @@
         if (have_window_list)
           continue;
         std::unique_ptr<DesktopMediaList> window_list;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
         window_list = std::make_unique<DesktopMediaListAsh>(
             content::DesktopMediaID::TYPE_WINDOW);
-#else   // !defined(OS_CHROMEOS)
+#else   // !BUILDFLAG(IS_CHROMEOS_ASH)
         // If window capture is not supported on the platform, then we should
         // not attempt to create an instance of NativeDesktopMediaList. Doing so
         // will hit a DCHECK.
@@ -84,7 +85,7 @@
           continue;
         window_list = std::make_unique<NativeDesktopMediaList>(
             content::DesktopMediaID::TYPE_WINDOW, std::move(capturer));
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
         have_window_list = true;
         source_lists.push_back(std::move(window_list));
         break;
diff --git a/chrome/browser/media/webrtc/display_media_access_handler.cc b/chrome/browser/media/webrtc/display_media_access_handler.cc
index 8779136..52b49928 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler.cc
@@ -12,6 +12,7 @@
 #include "base/callback.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/desktop_capture_devices_util.h"
 #include "chrome/browser/media/webrtc/desktop_media_picker_factory_impl.h"
 #include "chrome/browser/media/webrtc/native_desktop_media_list.h"
@@ -30,9 +31,9 @@
 #include "content/public/browser/web_contents.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if defined(OS_MAC)
 #include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
@@ -265,7 +266,7 @@
       request_result =
           blink::mojom::MediaStreamRequestResult::TAB_CAPTURE_FAILURE;
     }
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     if (request_result == blink::mojom::MediaStreamRequestResult::OK) {
       if (policy::DlpContentManager::Get()->IsScreenCaptureRestricted(
               media_id)) {
diff --git a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
index 0baab0c..30152f1c 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/fake_desktop_media_picker_factory.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/browser/browser_context.h"
@@ -29,7 +30,7 @@
 #include "base/mac/mac_util.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/dlp/mock_dlp_content_manager.h"
 #endif
 
@@ -165,7 +166,7 @@
   EXPECT_EQ(0u, devices.size());
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(DisplayMediaAccessHandlerTest, DlpRestricted) {
   const content::DesktopMediaID media_id(content::DesktopMediaID::TYPE_SCREEN,
                                          content::DesktopMediaID::kFakeId);
diff --git a/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc b/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc
index 578f0d93..afa08c4 100644
--- a/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc
+++ b/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/media_access_handler.h"
 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
 #include "chrome/browser/media/webrtc/permission_bubble_media_access_handler.h"
@@ -43,12 +44,12 @@
 #include "chrome/browser/media/webrtc/display_media_access_handler.h"
 #endif  //  defined(OS_ANDROID)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/shell.h"
 #include "chrome/browser/media/chromeos_login_media_access_handler.h"
 #include "chrome/browser/media/public_session_media_access_handler.h"
 #include "chrome/browser/media/public_session_tab_capture_access_handler.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #include "chrome/browser/media/extension_media_access_handler.h"
@@ -90,7 +91,7 @@
 #endif  //  defined(OS_ANDROID)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   media_access_handlers_.push_back(
       std::make_unique<ChromeOSLoginMediaAccessHandler>());
   // Wrapper around ExtensionMediaAccessHandler used in Public Sessions.
@@ -102,7 +103,7 @@
 #endif
   media_access_handlers_.push_back(
       std::make_unique<DesktopCaptureAccessHandler>());
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Wrapper around TabCaptureAccessHandler used in Public Sessions.
   media_access_handlers_.push_back(
       std::make_unique<PublicSessionTabCaptureAccessHandler>());
@@ -401,7 +402,7 @@
     }
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (IsOriginForCasting(security_origin) &&
       blink::IsVideoInputMediaType(stream_type)) {
     // Notify ash that casting state has changed.
diff --git a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
index 3b086ae..7858dd5 100644
--- a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
+++ b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
@@ -14,6 +14,7 @@
 #include "base/macros.h"
 #include "base/notreached.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
@@ -44,7 +45,7 @@
 #include "extensions/common/extension.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
 #endif
 
@@ -216,7 +217,7 @@
           devices_, ui_ ? base::OnceClosure() : std::move(stop_callback));
     }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     policy::DlpContentManager::Get()->OnScreenCaptureStarted(
         label, screen_capture_ids, state_change_callback);
 #endif
@@ -232,7 +233,7 @@
 
   void OnDeviceStopped(const std::string& label,
                        const content::DesktopMediaID& media_id) override {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     policy::DlpContentManager::Get()->OnScreenCaptureStopped(label, media_id);
 #endif
   }
diff --git a/chrome/browser/media/webrtc/tab_capture_access_handler.cc b/chrome/browser/media/webrtc/tab_capture_access_handler.cc
index a39cc1f..1096017 100644
--- a/chrome/browser/media/webrtc/tab_capture_access_handler.cc
+++ b/chrome/browser/media/webrtc/tab_capture_access_handler.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
@@ -18,9 +19,9 @@
 #include "extensions/common/permissions/permissions_data.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 TabCaptureAccessHandler::TabCaptureAccessHandler() = default;
 
@@ -68,7 +69,7 @@
     return;
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (request.video_type ==
       blink::mojom::MediaStreamType::GUM_TAB_VIDEO_CAPTURE) {
     content::DesktopMediaID media_id(
diff --git a/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc b/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc
index ab9cc7f..3baab6e 100644
--- a/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/tab_capture_access_handler_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
 #include "chrome/browser/media/webrtc/fake_desktop_media_picker_factory.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
@@ -23,7 +24,7 @@
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/dlp/mock_dlp_content_manager.h"
 #endif
 
@@ -99,7 +100,7 @@
             devices[0].type);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(TabCaptureAccessHandlerTest, DlpRestricted) {
   const content::DesktopMediaID source(
       content::DesktopMediaID::TYPE_WEB_CONTENTS,
diff --git a/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc b/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc
index e463955..6747e6a 100644
--- a/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc
+++ b/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/desktop_media_list.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -31,10 +32,10 @@
 #include "content/public/test/web_contents_tester.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 using content::WebContents;
 using content::WebContentsTester;
@@ -152,7 +153,7 @@
     TestingBrowserProcess::GetGlobal()->SetProfileManager(
         new UnittestProfileManager(temp_dir_.GetPath()));
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
     cl->AppendSwitch(switches::kTestType);
 #endif
@@ -247,7 +248,7 @@
 
   content::BrowserTaskEnvironment task_environment_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
   chromeos::ScopedTestUserManager test_user_manager_;
 #endif
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_common.cc b/chrome/browser/media/webrtc/webrtc_browsertest_common.cc
index 2da302b..565f77f 100644
--- a/chrome/browser/media/webrtc/webrtc_browsertest_common.cc
+++ b/chrome/browser/media/webrtc/webrtc_browsertest_common.cc
@@ -11,6 +11,7 @@
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/common/chrome_paths.h"
@@ -43,17 +44,17 @@
 
 #if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
     defined(ADDRESS_SANITIZER)
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 const int kDefaultPollIntervalMsec = 2000;
 #else
 const int kDefaultPollIntervalMsec = 1000;
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 #else
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 const int kDefaultPollIntervalMsec = 500;
 #else
 const int kDefaultPollIntervalMsec = 250;
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 #endif
 
 bool IsErrorResult(const std::string& result) {
diff --git a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
index bb7dac19..bd9059f 100644
--- a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "base/command_line.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/webrtc_browsertest_base.h"
 #include "chrome/browser/media/webrtc/webrtc_browsertest_common.h"
 #include "chrome/browser/ui/browser.h"
@@ -62,7 +63,9 @@
 
 // TODO(crbug.com/796889): Enable on Mac when thread check crash is fixed.
 // TODO(sprang): Figure out why test times out on Win 10 and ChromeOS.
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 #define MAYBE_RunsScreenshareFromOneTabToAnother \
   RunsScreenshareFromOneTabToAnother
 #else
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc
index b11ec75b..05841d4 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc
@@ -17,6 +17,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/unguessable_token.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/policy/core/common/policy_service.h"
@@ -25,7 +26,7 @@
 #include "content/public/browser/render_process_host.h"
 #include "third_party/zlib/zlib.h"
 
-#if defined OS_CHROMEOS
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #endif
 
@@ -1019,7 +1020,7 @@
 
 bool DoesProfileDefaultToLoggingEnabled(const Profile* const profile) {
 // For Chrome OS, exclude special profiles and users.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   const user_manager::User* user =
       chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
   // We do not log an error here since this can happen in several cases,
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_common_unittest.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_common_unittest.cc
index ae03db18..4700692c 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_manager_common_unittest.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_common_unittest.cc
@@ -15,11 +15,12 @@
 #include "base/rand_util.h"
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/webrtc_event_log_manager_unittest_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/zlib/google/compression_utils.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/test/base/testing_profile.h"
@@ -662,7 +663,7 @@
   EXPECT_FALSE(base::PathExists(path_));  // Errored files deleted by Close().
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 
 struct DoesProfileDefaultToLoggingEnabledForUserTypeTestCase {
   user_manager::UserType user_type;
@@ -742,6 +743,6 @@
             {user_manager::USER_TYPE_ARC_KIOSK_APP, false},
             {user_manager::USER_TYPE_ACTIVE_DIRECTORY, false}}));
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace webrtc_event_logging
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc
index 6cb9ed0..65df7ec53 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc
@@ -36,6 +36,7 @@
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/webrtc_event_log_manager_common.h"
 #include "chrome/browser/media/webrtc/webrtc_event_log_manager_unittest_helpers.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
@@ -59,14 +60,14 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/zlib/google/compression_utils.h"
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_types.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "components/account_id/account_id.h"
@@ -305,13 +306,13 @@
     SetLocalLogsObserver(&local_observer_);
     SetRemoteLogsObserver(&remote_observer_);
     LoadMainTestProfile();
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
     policy::BrowserPolicyConnectorBase::SetPolicyProviderForTesting(&provider_);
 #endif
   }
 
   void TearDown() override {
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
     TestingBrowserProcess::GetGlobal()->ShutdownBrowserPolicyConnector();
 #endif
   }
@@ -666,7 +667,7 @@
                                 policy_allows_remote_logging.value());
     }
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
     policy::PolicyMap policy_map;
     if (has_device_level_policies) {
       policy_map.Set("test-policy", policy::POLICY_LEVEL_MANDATORY,
@@ -810,7 +811,7 @@
   scoped_refptr<network::SharedURLLoaderFactory>
       test_shared_url_loader_factory_;
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   policy::MockConfigurationPolicyProvider provider_;
 #endif
 
@@ -1054,7 +1055,7 @@
     WebRtcEventLogManagerTestBase::SetUp();
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<user_manager::ScopedUserManager> GetScopedUserManager(
       user_manager::UserType user_type);
 #endif
@@ -3986,7 +3987,7 @@
   EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 std::unique_ptr<user_manager::ScopedUserManager>
 WebRtcEventLogManagerTestPolicy::GetScopedUserManager(
     user_manager::UserType user_type) {
@@ -4012,7 +4013,7 @@
 
   const bool allow_remote_logging = true;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager =
       GetScopedUserManager(user_manager::USER_TYPE_REGULAR);
 #endif
@@ -4043,7 +4044,7 @@
 
   const bool allow_remote_logging = false;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager =
       GetScopedUserManager(user_manager::USER_TYPE_CHILD);
 #endif
@@ -4061,7 +4062,7 @@
   EXPECT_EQ(StartRemoteLogging(key), allow_remote_logging);
 }
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(WebRtcEventLogManagerTestPolicy,
        OnlyManagedByPlatformPoliciesDoesNotAllowRemoteLoggingByDefault) {
   SetUp(true);  // Feature generally enabled (kill-switch not engaged).
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
index a0e329f..b8f2ec41 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
@@ -9,6 +9,7 @@
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -36,9 +37,9 @@
 const char kProduct[] = "Chrome";
 #elif defined(OS_MAC)
 const char kProduct[] = "Chrome_Mac";
-#elif defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
 const char kProduct[] = "Chrome_ChromeOS";
-#elif defined(OS_LINUX)
+#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 const char kProduct[] = "Chrome_Linux";
 #elif defined(OS_ANDROID)
 const char kProduct[] = "Chrome_Android";
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
index b44aed38..e3a2a66 100644
--- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/webrtc/webrtc_browsertest_base.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/web_contents.h"
@@ -18,7 +19,7 @@
 #include "base/mac/mac_util.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set.h"
 #endif
@@ -71,13 +72,13 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     command_line->AppendSwitch(
         switches::kEnableExperimentalWebPlatformFeatures);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     command_line->AppendSwitchASCII(switches::kAutoSelectDesktopCaptureSource,
                                     "Display");
 #else
     command_line->AppendSwitchASCII(switches::kAutoSelectDesktopCaptureSource,
                                     "Entire screen");
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   }
 };
 
@@ -96,7 +97,7 @@
   RunGetDisplayMedia(tab, constraints);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker,
                        GetDisplayMediaVideoWithDlp) {
   ASSERT_TRUE(embedded_test_server()->Start());
@@ -129,16 +130,17 @@
       tab->GetMainFrame(), "waitVideoUnmuted();", &result));
   EXPECT_EQ(result, "unmuted");
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 // Real desktop capture is flaky on below platforms.
 #if defined(OS_WIN)
 #define MAYBE_GetDisplayMediaVideoAndAudio DISABLED_GetDisplayMediaVideoAndAudio
 // On linux debug bots, it's flaky as well.
-#elif (defined(OS_LINUX) && !defined(NDEBUG))
+#elif ((defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(NDEBUG))
 #define MAYBE_GetDisplayMediaVideoAndAudio DISABLED_GetDisplayMediaVideoAndAudio
 // On linux asan bots, it's flaky as well - msan and other rel bot are fine.
-#elif (defined(OS_LINUX) && defined(ADDRESS_SANITIZER))
+#elif ((defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
+       defined(ADDRESS_SANITIZER))
 #define MAYBE_GetDisplayMediaVideoAndAudio DISABLED_GetDisplayMediaVideoAndAudio
 #else
 #define MAYBE_GetDisplayMediaVideoAndAudio GetDisplayMediaVideoAndAudio
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
index 88b66b4..bb05781 100644
--- a/chrome/browser/media/webrtc/webrtc_log_uploader.cc
+++ b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
@@ -22,6 +22,7 @@
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "components/version_info/version_info.h"
 #include "components/webrtc_logging/browser/log_cleanup.h"
@@ -347,7 +348,9 @@
   const char product[] = "Chrome";
 #elif defined(OS_MAC)
   const char product[] = "Chrome_Mac";
-#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 #if !defined(ADDRESS_SANITIZER)
   const char product[] = "Chrome_Linux";
 #else
@@ -355,7 +358,7 @@
 #endif
 #elif defined(OS_ANDROID)
   const char product[] = "Chrome_Android";
-#elif defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
   const char product[] = "Chrome_ChromeOS";
 #else
 #error Platform not supported.
diff --git a/chrome/browser/media/webrtc/webrtc_text_log_handler.cc b/chrome/browser/media/webrtc/webrtc_text_log_handler.cc
index cffdd8aa..ac22f09 100644
--- a/chrome/browser/media/webrtc/webrtc_text_log_handler.cc
+++ b/chrome/browser/media/webrtc/webrtc_text_log_handler.cc
@@ -21,6 +21,7 @@
 #include "base/system/sys_info.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/audio_service_util.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/media/webrtc_logging.mojom.h"
@@ -49,7 +50,7 @@
 #include "base/mac/mac_util.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chromeos/system/statistics_provider.h"
 #endif
 
@@ -472,7 +473,7 @@
   std::string computer_model = "Not available";
 #if defined(OS_MAC)
   computer_model = base::mac::GetModelIdentifier();
-#elif defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::system::StatisticsProvider::GetInstance()->GetMachineStatistic(
       chromeos::system::kHardwareClassKey, &computer_model);
 #endif
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager.cc b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
index 5cafa3f4..aa065b6 100644
--- a/chrome/browser/nearby_sharing/nearby_notification_manager.cc
+++ b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
@@ -614,6 +614,10 @@
     const TransferMetadata& transfer_metadata) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
+  // If there is an existing notification, close it first otherwise we won't
+  // get a heads-up pop-up.
+  CloseTransfer();
+
   message_center::Notification notification =
       CreateNearbyNotification(kNearbyNotificationId);
   notification.set_title(l10n_util::GetStringUTF16(
@@ -622,6 +626,7 @@
       GetConnectionRequestNotificationMessage(share_target, transfer_metadata));
   notification.set_icon(GetImageFromShareTarget(share_target));
   notification.set_never_timeout(true);
+  notification.set_priority(message_center::NotificationPriority::MAX_PRIORITY);
 
   bool show_accept_button =
       transfer_metadata.status() ==
@@ -668,6 +673,10 @@
 void NearbyNotificationManager::ShowSuccess(const ShareTarget& share_target) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
+  // If there is an existing notification, close it first otherwise we won't
+  // get a heads-up pop-up.
+  CloseTransfer();
+
   if (!share_target.is_incoming) {
     message_center::Notification notification =
         CreateNearbyNotification(kNearbyNotificationId);
@@ -761,6 +770,10 @@
     const TransferMetadata& transfer_metadata) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
+  // If there is an existing notification, close it first otherwise we won't
+  // get a heads-up pop-up.
+  CloseTransfer();
+
   message_center::Notification notification =
       CreateNearbyNotification(kNearbyNotificationId);
   notification.set_title(GetFailureNotificationTitle(share_target));
diff --git a/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/services/PaintPreviewTabServiceTest.java b/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/services/PaintPreviewTabServiceTest.java
index cb72f9c6..0e65d8c 100644
--- a/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/services/PaintPreviewTabServiceTest.java
+++ b/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/services/PaintPreviewTabServiceTest.java
@@ -99,8 +99,6 @@
         activity.getWindow().setLocalFocus(true, true);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             InstrumentationRegistry.getInstrumentation().callActivityOnRestart(activity);
-            InstrumentationRegistry.getInstrumentation().callActivityOnStart(activity);
-            InstrumentationRegistry.getInstrumentation().callActivityOnResume(activity);
         });
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.cc b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.cc
index f11b077..731947e6 100644
--- a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.cc
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.cc
@@ -4,11 +4,13 @@
 
 #include "chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller.h"
 
+#include "base/stl_util.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/ui/android/passwords/all_passwords_bottom_sheet_view.h"
 #include "chrome/browser/ui/android/passwords/all_passwords_bottom_sheet_view_impl.h"
 #include "components/password_manager/content/browser/content_password_manager_driver.h"
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
+#include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_driver.h"
 #include "components/password_manager/core/browser/password_store.h"
@@ -64,7 +66,8 @@
 
 void AllPasswordsBottomSheetController::OnGetPasswordStoreResults(
     std::vector<std::unique_ptr<password_manager::PasswordForm>> results) {
-  // TODO(crbug.com/1104132): Handle empty credentials case.
+  base::EraseIf(results,
+                [](const auto& form_ptr) { return form_ptr->blocked_by_user; });
   view_->Show(std::move(results), focused_field_type_);
 }
 
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller_unittest.cc b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller_unittest.cc
index b95d677..26256e3 100644
--- a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller_unittest.cc
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_controller_unittest.cc
@@ -39,6 +39,7 @@
 
 constexpr char kExampleCom[] = "https://example.com";
 constexpr char kExampleOrg[] = "http://www.example.org";
+constexpr char kExampleDe[] = "https://www.example.de";
 
 constexpr char kUsername1[] = "alice";
 constexpr char kUsername2[] = "bob";
@@ -80,11 +81,19 @@
 PasswordForm MakeSavedPassword(const std::string& signon_realm,
                                const std::string& username) {
   PasswordForm form;
-  form.signon_realm = std::string(signon_realm);
+  form.signon_realm = signon_realm;
   form.url = GURL(signon_realm);
   form.username_value = base::ASCIIToUTF16(username);
   form.password_value = base::ASCIIToUTF16(kPassword);
-  form.username_element = base::ASCIIToUTF16("");
+  form.in_store = PasswordForm::Store::kProfileStore;
+  return form;
+}
+
+PasswordForm MakePasswordException(const std::string& signon_realm) {
+  PasswordForm form;
+  form.blocked_by_user = true;
+  form.signon_realm = signon_realm;
+  form.url = GURL(signon_realm);
   form.in_store = PasswordForm::Store::kProfileStore;
   return form;
 }
@@ -149,6 +158,9 @@
   store().AddLogin(form2);
   store().AddLogin(form3);
   store().AddLogin(form4);
+  // Exceptions are not shown. Sites where saving is disabled still show pwds.
+  store().AddLogin(MakePasswordException(kExampleDe));
+  store().AddLogin(MakePasswordException(kExampleCom));
 
   EXPECT_CALL(view(),
               Show(UnorderedElementsAre(Pointee(Eq(form1)), Pointee(Eq(form2)),
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper.cc b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper.cc
index 8d86905e..5cced45f 100644
--- a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper.cc
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper.h"
 
+#include "base/functional/not_fn.h"
+#include "base/ranges/algorithm.h"
+#include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_store.h"
 
 AllPasswordsBottomSheetHelper::AllPasswordsBottomSheetHelper(
@@ -31,8 +34,9 @@
 
 void AllPasswordsBottomSheetHelper::OnGetPasswordStoreResults(
     std::vector<std::unique_ptr<password_manager::PasswordForm>> results) {
-  available_credentials_ = results.size();
-  if (results.empty())
+  available_credentials_ = base::ranges::count_if(
+      results, base::not_fn(&password_manager::PasswordForm::blocked_by_user));
+  if (available_credentials_.value() == 0)
     return;  // Don't update if sheet still wouldn't be available.
   if (update_callback_.is_null())
     return;  // No update if cannot be triggered right now.
diff --git a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper_unittest.cc b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper_unittest.cc
index 7e5fc0c5..b48a7a0c 100644
--- a/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper_unittest.cc
+++ b/chrome/browser/password_manager/android/all_passwords_bottom_sheet_helper_unittest.cc
@@ -22,6 +22,7 @@
 constexpr char kPassword[] = "password123";
 
 namespace {
+
 PasswordForm MakeSavedPassword(base::StringPiece signon_realm,
                                base::StringPiece username) {
   PasswordForm form;
@@ -32,6 +33,16 @@
   form.in_store = PasswordForm::Store::kProfileStore;
   return form;
 }
+
+PasswordForm MakePasswordException(const std::string& signon_realm) {
+  PasswordForm form;
+  form.blocked_by_user = true;
+  form.signon_realm = signon_realm;
+  form.url = GURL(signon_realm);
+  form.in_store = PasswordForm::Store::kProfileStore;
+  return form;
+}
+
 }  // namespace
 
 class AllPasswordsBottomSheetHelperTest : public testing::Test {
@@ -62,6 +73,9 @@
 }
 
 TEST_F(AllPasswordsBottomSheetHelperTest, CallbackIsNotCalledForEmptyStore) {
+  // Exceptions don't count towards stored passwords!
+  store().AddLogin(MakePasswordException(kExampleCom));
+
   base::MockOnceClosure callback;
   EXPECT_CALL(callback, Run).Times(0);
 
diff --git a/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc b/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc
index e7ddefa4..37f0af1e 100644
--- a/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc
+++ b/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc
@@ -43,9 +43,7 @@
     PasswordManagerSigninInterceptTestHelper(
         net::test_server::EmbeddedTestServer* https_test_server)
     : https_test_server_(https_test_server) {
-  feature_list_.InitWithFeatures(
-      {kDiceWebSigninInterceptionFeature, ::features::kProfilesUIRevamp},
-      /*disabled_features=*/{});
+  feature_list_.InitAndEnableFeature(kDiceWebSigninInterceptionFeature);
 }
 
 PasswordManagerSigninInterceptTestHelper::
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
index 5e556624..62c4e224 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -2093,8 +2093,15 @@
 
 // Tests that a Previous Track button is displayed in the Picture-in-Picture
 // window when Media Session Action "previoustrack" is handled by the website.
+// TODO(crbug.com/985303): Flaky on Linux.
+#if defined(OS_LINUX)
+#define MAYBE_PreviousTrackButtonVisibility \
+  DISABLED_PreviousTrackButtonVisibility
+#else
+#define MAYBE_PreviousTrackButtonVisibility PreviousTrackButtonVisibility
+#endif
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
-                       PreviousTrackButtonVisibility) {
+                       MAYBE_PreviousTrackButtonVisibility) {
   LoadTabAndEnterPictureInPicture(
       browser(), base::FilePath(kPictureInPictureWindowSizePage));
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc
index 562950f..f76d437 100644
--- a/chrome/browser/policy/chrome_browser_policy_connector.cc
+++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -15,6 +15,7 @@
 #include "base/task/post_task.h"
 #include "base/task/thread_pool.h"
 #include "build/branding_buildflags.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/policy/configuration_policy_handler_list_factory.h"
 #include "chrome/browser/policy/device_management_service_configuration.h"
@@ -51,7 +52,7 @@
 #include "components/policy/core/common/android/android_combined_policy_provider.h"
 #endif
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.h"
 #include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h"
 #include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
@@ -68,7 +69,7 @@
 
 ChromeBrowserPolicyConnector::ChromeBrowserPolicyConnector()
     : BrowserPolicyConnector(base::Bind(&BuildHandlerList)) {
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   chrome_browser_cloud_management_controller_ =
       std::make_unique<ChromeBrowserCloudManagementController>(
           std::make_unique<ChromeBrowserCloudManagementControllerDesktop>());
@@ -104,17 +105,17 @@
 bool ChromeBrowserPolicyConnector::HasMachineLevelPolicies() {
   if (ProviderHasPolicies(GetPlatformProvider()))
     return true;
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   if (ProviderHasPolicies(machine_level_user_cloud_policy_manager_))
     return true;
-#endif  // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   if (ProviderHasPolicies(command_line_provider_))
     return true;
   return false;
 }
 
 void ChromeBrowserPolicyConnector::Shutdown() {
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   // Reset the controller before calling base class so that
   // shutdown occurs in correct sequence.
   chrome_browser_cloud_management_controller_.reset();
@@ -155,7 +156,7 @@
     providers.insert(providers.begin(), std::move(platform_provider));
   }
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<MachineLevelUserCloudPolicyManager>
       machine_level_user_cloud_policy_manager =
           chrome_browser_cloud_management_controller_->CreatePolicyManager(
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.h b/chrome/browser/policy/chrome_browser_policy_connector.h
index 29456ba1..2e669eb 100644
--- a/chrome/browser/policy/chrome_browser_policy_connector.h
+++ b/chrome/browser/policy/chrome_browser_policy_connector.h
@@ -13,6 +13,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 
 class PrefService;
@@ -20,7 +21,7 @@
 namespace policy {
 class ConfigurationPolicyProvider;
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 class ChromeBrowserCloudManagementController;
 class MachineLevelUserCloudPolicyManager;
 #endif
@@ -55,7 +56,7 @@
 
   ConfigurationPolicyProvider* GetPlatformProvider();
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   ChromeBrowserCloudManagementController*
   chrome_browser_cloud_management_controller() {
     return chrome_browser_cloud_management_controller_.get();
@@ -84,7 +85,7 @@
   // Owned by base class.
   ConfigurationPolicyProvider* platform_provider_ = nullptr;
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<ChromeBrowserCloudManagementController>
       chrome_browser_cloud_management_controller_;
   // Owned by base class.
diff --git a/chrome/browser/policy/chrome_browser_policy_connector_unittest.cc b/chrome/browser/policy/chrome_browser_policy_connector_unittest.cc
index 69513885..a144535 100644
--- a/chrome/browser/policy/chrome_browser_policy_connector_unittest.cc
+++ b/chrome/browser/policy/chrome_browser_policy_connector_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/test/task_environment.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_types.h"
@@ -16,7 +17,7 @@
 
 namespace policy {
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
 // HasMachineLevelPolicies() is not implemented on ChromeOS.
 TEST(ChromeBrowserPolicyConnectorTest, HasMachineLevelPolicies) {
   base::test::TaskEnvironment env;
@@ -33,6 +34,6 @@
   EXPECT_TRUE(connector.HasMachineLevelPolicies());
   BrowserPolicyConnectorBase::SetPolicyProviderForTesting(nullptr);
 }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace policy
diff --git a/chrome/browser/policy/chrome_policy_conversions_client.cc b/chrome/browser/policy/chrome_policy_conversions_client.cc
index 9d224b8..a751b0e0 100644
--- a/chrome/browser/policy/chrome_policy_conversions_client.cc
+++ b/chrome/browser/policy/chrome_policy_conversions_client.cc
@@ -10,6 +10,7 @@
 
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
@@ -33,7 +34,7 @@
 #include "extensions/common/manifest_constants.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/active_directory_policy_manager.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
@@ -53,7 +54,7 @@
 
 namespace {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 Value GetIdentityFieldsFromPolicy(
     const enterprise_management::PolicyData* policy) {
   Value identity_fields(Value::Type::DICTIONARY);
@@ -81,7 +82,7 @@
   return identity_fields;
 }
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace
 
@@ -123,13 +124,13 @@
 
   const bool for_signin_screen =
       policy_domain == POLICY_DOMAIN_SIGNIN_EXTENSIONS;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   Profile* extension_profile = for_signin_screen
                                    ? chromeos::ProfileHelper::GetSigninProfile()
                                    : profile_;
-#else   // defined(OS_CHROMEOS)
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
   Profile* extension_profile = profile_;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   const extensions::ExtensionRegistry* registry =
       extensions::ExtensionRegistry::Get(extension_profile);
@@ -175,7 +176,7 @@
   return policies;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 Value ChromePolicyConversionsClient::GetDeviceLocalAccountPolicies() {
   Value policies(Value::Type::LIST);
   // DeviceLocalAccount policies are only available for affiliated users and for
diff --git a/chrome/browser/policy/chrome_policy_conversions_client.h b/chrome/browser/policy/chrome_policy_conversions_client.h
index 4f3c5d4..7e71cd8 100644
--- a/chrome/browser/policy/chrome_policy_conversions_client.h
+++ b/chrome/browser/policy/chrome_policy_conversions_client.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_POLICY_CHROME_POLICY_CONVERSIONS_CLIENT_H_
 #define CHROME_BROWSER_POLICY_CHROME_POLICY_CONVERSIONS_CLIENT_H_
 
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/browser/policy_conversions_client.h"
 
 namespace content {
@@ -35,7 +36,7 @@
   const ConfigurationPolicyHandlerList* GetHandlerList() const override;
   bool HasUserPolicies() const override;
   base::Value GetExtensionPolicies(PolicyDomain policy_domain) override;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   base::Value GetDeviceLocalAccountPolicies() override;
   base::Value GetIdentityFields() override;
 #endif
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
index a683bf9..8ff0569 100644
--- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -17,6 +17,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
@@ -59,7 +60,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
 #include "chromeos/cryptohome/cryptohome_parameters.h"
 #include "chromeos/dbus/constants/dbus_paths.h"
@@ -108,7 +109,7 @@
 }
 
 const char* GetTestUser() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   return user_manager::kStubUserEmail;
 #else
   return "user@example.com";
@@ -215,7 +216,7 @@
         g_browser_process->browser_policy_connector();
     connector->ScheduleServiceInitialization(0);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     UserCloudPolicyManagerChromeOS* policy_manager =
         browser()->profile()->GetUserCloudPolicyManagerChromeOS();
     ASSERT_TRUE(policy_manager);
@@ -235,7 +236,7 @@
         UserCloudPolicyManager::CreateCloudPolicyClient(
             connector->device_management_service(),
             g_browser_process->shared_url_loader_factory()));
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
     ASSERT_TRUE(policy_manager->core()->client());
 
@@ -261,7 +262,7 @@
     // CloudPolicyClient fetch the DMToken.
     ASSERT_FALSE(policy_manager->core()->client()->is_registered());
     CloudPolicyClient::RegistrationParameters parameters(
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
         em::DeviceRegisterRequest::USER,
 #else
         em::DeviceRegisterRequest::BROWSER,
@@ -280,7 +281,7 @@
     policy_manager->core()->client()->AddObserver(
         policy_manager->core()->refresh_scheduler());
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     // Get the path to the user policy key file.
     base::FilePath user_policy_key_dir;
     ASSERT_TRUE(base::PathService::Get(
@@ -362,7 +363,7 @@
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // ENTERPRISE_DEFAULT policies only are supported on Chrome OS currently.
 IN_PROC_BROWSER_TEST_F(CloudPolicyTest, EnsureDefaultPoliciesSet) {
   PolicyService* policy_service = GetPolicyService();
@@ -421,7 +422,7 @@
   policy_service->RemoveObserver(POLICY_DOMAIN_CHROME, this);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(CloudPolicyTest, FetchPolicyWithRotatedKey) {
   PolicyService* policy_service = GetPolicyService();
   {
diff --git a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
index f71b9a6..cf0069d 100644
--- a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "chrome/browser/profiles/profile.h"
@@ -30,7 +31,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
 #else
 #include "chrome/browser/net/system_network_context_manager.h"
@@ -168,7 +169,7 @@
         g_browser_process->browser_policy_connector();
     connector->ScheduleServiceInitialization(0);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     policy_manager()->core()->client()->SetURLLoaderFactoryForTesting(
         test_url_loader_factory_->GetSafeWeakWrapper());
 #else
@@ -192,7 +193,7 @@
     EXPECT_EQ(0, test_url_loader_factory_->NumPending());
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   UserCloudPolicyManagerChromeOS* policy_manager() {
     return browser()->profile()->GetUserCloudPolicyManagerChromeOS();
   }
@@ -200,7 +201,7 @@
   UserCloudPolicyManager* policy_manager() {
     return browser()->profile()->GetUserCloudPolicyManager();
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   // Register the client of the policy_manager() using a bogus auth token, and
   // returns once the registration gets a result back.
@@ -221,7 +222,7 @@
     // Give a bogus OAuth token to the |policy_manager|. This should make its
     // CloudPolicyClient fetch the DMToken.
     CloudPolicyClient::RegistrationParameters parameters(
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
         em::DeviceRegisterRequest::USER,
 #else
         em::DeviceRegisterRequest::BROWSER,
@@ -244,7 +245,7 @@
         // Accept one register request. The initial request should not include
         // the reregister flag.
         em::DeviceRegisterRequest::Type expected_type =
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
             em::DeviceRegisterRequest::USER;
 #else
             em::DeviceRegisterRequest::BROWSER;
@@ -294,7 +295,7 @@
   test_url_loader_factory_->SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
         em::DeviceRegisterRequest::Type expected_type =
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
             em::DeviceRegisterRequest::USER;
 #else
             em::DeviceRegisterRequest::BROWSER;
diff --git a/chrome/browser/policy/cloud/cloud_policy_test_utils.cc b/chrome/browser/policy/cloud/cloud_policy_test_utils.cc
index f5100030..0ebcae8 100644
--- a/chrome/browser/policy/cloud/cloud_policy_test_utils.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_test_utils.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/policy/cloud/cloud_policy_test_utils.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_types.h"
 #include "components/policy/policy_constants.h"
@@ -16,7 +17,7 @@
   policy_map->Set(key::kNTPContentSuggestionsEnabled, POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_USER, POLICY_SOURCE_ENTERPRISE_DEFAULT,
                   base::Value(false), nullptr);
-#elif defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
   SetEnterpriseUsersDefaults(policy_map);
 #endif
 }
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
index 4a37d23..76bb0b0 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -13,6 +13,7 @@
 #include "base/run_loop.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
@@ -38,7 +39,7 @@
 #include "extensions/test/extension_test_message_listener.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
 #include "chromeos/constants/chromeos_switches.h"
 #else
@@ -100,7 +101,7 @@
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     extensions::ExtensionBrowserTest::SetUpCommandLine(command_line);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     // ExtensionBrowserTest sets the login users to a non-managed value;
     // replace it. This is the default username sent in policy blobs from the
     // testserver.
@@ -174,7 +175,7 @@
         g_browser_process->browser_policy_connector();
     connector->ScheduleServiceInitialization(0);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     UserCloudPolicyManagerChromeOS* policy_manager =
         browser()->profile()->GetUserCloudPolicyManagerChromeOS();
     ASSERT_TRUE(policy_manager);
@@ -196,7 +197,7 @@
             connector->device_management_service(),
             g_browser_process->shared_url_loader_factory()));
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
     // Register the cloud policy client.
     client_ = policy_manager->core()->client();
@@ -214,7 +215,7 @@
     client_->RemoveObserver(&observer);
   }
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   void SignOut() {
     auto* primary_account_mutator =
         IdentityManagerFactory::GetForProfile(browser()->profile())
@@ -307,7 +308,7 @@
 // This test verifies that when the user signs out then any existing component
 // policy caches are dropped, and that it's still possible to sign back in and
 // get policy for components working again.
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, SignOutAndBackIn) {
   // Read the initial policy.
   ExtensionTestMessageListener initial_policy_listener(kTestPolicyJSON, true);
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.cc b/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.cc
index 17f0e212..5056bf4 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.cc
@@ -5,11 +5,12 @@
 #include "chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.h"
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
 #include "chrome/browser/policy/cloud/user_cloud_policy_invalidator.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
 #else
 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
@@ -35,7 +36,7 @@
 KeyedService* UserCloudPolicyInvalidatorFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
   Profile* profile = static_cast<Profile*>(context);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   CloudPolicyManager* policy_manager =
       profile->GetUserCloudPolicyManagerChromeOS();
 #else
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index b91f9c3e..7ffc159f 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -111,7 +111,7 @@
 #include "chrome/browser/policy/local_sync_policy_handler.h"
 #endif  // defined(OS_ANDROID)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/public/cpp/ash_pref_names.h"
 #include "chrome/browser/chromeos/accessibility/magnifier_type.h"
 #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
@@ -129,14 +129,14 @@
 #include "components/drive/drive_pref_names.h"  // nogncheck crbug.com/1125897
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
-#else  // defined(OS_CHROMEOS)
+#else  // BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/policy/browser_signin_policy_handler.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/browser_switcher/browser_switcher_prefs.h"
 #include "chrome/browser/external_protocol/auto_launch_protocols_policy_handler.h"
-#endif  // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #include "chrome/browser/extensions/api/messaging/native_messaging_policy_handler.h"
@@ -673,7 +673,7 @@
     base::Value::Type::BOOLEAN },
 #endif  // defined(OS_ANDROID)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   { key::kClientCertificateManagementAllowed,
     prefs::kClientCertificateManagementAllowed,
     base::Value::Type::INTEGER },
@@ -1124,11 +1124,11 @@
   { key::kSystemFeaturesDisableMode,
     policy::policy_prefs::kSystemFeaturesDisableMode,
     base::Value::Type::STRING },
-#else  // defined(OS_CHROMEOS)
+#else // BUILDFLAG(IS_CHROMEOS_ASH)
   { key::kMetricsReportingEnabled,
     metrics::prefs::kMetricsReportingEnabled,
     base::Value::Type::BOOLEAN },
-#endif  // defined(OS_CHROMEOS)
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if defined(OS_WIN)
   { key::kChromeCleanupEnabled,
@@ -1167,7 +1167,7 @@
     base::Value::Type::BOOLEAN },
 #endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
 
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   { key::kNativeMessagingUserLevelHosts,
     extensions::pref_names::kNativeMessagingUserLevelHosts,
     base::Value::Type::BOOLEAN },
@@ -1219,19 +1219,19 @@
   { key::kChromeVariations,
     variations::prefs::kVariationsRestrictionsByPolicy,
     base::Value::Type::INTEGER },
-#endif  // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#endif // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_MAC) && !defined(OS_CHROMEOS)
+#if !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_ASH)
   { key::kBackgroundModeEnabled,
     prefs::kBackgroundModeEnabled,
     base::Value::Type::BOOLEAN },
-#endif  // !defined(OS_MAC) && !defined(OS_CHROMEOS)
+#endif // !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_CHROMEOS)
   { key::kAuthNegotiateDelegateByKdcPolicy,
     prefs::kAuthNegotiateDelegateByKdcPolicy,
     base::Value::Type::BOOLEAN },
-#endif  // defined(OS_LINUX) || defined(OS_MAC) || defined(OS_CHROMEOS)
+#endif // defined(OS_LINUX) || defined(OS_MAC) || defined(OS_CHROMEOS)
 
 #if !defined(OS_MAC)
   { key::kFullscreenAllowed,
@@ -1251,11 +1251,11 @@
     base::Value::Type::LIST },
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
-#if !defined(OS_CHROMEOS) && BUILDFLAG(ENABLE_EXTENSIONS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(ENABLE_EXTENSIONS)
   { key::kBlockExternalExtensions,
     extensions::pref_names::kBlockExternalExtensions,
     base::Value::Type::BOOLEAN },
-#endif  // !defined(OS_CHROMEOS) && BUILDFLAG(ENABLE_EXTENSIONS)
+#endif // !BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(ENABLE_EXTENSIONS)
 
 #if BUILDFLAG(BUILTIN_CERT_VERIFIER_POLICY_SUPPORTED)
   { key::kBuiltinCertificateVerifierEnabled,
@@ -1275,11 +1275,12 @@
     base::Value::Type::BOOLEAN },
 #endif  // BUILDFLAG(ENABLE_SPELLCHECK)
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   { key::kAllowNativeNotifications,
     prefs::kAllowNativeNotifications,
     base::Value::Type::BOOLEAN },
-#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#endif // defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 
   { key::kScrollToTextFragmentEnabled,
     prefs::kScrollToTextFragmentEnabled,
@@ -1312,11 +1313,11 @@
     base::Value::Type::INTEGER },
 #endif  // defined(OS_ANDROID)
 
-#if BUILDFLAG(IS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   { key::kLacrosAllowed,
     prefs::kLacrosAllowed,
     base::Value::Type::BOOLEAN },
-#endif  // BUILDFLAG(IS_ASH)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 };
 // clang-format on
@@ -1351,14 +1352,14 @@
 }  // namespace
 
 void PopulatePolicyHandlerParameters(PolicyHandlerParameters* parameters) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (user_manager::UserManager::IsInitialized()) {
     const user_manager::User* user =
         user_manager::UserManager::Get()->GetActiveUser();
     if (user)
       parameters->user_id_hash = user->username_hash();
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 std::unique_ptr<ConfigurationPolicyHandlerList> BuildHandlerList(
@@ -1543,7 +1544,7 @@
       SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED));
 #endif  // defined(OS_ANDROID)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::vector<std::unique_ptr<ConfigurationPolicyHandler>>
       power_management_idle_legacy_policies;
   power_management_idle_legacy_policies.push_back(
@@ -1787,7 +1788,7 @@
       key::kPrintingAPIExtensionsAllowlist,
       prefs::kPrintingAPIExtensionsAllowlist, /*allow_wildcards=*/false));
 #endif  // defined(USE_CUPS)
-#else   // defined(OS_CHROMEOS)
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
   std::vector<std::unique_ptr<ConfigurationPolicyHandler>>
       signin_legacy_policies;
   signin_legacy_policies.push_back(std::make_unique<SimplePolicyHandler>(
@@ -1807,14 +1808,14 @@
   handlers->AddHandler(std::make_unique<LegacyPoliciesDeprecatingPolicyHandler>(
       std::move(signin_legacy_policies),
       std::make_unique<BrowserSigninPolicyHandler>(chrome_schema)));
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 // On most platforms, there is a legacy policy
 // kUnsafelyTreatInsecureOriginAsSecure which has been replaced by
 // kOverrideSecurityRestrictionsOnInsecureOrigins. The legacy policy was never
 // supported on ChromeOS or Android, so on those platforms, simply use the new
 // one.
-#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID)
   handlers->AddHandler(std::make_unique<SecureOriginPolicyHandler>(
       key::kOverrideSecurityRestrictionsOnInsecureOrigin, chrome_schema));
 #else
@@ -1827,9 +1828,9 @@
       std::move(secure_origin_legacy_policy),
       std::make_unique<SecureOriginPolicyHandler>(
           key::kOverrideSecurityRestrictionsOnInsecureOrigin, chrome_schema)));
-#endif  // defined(OS_CHROMEOS) || defined(OS_ANDROID)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID)
 
-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
   handlers->AddHandler(std::make_unique<DiskCacheDirPolicyHandler>());
 
   handlers->AddHandler(
@@ -1842,7 +1843,7 @@
           extensions::pref_names::kNativeMessagingBlocklist, true));
   handlers->AddHandler(
       std::make_unique<AutoLaunchProtocolsPolicyHandler>(chrome_schema));
-#endif  // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   handlers->AddHandler(std::make_unique<extensions::ExtensionListPolicyHandler>(
diff --git a/chrome/browser/policy/device_management_service_configuration.cc b/chrome/browser/policy/device_management_service_configuration.cc
index 7c7aa3e2..bba36f0 100644
--- a/chrome/browser/policy/device_management_service_configuration.cc
+++ b/chrome/browser/policy/device_management_service_configuration.cc
@@ -10,10 +10,11 @@
 #include "base/strings/stringprintf.h"
 #include "base/system/sys_info.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/version_info/version_info.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chromeos/system/statistics_provider.h"
 #endif
 
@@ -51,7 +52,7 @@
   std::string os_name = base::SysInfo::OperatingSystemName();
   std::string os_hardware = base::SysInfo::OperatingSystemArchitecture();
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::system::StatisticsProvider* provider =
       chromeos::system::StatisticsProvider::GetInstance();
 
@@ -65,7 +66,7 @@
 #endif
 
   std::string os_version("-");
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_CHROMEOS)
+#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
   int32_t os_major_version = 0;
   int32_t os_minor_version = 0;
   int32_t os_bugfix_version = 0;
diff --git a/chrome/browser/policy/dm_token_utils.cc b/chrome/browser/policy/dm_token_utils.cc
index 9cd90fc..ae592f6 100644
--- a/chrome/browser/policy/dm_token_utils.cc
+++ b/chrome/browser/policy/dm_token_utils.cc
@@ -5,9 +5,10 @@
 #include "chrome/browser/policy/dm_token_utils.h"
 
 #include "base/no_destructor.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "components/policy/core/common/cloud/cloud_policy_client.h"
@@ -34,7 +35,7 @@
 DMToken GetDMToken(Profile* const profile, bool only_affiliated) {
   DMToken dm_token = *GetTestingDMTokenStorage();
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (!profile)
     return dm_token;
   auto* policy_manager = profile->GetUserCloudPolicyManagerChromeOS();
diff --git a/chrome/browser/policy/download_directory_browsertest.cc b/chrome/browser/policy/download_directory_browsertest.cc
index 34ffa48..54aae453 100644
--- a/chrome/browser/policy/download_directory_browsertest.cc
+++ b/chrome/browser/policy/download_directory_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/test/test_file_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/policy/policy_test_utils.h"
 #include "chrome/browser/profiles/profile.h"
@@ -24,9 +25,9 @@
 #include "content/public/test/download_test_observer.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 namespace policy {
 
@@ -89,7 +90,7 @@
   EXPECT_FALSE(base::PathExists(initial_dir.Append(file)));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Verifies that the download directory can be forced to Google Drive by policy.
 IN_PROC_BROWSER_TEST_F(PolicyTest, DownloadDirectory_Drive) {
   // Override the download directory with the policy.
@@ -123,6 +124,6 @@
                 .DownloadPath()
                 .StripTrailingSeparators());
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace policy
diff --git a/chrome/browser/policy/enrollment_status.cc b/chrome/browser/policy/enrollment_status.cc
index 3e8efbea..cdccf1b3 100644
--- a/chrome/browser/policy/enrollment_status.cc
+++ b/chrome/browser/policy/enrollment_status.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/policy/enrollment_status.h"
 
+#include "build/chromeos_buildflags.h"
 #include "net/http/http_status_code.h"
 
 namespace policy {
@@ -63,7 +64,7 @@
                                                 validation_status);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // static
 EnrollmentStatus EnrollmentStatus::ForLockError(
     chromeos::InstallAttributes::LockResult lock_status) {
@@ -106,7 +107,7 @@
     int http_status,
     CloudPolicyStore::Status store_status,
     CloudPolicyValidatorBase::Status validation_status) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   return EnrollmentStatus(status, client_status, http_status, store_status,
                           validation_status,
                           chromeos::InstallAttributes::LOCK_SUCCESS);
diff --git a/chrome/browser/policy/enrollment_status.h b/chrome/browser/policy/enrollment_status.h
index 924c0c1..98e3e1d 100644
--- a/chrome/browser/policy/enrollment_status.h
+++ b/chrome/browser/policy/enrollment_status.h
@@ -5,7 +5,8 @@
 #ifndef CHROME_BROWSER_POLICY_ENROLLMENT_STATUS_H_
 #define CHROME_BROWSER_POLICY_ENROLLMENT_STATUS_H_
 
-#if defined(OS_CHROMEOS)
+#include "build/chromeos_buildflags.h"
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chromeos/tpm/install_attributes.h"
 #endif
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
@@ -68,7 +69,7 @@
   static EnrollmentStatus ForStoreError(
       CloudPolicyStore::Status store_error,
       CloudPolicyValidatorBase::Status validation_status);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   static EnrollmentStatus ForLockError(
       chromeos::InstallAttributes::LockResult lock_status);
 #endif
@@ -80,14 +81,14 @@
   CloudPolicyValidatorBase::Status validation_status() const {
     return validation_status_;
   }
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::InstallAttributes::LockResult lock_status() const {
     return lock_status_;
   }
 #endif
 
  private:
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   EnrollmentStatus(Status status,
                    DeviceManagementStatus client_status,
                    int http_status,
@@ -116,7 +117,7 @@
   int http_status_;
   CloudPolicyStore::Status store_status_;
   CloudPolicyValidatorBase::Status validation_status_;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::InstallAttributes::LockResult lock_status_;
 #endif
 };
diff --git a/chrome/browser/policy/extension_force_install_mixin.cc b/chrome/browser/policy/extension_force_install_mixin.cc
index 6f48414..ff4c5f4fa 100644
--- a/chrome/browser/policy/extension_force_install_mixin.cc
+++ b/chrome/browser/policy/extension_force_install_mixin.cc
@@ -26,6 +26,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "base/version.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/crx_file/crx_verifier.h"
 #include "components/crx_file/id_util.h"
@@ -53,7 +54,7 @@
 #include "third_party/zlib/google/zip.h"
 #include "url/gurl.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/login/test/device_state_mixin.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
@@ -103,10 +104,10 @@
 };
 
 std::string GetForceInstallPrefName(Profile* profile) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (chromeos::ProfileHelper::IsSigninProfile(profile))
     return extensions::pref_names::kLoginScreenExtensions;
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   return extensions::pref_names::kInstallForceList;
 }
 
@@ -366,7 +367,7 @@
   mock_policy_provider->UpdateChromePolicy(policy_map);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 
 void UpdatePolicyViaDeviceStateMixin(
     const extensions::ExtensionId& extension_id,
@@ -391,7 +392,7 @@
   device_policy_cros_test_helper->RefreshDevicePolicy();
 }
 
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace
 
@@ -412,7 +413,7 @@
   mock_policy_provider_ = mock_policy_provider;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 
 void ExtensionForceInstallMixin::InitWithDeviceStateMixin(
     Profile* profile,
@@ -436,7 +437,7 @@
   device_policy_cros_test_helper_ = device_policy_cros_test_helper;
 }
 
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 bool ExtensionForceInstallMixin::ForceInstallFromCrx(
     const base::FilePath& crx_path,
@@ -653,7 +654,7 @@
                                       mock_policy_provider_);
     return true;
   }
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (device_state_mixin_) {
     UpdatePolicyViaDeviceStateMixin(extension_id, update_manifest_url,
                                     device_state_mixin_);
@@ -664,7 +665,7 @@
                                               device_policy_cros_test_helper_);
     return true;
   }
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   NOTREACHED() << "Init not called";
   return false;
 }
diff --git a/chrome/browser/policy/extension_force_install_mixin.h b/chrome/browser/policy/extension_force_install_mixin.h
index 668d50a..a3cea1cb 100644
--- a/chrome/browser/policy/extension_force_install_mixin.h
+++ b/chrome/browser/policy/extension_force_install_mixin.h
@@ -10,6 +10,7 @@
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/optional.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/base/mixin_based_in_process_browser_test.h"
 #include "extensions/common/extension_id.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -29,7 +30,7 @@
 class MockConfigurationPolicyProvider;
 }  // namespace policy
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 
 namespace chromeos {
 class DeviceStateMixin;
@@ -39,7 +40,7 @@
 class DevicePolicyCrosTestHelper;
 }  // namespace policy
 
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 // A mixin that allows to force-install an extension/app via the device policy.
 //
@@ -100,13 +101,13 @@
       Profile* profile,
       policy::MockConfigurationPolicyProvider* mock_policy_provider);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void InitWithDeviceStateMixin(Profile* profile,
                                 chromeos::DeviceStateMixin* device_state_mixin);
   void InitWithDevicePolicyCrosTestHelper(
       Profile* profile,
       policy::DevicePolicyCrosTestHelper* device_policy_cros_test_helper);
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   // Force-installs the CRX file |crx_path|; under the hood, generates an update
   // manifest and serves it and the CRX file by the embedded test server.
@@ -186,7 +187,7 @@
   net::EmbeddedTestServer embedded_test_server_;
   Profile* profile_ = nullptr;
   policy::MockConfigurationPolicyProvider* mock_policy_provider_ = nullptr;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::DeviceStateMixin* device_state_mixin_ = nullptr;
   policy::DevicePolicyCrosTestHelper* device_policy_cros_test_helper_ = nullptr;
 #endif
diff --git a/chrome/browser/policy/extension_policy_browsertest.cc b/chrome/browser/policy/extension_policy_browsertest.cc
index 9aa34d83..baae437 100644
--- a/chrome/browser/policy/extension_policy_browsertest.cc
+++ b/chrome/browser/policy/extension_policy_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/background/background_contents_service.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/chrome_content_verifier_delegate.h"
@@ -70,7 +71,7 @@
 #include "base/win/win_util.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/extensions/updater/local_extension_cache.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/web_app_id_constants.h"
@@ -175,10 +176,10 @@
 class ExtensionPolicyTest : public PolicyTest {
  public:
   ExtensionPolicyTest() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     scoped_feature_list_.InitAndDisableFeature(
         chromeos::features::kCameraSystemWebApp);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   }
 
  protected:
@@ -291,7 +292,7 @@
     return return_app_id;
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   const extensions::Extension* InstallOSSettings() {
     WebApplicationInfo web_app;
     web_app.title = base::ASCIIToUTF16("Settings");
@@ -391,7 +392,7 @@
 
 }  // namespace
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Check that component extension can't be blocklisted, besides the camera app
 // that can be disabled by extension policy. This is a temporary solution until
 // there's a dedicated policy to disable the camera, at which point the special
@@ -457,7 +458,7 @@
   extensions::ExtensionService* service = extension_service();
   EXPECT_TRUE(service->IsExtensionEnabled(web_app::kOsSettingsAppId));
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest,
                        ExtensionInstallBlocklistSelective) {
@@ -1054,7 +1055,7 @@
       extension_cache()->GetExtension(kGoodCrxId, "", nullptr, nullptr));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Verifies that if the cache entry contains inconsistent extension version,
 // the crx installation fails and download of a new crx file is attempted.
 IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest, CrxVersionInconsistencyInCache) {
@@ -1151,7 +1152,7 @@
   EXPECT_EQ(version, kGoodCrxVersion);
   EXPECT_NE(file_path, filename);
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest, ExtensionInstallForcelist) {
   // Verifies that extensions that are force-installed by policies are
@@ -2053,7 +2054,7 @@
 
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     command_line->AppendSwitch(
         chromeos::switches::kIgnoreUserProfileMappingForTests);
 #endif
diff --git a/chrome/browser/policy/hide_webstore_icon_policy_browsertest.cc b/chrome/browser/policy/hide_webstore_icon_policy_browsertest.cc
index 58c9ce2..e3e8648 100644
--- a/chrome/browser/policy/hide_webstore_icon_policy_browsertest.cc
+++ b/chrome/browser/policy/hide_webstore_icon_policy_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/policy/policy_test_utils.h"
 #include "chrome/browser/ui/search/instant_test_utils.h"
 #include "chrome/browser/ui/search/local_ntp_test_utils.h"
@@ -81,7 +82,7 @@
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   // Look for web store's app ID in the apps page.
   EXPECT_TRUE(
       ContainsVisibleElement(contents, "ahfgeienlihckogmohjhadlkjgocpleb"));
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 4c76b750..372a3e20 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -52,6 +52,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/browser_app_launcher.h"
@@ -170,7 +171,7 @@
 #include "url/gurl.h"
 #include "url/origin.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/public/cpp/ash_pref_names.h"
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/shell.h"
@@ -209,12 +210,12 @@
 
 namespace {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 const int kOneHourInMs = 60 * 60 * 1000;
 const int kThreeHoursInMs = 180 * 60 * 1000;
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 int CountScreenshots() {
   DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(
       ProfileManager::GetActiveUserProfile());
@@ -321,7 +322,7 @@
   expected_value.SetIntKey(key::kProxyServerMode, 3);
   expected.Set(key::kProxySettings, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_CLOUD, std::move(expected_value), nullptr);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   SetEnterpriseUsersDefaults(&expected);
 #endif
 
@@ -490,7 +491,7 @@
       unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 
 // Flaky on MSan (crbug.com/476964) and regular Chrome OS (crbug.com/645769).
 IN_PROC_BROWSER_TEST_F(PolicyTest, DISABLED_DisableScreenshotsFile) {
@@ -622,7 +623,7 @@
   Mock::VerifyAndClearExpectations(&observer);
 }
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 // Test that TaskManagerInterface::IsEndProcessEnabled is controlled by
 // TaskManagerEndProcessEnabled policy
@@ -651,7 +652,7 @@
   EXPECT_TRUE(task_manager::TaskManagerInterface::IsEndProcessEnabled());
 }
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
 // Similar to PolicyTest but sets the proper policy before the browser is
 // started.
 class PolicyVariationsServiceTest : public PolicyTest {
@@ -681,7 +682,7 @@
 }
 #endif  // !defined(CHROME_OS)
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
 // Sets the hardware acceleration mode policy before the browser is started.
 class HardwareAccelerationModePolicyTest : public PolicyTest {
  public:
@@ -703,9 +704,9 @@
   EXPECT_FALSE(
       content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled());
 }
-#endif  // !defined(OS_CHROMEOS)
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Policy is only available in ChromeOS
 IN_PROC_BROWSER_TEST_F(PolicyTest, UnifiedDesktopEnabledByDefault) {
   // Verify that Unified Desktop can be enabled by policy
@@ -731,7 +732,7 @@
   EXPECT_FALSE(display_manager->unified_desktop_enabled());
 }
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 class NetworkTimePolicyTest : public PolicyTest {
  public:
diff --git a/chrome/browser/policy/policy_network_browsertest.cc b/chrome/browser/policy/policy_network_browsertest.cc
index 612866b..8b9fc9e 100644
--- a/chrome/browser/policy/policy_network_browsertest.cc
+++ b/chrome/browser/policy/policy_network_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "chrome/browser/policy/profile_policy_connector_builder.h"
@@ -42,7 +43,7 @@
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/mojom/network_service_test.mojom.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chromeos/constants/chromeos_switches.h"
 #endif
 
@@ -250,7 +251,7 @@
 // some particular order.
 
 // TODO(crbug.com/938139): Flaky on ChromeOS with Network Service
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_QuicAllowedForSystem DISABLED_QuicAllowedForSystem
 #else
 #define MAYBE_QuicAllowedForSystem QuicAllowedForSystem
@@ -324,7 +325,7 @@
 
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     command_line->AppendSwitch(
         chromeos::switches::kIgnoreUserProfileMappingForTests);
 #endif
diff --git a/chrome/browser/policy/policy_test_utils.cc b/chrome/browser/policy/policy_test_utils.cc
index ee91724..6c9f6db 100644
--- a/chrome/browser/policy/policy_test_utils.cc
+++ b/chrome/browser/policy/policy_test_utils.cc
@@ -9,6 +9,7 @@
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/current_thread.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h"
@@ -39,7 +40,7 @@
 #include "net/http/transport_security_state.h"
 #include "services/network/public/mojom/network_service_test.mojom.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ui/snapshot/screenshot_grabber.h"
 #endif
 
@@ -145,7 +146,7 @@
                      required));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 class QuitMessageLoopAfterScreenshot
     : public ChromeScreenshotGrabberTestObserver {
  public:
@@ -175,7 +176,7 @@
 
   grabber->test_observer_ = nullptr;
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 scoped_refptr<const extensions::Extension> PolicyTest::LoadUnpackedExtension(
     const base::FilePath::StringType& name) {
@@ -188,7 +189,7 @@
 void PolicyTest::UpdateProviderPolicy(const PolicyMap& policy) {
   PolicyMap policy_with_defaults;
   policy_with_defaults.CopyFrom(policy);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   SetEnterpriseUsersDefaults(&policy_with_defaults);
 #endif
   provider_.UpdateChromePolicy(policy_with_defaults);
@@ -233,7 +234,7 @@
   UpdateProviderPolicy(policies);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void PolicyTest::SetEnableFlag(const keyboard::KeyboardEnableFlag& flag) {
   auto* keyboard_client = ChromeKeyboardControllerClient::Get();
   keyboard_client->SetEnableFlag(flag);
@@ -243,7 +244,7 @@
   auto* keyboard_client = ChromeKeyboardControllerClient::Get();
   keyboard_client->ClearEnableFlag(flag);
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 // static
 GURL PolicyTest::GetExpectedSearchURL(bool expect_safe_search) {
diff --git a/chrome/browser/policy/policy_test_utils.h b/chrome/browser/policy/policy_test_utils.h
index 8ea82bf..a3158dd 100644
--- a/chrome/browser/policy/policy_test_utils.h
+++ b/chrome/browser/policy/policy_test_utils.h
@@ -9,6 +9,7 @@
 
 #include "ash/public/cpp/keyboard/keyboard_types.h"
 #include "base/files/file_path.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
@@ -77,13 +78,13 @@
                              base::Optional<base::Value> legacy_youtube,
                              base::Optional<base::Value> youtube_restrict);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void TestScreenshotFile(bool enabled);
 
   void SetEnableFlag(const keyboard::KeyboardEnableFlag& flag);
 
   void ClearEnableFlag(const keyboard::KeyboardEnableFlag& flag);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   static GURL GetExpectedSearchURL(bool expect_safe_search);
 
diff --git a/chrome/browser/policy/printing_restrictions_policy_handler.cc b/chrome/browser/policy/printing_restrictions_policy_handler.cc
index 44cca7e..de8c7e9a 100644
--- a/chrome/browser/policy/printing_restrictions_policy_handler.cc
+++ b/chrome/browser/policy/printing_restrictions_policy_handler.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/policy/printing_restrictions_policy_handler.h"
 
+#include "build/chromeos_buildflags.h"
 #include "chrome/common/pref_names.h"
 #include "components/policy/core/browser/policy_error_map.h"
 #include "components/policy/policy_constants.h"
@@ -63,7 +64,7 @@
   return false;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 PrintingAllowedColorModesPolicyHandler::PrintingAllowedColorModesPolicyHandler()
     : PrintingEnumPolicyHandler<printing::ColorModeRestriction>(
           key::kPrintingAllowedColorModes,
@@ -139,7 +140,7 @@
           }) {}
 
 PrintingPinDefaultPolicyHandler::~PrintingPinDefaultPolicyHandler() = default;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 PrintingAllowedBackgroundGraphicsModesPolicyHandler::
     PrintingAllowedBackgroundGraphicsModesPolicyHandler()
diff --git a/chrome/browser/policy/printing_restrictions_policy_handler.h b/chrome/browser/policy/printing_restrictions_policy_handler.h
index 1db3a1f..c0edfcc 100644
--- a/chrome/browser/policy/printing_restrictions_policy_handler.h
+++ b/chrome/browser/policy/printing_restrictions_policy_handler.h
@@ -9,6 +9,7 @@
 
 #include "base/containers/flat_map.h"
 #include "base/values.h"
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/browser/configuration_policy_handler.h"
 #include "printing/backend/printing_restrictions.h"
 
@@ -46,7 +47,7 @@
   base::flat_map<std::string, Mode> policy_value_to_mode_;
 };
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 class PrintingAllowedColorModesPolicyHandler
     : public PrintingEnumPolicyHandler<printing::ColorModeRestriction> {
  public:
@@ -88,7 +89,7 @@
   PrintingPinDefaultPolicyHandler();
   ~PrintingPinDefaultPolicyHandler() override;
 };
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 class PrintingAllowedBackgroundGraphicsModesPolicyHandler
     : public PrintingEnumPolicyHandler<
diff --git a/chrome/browser/policy/profile_policy_connector.cc b/chrome/browser/policy/profile_policy_connector.cc
index 91ad8393..bb50020d 100644
--- a/chrome/browser/policy/profile_policy_connector.cc
+++ b/chrome/browser/policy/profile_policy_connector.cc
@@ -13,6 +13,7 @@
 #include "base/timer/timer.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_switcher/browser_switcher_policy_migrator.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
@@ -29,7 +30,7 @@
 #include "components/policy/core/common/schema_registry_tracking_policy_provider.h"
 #include "components/policy/policy_constants.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/chromeos/policy/active_directory_policy_manager.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -44,7 +45,7 @@
 
 namespace policy {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 namespace internal {
 
 // This class allows observing a |device_wide_policy_service| for policy updates
@@ -133,7 +134,7 @@
 }
 }  // namespace
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 ProfilePolicyConnector::ProfilePolicyConnector() = default;
 
@@ -149,7 +150,7 @@
   configuration_policy_provider_ = configuration_policy_provider;
   policy_store_ = policy_store;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   auto* browser_policy_connector =
       static_cast<BrowserPolicyConnectorChromeOS*>(connector);
 #else
@@ -166,7 +167,7 @@
     policy_providers_.push_back(wrapped_platform_policy_provider_.get());
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (browser_policy_connector->GetDeviceCloudPolicyManager()) {
     policy_providers_.push_back(
         browser_policy_connector->GetDeviceCloudPolicyManager());
@@ -193,7 +194,7 @@
   if (configuration_policy_provider)
     policy_providers_.push_back(configuration_policy_provider);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (!user) {
     DCHECK(schema_registry);
     // This case occurs for the signin and the lock screen app profiles.
@@ -223,7 +224,7 @@
       std::make_unique<browser_switcher::BrowserSwitcherPolicyMigrator>());
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   migrators.push_back(std::make_unique<LegacyChromePolicyMigrator>(
       policy::key::kDeviceNativePrinters, policy::key::kDevicePrinters));
   migrators.push_back(std::make_unique<LegacyChromePolicyMigrator>(
@@ -259,10 +260,10 @@
     policy_service_ = std::make_unique<PolicyServiceImpl>(policy_providers_,
                                                           std::move(migrators));
   }
-#else   // defined(OS_CHROMEOS)
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
   policy_service_ = std::make_unique<PolicyServiceImpl>(policy_providers_,
                                                         std::move(migrators));
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void ProfilePolicyConnector::InitForTesting(
@@ -281,7 +282,7 @@
 }
 
 void ProfilePolicyConnector::Shutdown() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (is_primary_user_)
     GetProxyPolicyProvider()->SetDelegate(nullptr);
 
@@ -308,17 +309,17 @@
   return provider == configuration_policy_provider_;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void ProfilePolicyConnector::TriggerProxiedPoliciesWaitTimeoutForTesting() {
   CHECK(proxied_policies_propagated_watcher_);
   proxied_policies_propagated_watcher_->OnProviderUpdatePropagationTimedOut();
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 const CloudPolicyStore* ProfilePolicyConnector::GetActualPolicyStore() const {
   if (policy_store_)
     return policy_store_;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (special_user_policy_provider_) {
     // |special_user_policy_provider_| is non-null for device-local accounts,
     // for the login profile, and the lock screen app profile.
@@ -352,7 +353,7 @@
   return browser_policy_connector->GetPlatformProvider();
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 std::unique_ptr<PolicyService>
 ProfilePolicyConnector::CreatePolicyServiceWithInitializationThrottled(
     const std::vector<ConfigurationPolicyProvider*>& policy_providers,
diff --git a/chrome/browser/policy/profile_policy_connector.h b/chrome/browser/policy/profile_policy_connector.h
index bc72ad1..5f373c3 100644
--- a/chrome/browser/policy/profile_policy_connector.h
+++ b/chrome/browser/policy/profile_policy_connector.h
@@ -11,17 +11,18 @@
 
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 
 namespace user_manager {
 class User;
 }
 
 namespace policy {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 namespace internal {
 class ProxiedPoliciesPropagatedWatcher;
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 class CloudPolicyStore;
 class ConfigurationPolicyProvider;
@@ -74,11 +75,11 @@
   // higher-level provider.
   bool IsProfilePolicy(const char* policy_key) const;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Triggers the time out handling of waiting for the proxied primary user
   // policies to propagate. May be only called form tests.
   void TriggerProxiedPoliciesWaitTimeoutForTesting();
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
  private:
   // Returns the policy store which is actually used.
@@ -96,7 +97,7 @@
   ConfigurationPolicyProvider* GetPlatformProvider(
       policy::ChromeBrowserPolicyConnector* browser_policy_connector);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // On Chrome OS, primary Profile user policies are forwarded to the
   // device-global PolicyService[1] using a ProxyPolicyProvider.
   // When that is done, signaling that |policy_service_| is initialized should
@@ -142,7 +143,7 @@
   std::unique_ptr<internal::ProxiedPoliciesPropagatedWatcher>
       proxied_policies_propagated_watcher_;
 
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   std::unique_ptr<ConfigurationPolicyProvider>
       wrapped_platform_policy_provider_;
diff --git a/chrome/browser/policy/profile_policy_connector_builder.cc b/chrome/browser/policy/profile_policy_connector_builder.cc
index fcdb8a37..f41630e7 100644
--- a/chrome/browser/policy/profile_policy_connector_builder.cc
+++ b/chrome/browser/policy/profile_policy_connector_builder.cc
@@ -9,13 +9,14 @@
 
 #include "base/no_destructor.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/policy/schema_registry_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/policy/core/common/policy_service.h"
 #include "components/policy/core/common/policy_service_impl.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/active_directory_policy_manager.h"
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
@@ -45,7 +46,7 @@
   ConfigurationPolicyProvider* policy_provider = nullptr;
   const CloudPolicyStore* policy_store = nullptr;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   Profile* const profile = Profile::FromBrowserContext(context);
   if (!chromeos::ProfileHelper::IsSigninProfile(profile) &&
       !chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) {
@@ -73,7 +74,7 @@
     policy_provider = user_cloud_policy_manager;
     policy_store = user_cloud_policy_manager->core()->store();
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   return CreateAndInitProfilePolicyConnector(
       schema_registry, browser_policy_connector, policy_provider, policy_store,
diff --git a/chrome/browser/policy/profile_policy_connector_unittest.cc b/chrome/browser/policy/profile_policy_connector_unittest.cc
index 14b9160..cad5807 100644
--- a/chrome/browser/policy/profile_policy_connector_unittest.cc
+++ b/chrome/browser/policy/profile_policy_connector_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/test/task_environment.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/account_id/account_id.h"
 #include "components/autofill/core/common/autofill_prefs.h"
@@ -29,11 +30,11 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chromeos/tpm/stub_install_attributes.h"
 #include "components/user_manager/scoped_user_manager.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 using testing::Return;
 using testing::_;
@@ -119,9 +120,9 @@
   MockCloudPolicyStore cloud_policy_store_;
   std::unique_ptr<CloudPolicyManager> cloud_policy_manager_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::ScopedStubInstallAttributes test_install_attributes_;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 };
 
 TEST_F(ProfilePolicyConnectorTest, IsManagedForManagedUsers) {
@@ -142,7 +143,7 @@
   connector.Shutdown();
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(ProfilePolicyConnectorTest, IsManagedForActiveDirectoryUsers) {
   user_manager::ScopedUserManager scoped_user_manager_enabler(
       std::make_unique<chromeos::FakeChromeUserManager>());
@@ -221,7 +222,7 @@
   // Cleanup.
   connector.Shutdown();
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 TEST_F(ProfilePolicyConnectorTest, IsProfilePolicy) {
   MockConfigurationPolicyProvider mock_platform_provider;
diff --git a/chrome/browser/policy/restore_on_startup_policy_browsertest.cc b/chrome/browser/policy/restore_on_startup_policy_browsertest.cc
index 890ba80b..e12c63e 100644
--- a/chrome/browser/policy/restore_on_startup_policy_browsertest.cc
+++ b/chrome/browser/policy/restore_on_startup_policy_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/command_line.h"
 #include "base/stl_util.h"
 #include "base/values.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/policy/policy_test_utils.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/resource_coordinator/tab_load_tracker_test_support.h"
@@ -55,7 +56,7 @@
   RestoreOnStartupPolicyTest() = default;
   ~RestoreOnStartupPolicyTest() override = default;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void SetUpCommandLine(base::CommandLine* command_line) override {
     // TODO(nkostylev): Investigate if we can remove this switch.
     command_line->AppendSwitch(switches::kCreateBrowserOnStartupForTests);
diff --git a/chrome/browser/policy/schema_registry_service_builder.cc b/chrome/browser/policy/schema_registry_service_builder.cc
index c212177..be87ff10 100644
--- a/chrome/browser/policy/schema_registry_service_builder.cc
+++ b/chrome/browser/policy/schema_registry_service_builder.cc
@@ -8,12 +8,13 @@
 
 #include "base/check.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/policy/schema_registry_service.h"
 #include "components/policy/core/common/schema.h"
 #include "components/policy/core/common/schema_registry.h"
 #include "content/public/browser/browser_context.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/browser/chromeos/policy/active_directory_policy_manager.h"
@@ -28,7 +29,7 @@
 
 namespace policy {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 namespace {
 
 DeviceLocalAccountPolicyBroker* GetBroker(content::BrowserContext* context) {
@@ -58,7 +59,7 @@
 }
 
 }  // namespace
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 std::unique_ptr<SchemaRegistryService> BuildSchemaRegistryServiceForProfile(
     content::BrowserContext* context,
@@ -68,7 +69,7 @@
 
   std::unique_ptr<SchemaRegistry> registry;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   DeviceLocalAccountPolicyBroker* broker = GetBroker(context);
   if (broker) {
     // The SchemaRegistry for a device-local account is owned by its
@@ -82,7 +83,7 @@
   if (!registry)
     registry.reset(new SchemaRegistry);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   Profile* const profile = Profile::FromBrowserContext(context);
   if (chromeos::ProfileHelper::IsSigninProfile(profile)) {
     // Pass the SchemaRegistry of the signin profile to the device policy
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
index 39fc46ab..1b5a903c 100644
--- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
+++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/common/pref_names.h"
 #include "components/content_settings/core/common/pref_names.h"
 #include "components/policy/core/browser/policy_error_map.h"
@@ -48,7 +49,7 @@
       chrome_schema);
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // static
 std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler>
 WebUsbAllowDevicesForUrlsPolicyHandler::CreateForDevicePolicy(
@@ -64,7 +65,7 @@
   registry->RegisterListPref(
       prefs::kDeviceLoginScreenWebUsbAllowDevicesForUrls);
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 WebUsbAllowDevicesForUrlsPolicyHandler::WebUsbAllowDevicesForUrlsPolicyHandler(
     const char* policy_name,
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h
index a4a13d2..5d44bde 100644
--- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h
+++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/browser/configuration_policy_handler.h"
 
 class PrefRegistrySimple;
@@ -24,12 +25,12 @@
   static std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler>
   CreateForUserPolicy(const Schema& chrome_schema);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   static std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler>
   CreateForDevicePolicy(const Schema& chrome_schema);
 
   static void RegisterPrefs(PrefRegistrySimple* registry);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   WebUsbAllowDevicesForUrlsPolicyHandler(const char* policy_name,
                                          const char* pref_name,
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc
index 7526efc..403dcf3 100644
--- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc
+++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/json/json_reader.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/common/pref_names.h"
 #include "components/content_settings/core/common/pref_names.h"
 #include "components/policy/core/browser/configuration_policy_pref_store.h"
@@ -210,30 +211,30 @@
     ])";
 
 std::string GetPolicyName(PolicyType policy_type) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (policy_type == PolicyType::kDevice)
     return key::kDeviceLoginScreenWebUsbAllowDevicesForUrls;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   return key::kWebUsbAllowDevicesForUrls;
 }
 
 std::string GetPrefName(PolicyType policy_type) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (policy_type == PolicyType::kDevice)
     return prefs::kDeviceLoginScreenWebUsbAllowDevicesForUrls;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   return prefs::kManagedWebUsbAllowDevicesForUrls;
 }
 
 std::unique_ptr<WebUsbAllowDevicesForUrlsPolicyHandler> CreateHandler(
     PolicyType policy_type,
     const Schema& chrome_schema) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (policy_type == PolicyType::kDevice) {
     return WebUsbAllowDevicesForUrlsPolicyHandler::CreateForDevicePolicy(
         chrome_schema);
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   return WebUsbAllowDevicesForUrlsPolicyHandler::CreateForUserPolicy(
       chrome_schema);
 }
@@ -755,7 +756,7 @@
 // other operating systems, this test just tests the user policy.
 INSTANTIATE_TEST_SUITE_P(All,
                          WebUsbAllowDevicesForUrlsPolicyHandlerTest,
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
                          testing::Values(PolicyType::kUser, PolicyType::kDevice)
 #else
                          testing::Values(PolicyType::kUser)
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 442d1e74..c10f37da 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -11,11 +11,8 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
-#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profile_observer.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
@@ -24,12 +21,8 @@
 #include "components/media_router/common/pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
-#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
-#include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
-#include "components/sync/driver/sync_service.h"
-#include "components/variations/proto/study.pb.h"
 #include "components/variations/variations.mojom.h"
 #include "components/variations/variations_client.h"
 #include "components/variations/variations_ids_provider.h"
@@ -42,7 +35,6 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/command_line.h"
-#include "chrome/common/chrome_switches.h"
 #include "chromeos/constants/chromeos_switches.h"
 #endif
 
diff --git a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
index 27906b6..8ee988c 100644
--- a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
+++ b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
@@ -89,8 +89,8 @@
           <div id="arcPaiService" class="parameter-section arc-tos-content">
             <p>
               <span>[[i18nDynamic(locale, 'arcTextPaiService')]]</span>
-              <a href="#" id="learnMoreLinkPai"
-                  on-click="onPaiLearnMoreTap_">
+              <a id="learnMoreLinkPai" class="oobe-local-link"
+                  on-click="onPaiLearnMoreTap_" is="action-link">
                 [[i18nDynamic(locale, 'arcLearnMoreText')]]
               </a>
             </p>
diff --git a/chrome/browser/resources/chromeos/login/cr_ui.js b/chrome/browser/resources/chromeos/login/cr_ui.js
index d7d6a91..6f81cd8 100644
--- a/chrome/browser/resources/chromeos/login/cr_ui.js
+++ b/chrome/browser/resources/chromeos/login/cr_ui.js
@@ -32,6 +32,28 @@
   };
 
   /**
+   * OOBE initialization coordination. Used by tests to wait for OOBE
+   * to fully load when using the HTLImports polyfill.
+   * TODO(crbug.com/1111387) - Remove once migrated to JS modules.
+   * Remove spammy logging when closer to M89 branch point.
+   */
+  Oobe.initializationComplete = false;
+  Oobe.initCallbacks = [];
+  Oobe.waitForOobeToLoad = function() {
+    return new Promise(function(resolve, reject) {
+      if (cr.ui.Oobe.initializationComplete) {
+        // TODO(crbug.com/1111387) - Remove excessive logging.
+        console.warn('OOBE is already initialized. Continuing...');
+        resolve();
+      } else {
+        // TODO(crbug.com/1111387) - Remove excessive logging.
+        console.warn('OOBE not loaded yet. Waiting...');
+        cr.ui.Oobe.initCallbacks.push(resolve);
+      }
+    });
+  };
+
+  /**
    * Called when focus is returned from ash::SystemTray.
    * @param {boolean} reverse Is focus returned in reverse order?
    */
diff --git a/chrome/browser/resources/chromeos/login/md_login.html b/chrome/browser/resources/chromeos/login/md_login.html
index 8169690..045e89af 100644
--- a/chrome/browser/resources/chromeos/login/md_login.html
+++ b/chrome/browser/resources/chromeos/login/md_login.html
@@ -7,6 +7,7 @@
 <meta charset="utf-8">
 <meta name="google" value="notranslate">
 <title i18n-content="title"></title>
+<script src="chrome://resources/polymer/v1_0/html-imports/html-imports.min.js"></script>
 <!-- This must be the first import in all login pages. -->
 <link rel="import" href="chrome://resources/html/polymer.html">
 
diff --git a/chrome/browser/resources/chromeos/login/md_login.js b/chrome/browser/resources/chromeos/login/md_login.js
index a7253b2..aa9707e 100644
--- a/chrome/browser/resources/chromeos/login/md_login.js
+++ b/chrome/browser/resources/chromeos/login/md_login.js
@@ -40,60 +40,61 @@
   setTimeout(onLoaded);
 }
 
-cr.define('cr.ui.Oobe', function() {
-  return {
-    /**
-     * Initializes the OOBE flow.  This will cause all C++ handlers to
-     * be invoked to do final setup.
-     */
-    initialize() {
-      cr.ui.login.DisplayManager.initialize();
-      login.AccountPickerScreen.register();
-      login.AutolaunchScreen.register();
-      login.ErrorMessageScreen.register();
-      login.ArcTermsOfServiceScreen.register();
-      login.DiscoverScreen.register();
-      login.MultiDeviceSetupScreen.register();
+HTMLImports.whenReady(() => {
+  cr.define('cr.ui.Oobe', function() {
+    return {
+      /**
+       * Initializes the OOBE flow.  This will cause all C++ handlers to
+       * be invoked to do final setup.
+       */
+      initialize() {
+        cr.ui.login.DisplayManager.initialize();
+        login.AccountPickerScreen.register();
+        login.AutolaunchScreen.register();
+        login.ErrorMessageScreen.register();
+        login.ArcTermsOfServiceScreen.register();
+        login.DiscoverScreen.register();
+        login.MultiDeviceSetupScreen.register();
 
-      cr.ui.Bubble.decorate($('bubble-persistent'));
-      $('bubble-persistent').persistent = true;
-      $('bubble-persistent').hideOnKeyPress = false;
+        cr.ui.Bubble.decorate($('bubble-persistent'));
+        $('bubble-persistent').persistent = true;
+        $('bubble-persistent').hideOnKeyPress = false;
 
-      cr.ui.Bubble.decorate($('bubble'));
+        cr.ui.Bubble.decorate($('bubble'));
 
-      chrome.send('screenStateInitialize');
-    },
+        chrome.send('screenStateInitialize');
+      },
 
-    // Dummy Oobe functions not present with stripped login UI.
-    refreshA11yInfo(data) {},
-    reloadEulaContent(data) {},
+      // Dummy Oobe functions not present with stripped login UI.
+      refreshA11yInfo(data) {},
+      reloadEulaContent(data) {},
 
-    /**
-     * Reloads content of the page.
-     * @param {!Object} data New dictionary with i18n values.
-     */
-    reloadContent(data) {
-      loadTimeData.overrideValues(data);
-      i18nTemplate.process(document, loadTimeData);
-      Oobe.getInstance().updateLocalizedContent_();
-    },
+      /**
+       * Reloads content of the page.
+       * @param {!Object} data New dictionary with i18n values.
+       */
+      reloadContent(data) {
+        loadTimeData.overrideValues(data);
+        i18nTemplate.process(document, loadTimeData);
+        Oobe.getInstance().updateLocalizedContent_();
+      },
 
-    /**
-     * Updates "device in tablet mode" state when tablet mode is changed.
-     * @param {Boolean} isInTabletMode True when in tablet mode.
-     */
-    setTabletModeState(isInTabletMode) {
-      Oobe.getInstance().setTabletModeState_(isInTabletMode);
-    },
+      /**
+       * Updates "device in tablet mode" state when tablet mode is changed.
+       * @param {Boolean} isInTabletMode True when in tablet mode.
+       */
+      setTabletModeState(isInTabletMode) {
+        Oobe.getInstance().setTabletModeState_(isInTabletMode);
+      },
 
-    /**
-     * Updates OOBE configuration when it is loaded.
-     * @param {!OobeTypes.OobeConfiguration} configuration OOBE configuration.
-     */
-    updateOobeConfiguration(configuration) {
-      Oobe.getInstance().updateOobeConfiguration_(configuration);
-    },
-  };
+      /**
+       * Updates OOBE configuration when it is loaded.
+       * @param {!OobeTypes.OobeConfiguration} configuration OOBE configuration.
+       */
+      updateOobeConfiguration(configuration) {
+        Oobe.getInstance().updateOobeConfiguration_(configuration);
+      },
+    };
+  });
+  // <include src="oobe_initialization.js">
 });
-
-// <include src="oobe_initialization.js">
\ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/login/oobe.html b/chrome/browser/resources/chromeos/login/oobe.html
index 7dc40c06..36890e6 100644
--- a/chrome/browser/resources/chromeos/login/oobe.html
+++ b/chrome/browser/resources/chromeos/login/oobe.html
@@ -7,6 +7,7 @@
 <meta charset="utf-8">
 <meta name="google" value="notranslate">
 <title i18n-content="title"></title>
+<script src="chrome://resources/polymer/v1_0/html-imports/html-imports.min.js"></script>
 <!-- This must be the first import in all login pages. -->
 <link rel="import" href="chrome://resources/html/polymer.html">
 
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js
index ff056d3..2c41bc4b 100644
--- a/chrome/browser/resources/chromeos/login/oobe.js
+++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -33,79 +33,80 @@
 // <include src="multi_tap_detector.js">
 // <include src="web_view_helper.js">
 
-cr.define('cr.ui.Oobe', function() {
-  return {
-    /**
-     * Initializes the OOBE flow.  This will cause all C++ handlers to
-     * be invoked to do final setup.
-     */
-    initialize() {
-      cr.ui.login.DisplayManager.initialize();
-      login.AutoEnrollmentCheckScreen.register();
-      login.AutolaunchScreen.register();
-      login.AccountPickerScreen.register();
-      login.ErrorMessageScreen.register();
-      login.ArcTermsOfServiceScreen.register();
-      login.DiscoverScreen.register();
-      login.MultiDeviceSetupScreen.register();
+HTMLImports.whenReady(() => {
+  cr.define('cr.ui.Oobe', function() {
+    return {
+      /**
+       * Initializes the OOBE flow.  This will cause all C++ handlers to
+       * be invoked to do final setup.
+       */
+      initialize() {
+        cr.ui.login.DisplayManager.initialize();
+        login.AutoEnrollmentCheckScreen.register();
+        login.AutolaunchScreen.register();
+        login.AccountPickerScreen.register();
+        login.ErrorMessageScreen.register();
+        login.ArcTermsOfServiceScreen.register();
+        login.DiscoverScreen.register();
+        login.MultiDeviceSetupScreen.register();
 
-      cr.ui.Bubble.decorate($('bubble-persistent'));
-      $('bubble-persistent').persistent = true;
-      $('bubble-persistent').hideOnKeyPress = false;
+        cr.ui.Bubble.decorate($('bubble-persistent'));
+        $('bubble-persistent').persistent = true;
+        $('bubble-persistent').hideOnKeyPress = false;
 
-      cr.ui.Bubble.decorate($('bubble'));
+        cr.ui.Bubble.decorate($('bubble'));
 
-      chrome.send('screenStateInitialize');
-    },
+        chrome.send('screenStateInitialize');
+      },
 
-    /**
-     * Reloads content of the page (localized strings, options of the select
-     * controls).
-     * @param {!Object} data New dictionary with i18n values.
-     */
-    reloadContent(data) {
-      // Reload global local strings, process DOM tree again.
-      loadTimeData.overrideValues(data);
-      i18nTemplate.process(document, loadTimeData);
+      /**
+       * Reloads content of the page (localized strings, options of the select
+       * controls).
+       * @param {!Object} data New dictionary with i18n values.
+       */
+      reloadContent(data) {
+        // Reload global local strings, process DOM tree again.
+        loadTimeData.overrideValues(data);
+        i18nTemplate.process(document, loadTimeData);
 
-      // Update localized content of the screens.
-      Oobe.updateLocalizedContent();
-    },
+        // Update localized content of the screens.
+        Oobe.updateLocalizedContent();
+      },
 
-    /**
-     * Updates "device in tablet mode" state when tablet mode is changed.
-     * @param {Boolean} isInTabletMode True when in tablet mode.
-     */
-    setTabletModeState(isInTabletMode) {
-      Oobe.getInstance().setTabletModeState_(isInTabletMode);
-    },
+      /**
+       * Updates "device in tablet mode" state when tablet mode is changed.
+       * @param {Boolean} isInTabletMode True when in tablet mode.
+       */
+      setTabletModeState(isInTabletMode) {
+        Oobe.getInstance().setTabletModeState_(isInTabletMode);
+      },
 
-    /**
-     * Reloads localized strings for the eula page.
-     * @param {!Object} data New dictionary with changed eula i18n values.
-     */
-    reloadEulaContent(data) {
-      loadTimeData.overrideValues(data);
-      i18nTemplate.process(document, loadTimeData);
-    },
+      /**
+       * Reloads localized strings for the eula page.
+       * @param {!Object} data New dictionary with changed eula i18n values.
+       */
+      reloadEulaContent(data) {
+        loadTimeData.overrideValues(data);
+        i18nTemplate.process(document, loadTimeData);
+      },
 
-    /**
-     * Updates localized content of the screens.
-     * Should be executed on language change.
-     */
-    updateLocalizedContent() {
-      // Buttons, headers and links.
-      Oobe.getInstance().updateLocalizedContent_();
-    },
+      /**
+       * Updates localized content of the screens.
+       * Should be executed on language change.
+       */
+      updateLocalizedContent() {
+        // Buttons, headers and links.
+        Oobe.getInstance().updateLocalizedContent_();
+      },
 
-    /**
-     * Updates OOBE configuration when it is loaded.
-     * @param {!OobeTypes.OobeConfiguration} configuration OOBE configuration.
-     */
-    updateOobeConfiguration(configuration) {
-      Oobe.getInstance().updateOobeConfiguration_(configuration);
-    },
-  };
+      /**
+       * Updates OOBE configuration when it is loaded.
+       * @param {!OobeTypes.OobeConfiguration} configuration OOBE configuration.
+       */
+      updateOobeConfiguration(configuration) {
+        Oobe.getInstance().updateOobeConfiguration_(configuration);
+      },
+    };
+  });
+  // <include src="oobe_initialization.js">
 });
-
-// <include src="oobe_initialization.js">
diff --git a/chrome/browser/resources/chromeos/login/oobe_initialization.js b/chrome/browser/resources/chromeos/login/oobe_initialization.js
index bcaecea..4590618 100644
--- a/chrome/browser/resources/chromeos/login/oobe_initialization.js
+++ b/chrome/browser/resources/chromeos/login/oobe_initialization.js
@@ -28,6 +28,11 @@
     // readyForTesting even on failures, just to make test bots happy.
     Oobe.readyForTesting = true;
   }
+
+  // Mark initialization complete and wake any callers that might be waiting
+  // for OOBE to load.
+  cr.ui.Oobe.initializationComplete = true;
+  cr.ui.Oobe.initCallbacks.forEach(resolvePromise => resolvePromise());
 }
 
 // Install a global error handler so stack traces are included in logs.
@@ -40,11 +45,18 @@
 console.warn('1082670 : cr_ui loaded');
 
 /**
- * Final initialization performed after DOM and all scripts have loaded.
+ * Final initialization performed after HTML imports are loaded. Loads
+ * common elements used in OOBE (Custom Elements).
  */
-if (document.readyState === 'loading') {
-  document.addEventListener('DOMContentLoaded', initializeOobe);
-} else {
-  initializeOobe();
-}
+HTMLImports.whenReady(() => {
+  // TODO(crbug.com/1111387) - Remove excessive logging.
+  console.warn('HTMLImports ready.');
+  loadCommonComponents();
+
+  if (document.readyState === 'loading') {
+    document.addEventListener('DOMContentLoaded', initializeOobe);
+  } else {
+    initializeOobe();
+  }
+});
 })();
diff --git a/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js b/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
index c21f84f..97e0423 100644
--- a/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
+++ b/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
@@ -18,6 +18,15 @@
     return 'chrome://oobe/login';
   }
 
+  /** @override */
+  setUp() {
+    suiteSetup(async function() {
+      console.warn('Running suite setup..');
+      await cr.ui.Oobe.waitForOobeToLoad();
+      console.warn('OOBE has been loaded. Continuing with test.');
+    });
+  }
+
   get extraLibraries() {
     return super.extraLibraries.concat(['components/oobe_types.js']);
   }
diff --git a/chrome/browser/resources/chromeos/login/structure/components_common.js b/chrome/browser/resources/chromeos/login/structure/components_common.js
index 69d1900a..dc7a324 100644
--- a/chrome/browser/resources/chromeos/login/structure/components_common.js
+++ b/chrome/browser/resources/chromeos/login/structure/components_common.js
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+
+function loadCommonComponents() {
+// TODO(crbug.com/1111387) - Remove excessive logging.
+  console.warn('loadCommonComponents() : Starting to load common components.');
 // This inclusion is types-only. No actual code to execute.
 // <include src="../components/oobe_types.js">
 
@@ -51,3 +55,6 @@
 // <include src="../screen_app_launch_splash.js">
 
 // <include src="components_[OOBE].js">
+// TODO(crbug.com/1111387) - Remove excessive logging.
+  console.warn('loadCommonComponents() : Common components have loaded.');
+}
diff --git a/chrome/browser/resources/nearby_share/nearby_confirmation_page.html b/chrome/browser/resources/nearby_share/nearby_confirmation_page.html
index f7eb255..ecfb472 100644
--- a/chrome/browser/resources/nearby_share/nearby_confirmation_page.html
+++ b/chrome/browser/resources/nearby_share/nearby_confirmation_page.html
@@ -92,7 +92,9 @@
         cancel-button-event-name="[[getCancelEventName_(needsConfirmation_)]]">
   <div id="centerContent" slot="content">
     <div id="processRow">
-      <nearby-preview send-preview="[[sendPreview]]"></nearby-preview>
+      <nearby-preview send-preview="[[sendPreview]]"
+          disabled="[[errorTitle_]]">
+      </nearby-preview>
       <div id="confirmationToken">
         <template is="dom-if" if="[[confirmationToken_]]">
           [[i18n('nearbyShareSecureConnectionId', confirmationToken_)]]
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.html b/chrome/browser/resources/nearby_share/nearby_discovery_page.html
index 2b712836..6ba98b2 100644
--- a/chrome/browser/resources/nearby_share/nearby_discovery_page.html
+++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.html
@@ -132,7 +132,9 @@
         autoplay="true">
     </cr-lottie>
     <div id="process-row">
-      <nearby-preview send-preview="[[sendPreview]]"></nearby-preview>
+      <nearby-preview send-preview="[[sendPreview]]"
+          disabled="[[errorTitle_]]">
+      </nearby-preview>
       <div id="placeholder"
           hidden="[[!isShareTargetsEmpty_(shareTargets_.*)]]">
         $i18n{nearbyShareDiscoveryPagePlaceholder}
diff --git a/chrome/browser/resources/nearby_share/nearby_preview.html b/chrome/browser/resources/nearby_share/nearby_preview.html
index a9213e4..81766a2 100644
--- a/chrome/browser/resources/nearby_share/nearby_preview.html
+++ b/chrome/browser/resources/nearby_share/nearby_preview.html
@@ -6,6 +6,11 @@
     width: 68px;
   }
 
+  iron-icon.disabled {
+    --nearby-preview-color: var(--google-grey-600);
+    --nearby-preview-background-color: var(--google-grey-200);
+  }
+
   #title {
     color: var(--google-grey-900);
     font-size: 13px;
@@ -20,5 +25,7 @@
   }
 </style>
 
-<iron-icon icon="[[getIronIconName_(sendPreview)]]"></iron-icon>
+<iron-icon class$="[[getIconClass_(disabled)]]"
+    icon="[[getIronIconName_(sendPreview)]]">
+</iron-icon>
 <div id="title">[[getTitle_(sendPreview)]]</div>
diff --git a/chrome/browser/resources/nearby_share/nearby_preview.js b/chrome/browser/resources/nearby_share/nearby_preview.js
index e8c12243..0e6c2dc 100644
--- a/chrome/browser/resources/nearby_share/nearby_preview.js
+++ b/chrome/browser/resources/nearby_share/nearby_preview.js
@@ -31,6 +31,14 @@
       value: null,
     },
 
+    /**
+     * Controls whether the icon should be greyed out.
+     * @type {boolean}
+     */
+    disabled: {
+      type: Boolean,
+      value: false,
+    },
   },
 
   /**
@@ -94,4 +102,15 @@
         return 'nearbysharetype68:unknown-file';
     }
   },
+
+  /**
+   * @return {string} The css class to be applied to the icon.
+   * @private
+   */
+  getIconClass_() {
+    if (this.disabled) {
+      return 'disabled';
+    }
+    return '';
+  },
 });
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_shared_share_type_icons.html b/chrome/browser/resources/nearby_share/shared/nearby_shared_share_type_icons.html
index 2011003..b85d2608 100644
--- a/chrome/browser/resources/nearby_share/shared/nearby_shared_share_type_icons.html
+++ b/chrome/browser/resources/nearby_share/shared/nearby_shared_share_type_icons.html
@@ -8,52 +8,52 @@
       Keep these in sorted order by id="". See also http://goo.gl/Y1OdAq
       -->
       <g id="address">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M12 2C8.13 2 5 5.13 5 9C5 14.25 12 22 12 22C12 22 19 14.25 19 9C19 5.13 15.87 2 12 2ZM7 9C7 6.24 9.24 4 12 4C14.76 4 17 6.24 17 9C17 11.88 14.12 16.19 12 18.88C9.92 16.21 7 11.85 7 9ZM14.5 9C14.5 10.3807 13.3807 11.5 12 11.5C10.6193 11.5 9.5 10.3807 9.5 9C9.5 7.61929 10.6193 6.5 12 6.5C13.3807 6.5 14.5 7.61929 14.5 9Z" fill="#1a73e8"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M12 2C8.13 2 5 5.13 5 9C5 14.25 12 22 12 22C12 22 19 14.25 19 9C19 5.13 15.87 2 12 2ZM7 9C7 6.24 9.24 4 12 4C14.76 4 17 6.24 17 9C17 11.88 14.12 16.19 12 18.88C9.92 16.21 7 11.85 7 9ZM14.5 9C14.5 10.3807 13.3807 11.5 12 11.5C10.6193 11.5 9.5 10.3807 9.5 9C9.5 7.61929 10.6193 6.5 12 6.5C13.3807 6.5 14.5 7.61929 14.5 9Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
       <g id="audio-file">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M6 8C7.1 8 8 8.9 8 10V14C8 15.1 7.1 16 6 16C4.9 16 4 15.1 4 14V10C4 8.9 4.9 8 6 8ZM16 10V14C16 15.1 16.9 16 18 16C19.1 16 20 15.1 20 14V10C20 8.9 19.1 8 18 8C16.9 8 16 8.9 16 10ZM10 6V18C10 19.1 10.9 20 12 20C13.1 20 14 19.1 14 18V6C14 4.9 13.1 4 12 4C10.9 4 10 4.9 10 6Z" fill="#1a73e8"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M6 8C7.1 8 8 8.9 8 10V14C8 15.1 7.1 16 6 16C4.9 16 4 15.1 4 14V10C4 8.9 4.9 8 6 8ZM16 10V14C16 15.1 16.9 16 18 16C19.1 16 20 15.1 20 14V10C20 8.9 19.1 8 18 8C16.9 8 16 8.9 16 10ZM10 6V18C10 19.1 10.9 20 12 20C13.1 20 14 19.1 14 18V6C14 4.9 13.1 4 12 4C10.9 4 10 4.9 10 6Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
       <g id="google-docs-file">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3V3ZM17.01 9H7V7H17.01V9V9ZM17.01 13H7V11H17.01V13V13ZM14.01 17H7V15H14.01V17V17Z" fill="#4285F4"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3V3ZM17.01 9H7V7H17.01V9V9ZM17.01 13H7V11H17.01V13V13ZM14.01 17H7V15H14.01V17V17Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
       <g id="google-sheets-file">
-        <circle cx="34" cy="34" r="34" fill="#e6f4ea"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M19 3H5C3.9 3 3.01 3.9 3.01 5L3 8V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3V3ZM19 11H11V19H9V11H5V9H9V5H11V9H19V11V11Z" fill="#34A853"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, rgb(230, 244, 234))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M19 3H5C3.9 3 3.01 3.9 3.01 5L3 8V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3V3ZM19 11H11V19H9V11H5V9H9V5H11V9H19V11V11Z" style="fill: var(--nearby-preview-color, rgb(30, 142, 162))"></path>
       </g>
       <g id="google-slides-file">
-        <circle cx="34" cy="34" r="34" fill="#fef7e0"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M18.9998 3H4.99977C3.89977 3 3.00977 3.9 3.00977 5V19C3.00977 20.1 3.89977 21 4.99977 21H18.9998C20.0998 21 20.9998 20.1 20.9998 19V5C20.9998 3.9 20.0998 3 18.9998 3V3ZM18.9998 16H4.99977V8H18.9998V16V16Z" fill="#F4B400"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-yellow-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M18.9998 3H4.99977C3.89977 3 3.00977 3.9 3.00977 5V19C3.00977 20.1 3.89977 21 4.99977 21H18.9998C20.0998 21 20.9998 20.1 20.9998 19V5C20.9998 3.9 20.0998 3 18.9998 3V3ZM18.9998 16H4.99977V8H18.9998V16V16Z" style="fill: var(--nearby-preview-color, rgb(249, 171, 0))"></path>
       </g>
       <g id="image-video-file">
-        <rect x="5" height="68" width="58" rx="4" fill="#e8f0fe"></rect>
-        <path transform="translate(16 16)" fill-rule="evenodd" d="M14 8v6a9 9 0 1 0 10 11h7v-17zm10 17a9 9 0 0 0 -10 -11v11h10z" fill="#aecbfa"></path>
+        <rect x="5" height="68" width="58" rx="4" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></rect>
+        <path transform="translate(16 16)" fill-rule="evenodd" d="M14 8v6a9 9 0 1 0 10 11h7v-17zm10 17a9 9 0 0 0 -10 -11v11h10z" style="fill: var(--nearby-preview-color, var(--google-blue-200))"></path>
       </g>
       <g id="multiple-file">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M15 1H8C6.9 1 6.01 1.9 6.01 3L6 17C6 18.1 6.89 19 7.99 19H19C20.1 19 21 18.1 21 17V7L15 1ZM18 23H4C2.9 23 2 22.1 2 21V7H4V21H18V23ZM8 3V17H19V8H14V3H8Z" fill="#1a73e8"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M15 1H8C6.9 1 6.01 1.9 6.01 3L6 17C6 18.1 6.89 19 7.99 19H19C20.1 19 21 18.1 21 17V7L15 1ZM18 23H4C2.9 23 2 22.1 2 21V7H4V21H18V23ZM8 3V17H19V8H14V3H8Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
       <g id="pdf-file">
-        <circle cx="34" cy="34" r="34" fill="#fce8e6"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M5 3H19C20.1 3 21 3.9 21 5V19C21 20.1 20.1 21 19 21H5C3.9 21 3 20.1 3 19V5C3 3.9 3.9 3 5 3ZM8 11.5H7V10.5H8V11.5ZM9.5 11.5C9.5 12.33 8.83 13 8 13H7V15H5.5V9H8C8.83 9 9.5 9.67 9.5 10.5V11.5ZM17 10.5H19.5V9H15.5V15H17V13H18.5V11.5H17V10.5ZM14.5 13.5C14.5 14.33 13.83 15 13 15H10.5V9H13C13.83 9 14.5 9.67 14.5 10.5V13.5ZM13 13.5H12V10.5H13V13.5Z" fill="#EA4335"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, rgb(252, 232, 230))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M5 3H19C20.1 3 21 3.9 21 5V19C21 20.1 20.1 21 19 21H5C3.9 21 3 20.1 3 19V5C3 3.9 3.9 3 5 3ZM8 11.5H7V10.5H8V11.5ZM9.5 11.5C9.5 12.33 8.83 13 8 13H7V15H5.5V9H8C8.83 9 9.5 9.67 9.5 10.5V11.5ZM17 10.5H19.5V9H15.5V15H17V13H18.5V11.5H17V10.5ZM14.5 13.5C14.5 14.33 13.83 15 13 15H10.5V9H13C13.83 9 14.5 9.67 14.5 10.5V13.5ZM13 13.5H12V10.5H13V13.5Z" style="fill: var(--nearby-preview-color, var(--google-red-600))"></path>
       </g>
       <g id="phone">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M17 1H7C5.9 1 5 1.9 5 3V21C5 22.1 5.9 23 7 23H17C18.1 23 19 22.1 19 21V3C19 1.9 18.1 1 17 1ZM7 6H17V16H7V6ZM7 21H17V18H7V21ZM7 4V3H17V4H7ZM14 19H10V20H14V19Z" fill="#1a73e8"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M17 1H7C5.9 1 5 1.9 5 3V21C5 22.1 5.9 23 7 23H17C18.1 23 19 22.1 19 21V3C19 1.9 18.1 1 17 1ZM7 6H17V16H7V6ZM7 21H17V18H7V21ZM7 4V3H17V4H7ZM14 19H10V20H14V19Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
       <g id="text">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M3.59961 6H20.3996V8.4H3.59961V6ZM3.59961 10.8H20.3996V13.2H3.59961V10.8ZM13.1996 15.6H3.59961V18H13.1996V15.6Z" fill="#1a73e8"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M3.59961 6H20.3996V8.4H3.59961V6ZM3.59961 10.8H20.3996V13.2H3.59961V10.8ZM13.1996 15.6H3.59961V18H13.1996V15.6Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
       <g id="unknown-file">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M6 2H14L20 8V20C20 21.1 19.1 22 18 22H5.99C4.89 22 4 21.1 4 20L4.01 4C4.01 2.9 4.9 2 6 2ZM6 4V20H18V9H13V4H6Z" fill="#1a73e8"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M6 2H14L20 8V20C20 21.1 19.1 22 18 22H5.99C4.89 22 4 21.1 4 20L4.01 4C4.01 2.9 4.9 2 6 2ZM6 4V20H18V9H13V4H6Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
       <g id="url">
-        <circle cx="34" cy="34" r="34" fill="#e8f0fe"></circle>
-        <path fill-rule="evenodd" transform="translate(22 22)" d="M11 15H7C5.35 15 4 13.65 4 12C4 10.35 5.35 9 7 9H11V7H7C4.24 7 2 9.24 2 12C2 14.76 4.24 17 7 17H11V15ZM17 7H13V9H17C18.65 9 20 10.35 20 12C20 13.65 18.65 15 17 15H13V17H17C19.76 17 22 14.76 22 12C22 9.24 19.76 7 17 7ZM16 11H8V13H16V11Z" fill="#1a73e8"></path>
+        <circle cx="34" cy="34" r="34" style="fill: var(--nearby-preview-background-color, var(--google-blue-50))"></circle>
+        <path fill-rule="evenodd" transform="translate(22 22)" d="M11 15H7C5.35 15 4 13.65 4 12C4 10.35 5.35 9 7 9H11V7H7C4.24 7 2 9.24 2 12C2 14.76 4.24 17 7 17H11V15ZM17 7H13V9H17C18.65 9 20 10.35 20 12C20 13.65 18.65 15 17 15H13V17H17C19.76 17 22 14.76 22 12C22 9.24 19.76 7 17 7ZM16 11H8V13H16V11Z" style="fill: var(--nearby-preview-color, var(--google-blue-600))"></path>
       </g>
     </defs>
   </svg>
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.html b/chrome/browser/resources/settings/autofill_page/password_check.html
index 2500da7..ec0f318 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check.html
+++ b/chrome/browser/resources/settings/autofill_page/password_check.html
@@ -53,11 +53,6 @@
         width: 100%;
       }
 
-      #weakPasswordsDescription {
-        display: block;
-        text-align: left;
-      }
-
     </style>
     <!-- The banner is visible if no insecure password was found (yet) and user
     is signed in. -->
@@ -123,7 +118,8 @@
         <h2>$i18n{compromisedPasswords}</h2>
       </div>
       <div class="list-frame vertical-list">
-        <div class="list-item secondary" id="compromisedPasswordsDescription"
+        <div class="cr-padded-text secondary"
+            id="compromisedPasswordsDescription"
             hidden$="[[!hasLeakedCredentials_(leakedPasswords)]]">
           $i18n{compromisedPasswordsDescription}
         </div>
@@ -157,7 +153,7 @@
         <h2>$i18n{weakPasswords}</h2>
       </div>
       <div class="list-frame vertical-list">
-        <div class="list-item secondary" id="weakPasswordsDescription"
+        <div class="cr-padded-text secondary" id="weakPasswordsDescription"
             inner-h-t-m-l="[[getWeakPasswordsHelpText_(isSyncingPasswords_)]]">
         </div>
       </div>
diff --git a/chrome/browser/resources/settings/people_page/manage_profile.html b/chrome/browser/resources/settings/people_page/manage_profile.html
index 08169d9..91e7f05 100644
--- a/chrome/browser/resources/settings/people_page/manage_profile.html
+++ b/chrome/browser/resources/settings/people_page/manage_profile.html
@@ -56,7 +56,7 @@
         padding: var(--cr-section-vertical-padding) 0;
       }
     </style>
-    <template is="dom-if" if="[[!isProfilesUIRevamp_]]">
+    <template is="dom-if" if="[[!isNewProfilePicker_]]">
       <div class="cr-row first">
         <cr-input id="name" value="[[profileName]]" pattern="[[pattern_]]"
             on-change="onProfileNameChanged_" on-keydown="onProfileNameKeydown_"
@@ -83,7 +83,7 @@
       </cr-profile-avatar-selector>
   </template>
 
-  <template is="dom-if" if="[[isProfilesUIRevamp_]]">
+  <template is="dom-if" if="[[isNewProfilePicker_]]">
     <div class="cr-row first manage-profile-section">
       <h1 class="cr-title-text">$i18n{nameYourProfile}</h1>
       <div class="content">
diff --git a/chrome/browser/resources/settings/people_page/manage_profile.js b/chrome/browser/resources/settings/people_page/manage_profile.js
index 2d5e068..daff6e8 100644
--- a/chrome/browser/resources/settings/people_page/manage_profile.js
+++ b/chrome/browser/resources/settings/people_page/manage_profile.js
@@ -78,12 +78,12 @@
     isProfileShortcutSettingVisible_: Boolean,
 
     /**
-     * True if the 'kProfilesUIRevamp' feature is enabled.
+     * True if the 'kNewProfilePicker' feature is enabled.
      * @private
      */
-    isProfilesUIRevamp_: {
+    isNewProfilePicker_: {
       type: Boolean,
-      value: () => loadTimeData.getBoolean('profilesUIRevamp')
+      value: () => loadTimeData.getBoolean('newProfilePicker')
     },
 
     /**
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js b/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js
index 9596017..2d65d8d8 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js
@@ -71,6 +71,7 @@
   QUOTA_LIMIT: 6,
   ERROR: 7,
   FEATURE_UNAVAILABLE: 8,
+  WEAK_PASSWORDS_EXIST: 9,
 };
 
 /**
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js
index d7a9534..c4337ce9a 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js
@@ -66,6 +66,7 @@
         SafetyCheckPasswordsStatus.SAFE,
         SafetyCheckPasswordsStatus.QUOTA_LIMIT,
         SafetyCheckPasswordsStatus.ERROR,
+        SafetyCheckPasswordsStatus.WEAK_PASSWORDS_EXIST,
       ]),
     },
   },
@@ -110,6 +111,7 @@
       case SafetyCheckPasswordsStatus.QUOTA_LIMIT:
       case SafetyCheckPasswordsStatus.ERROR:
       case SafetyCheckPasswordsStatus.FEATURE_UNAVAILABLE:
+      case SafetyCheckPasswordsStatus.WEAK_PASSWORDS_EXIST:
         return SafetyCheckIconStatus.INFO;
       default:
         assertNotReached();
diff --git a/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html b/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html
index 3f4cc6ed..79b68ec 100644
--- a/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html
+++ b/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html
@@ -5,6 +5,9 @@
     </style>
     <div id="exceptionHeader" hidden="[[!enableContentSettingsRedesign_]]">
       <h2>$i18n{siteSettingsCustomizedBehaviors}</h2>
+      <div id="exceptionHeaderSubLabel" class="secondary">
+        $i18n{siteSettingsCustomizedBehaviorsDescription}
+      </div>
     </div>
     <site-list
         has-discarded-exceptions="{{blockSiteListHasDiscardedExceptions_}}"
diff --git a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/SettingsActivityTestRule.java b/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/SettingsActivityTestRule.java
index 22bcb58..250dbd2e 100644
--- a/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/SettingsActivityTestRule.java
+++ b/chrome/browser/settings/android/java/src/org/chromium/chrome/browser/settings/SettingsActivityTestRule.java
@@ -8,15 +8,17 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.lifecycle.Stage;
+import android.support.test.rule.ActivityTestRule;
 
 import androidx.fragment.app.Fragment;
 
+import org.hamcrest.Matchers;
 import org.junit.Assert;
 
-import org.chromium.base.test.BaseActivityTestRule;
-import org.chromium.base.test.util.ApplicationTestUtils;
-
+import org.chromium.base.ActivityState;
+import org.chromium.base.ApplicationStatus;
+import org.chromium.base.test.util.Criteria;
+import org.chromium.base.test.util.CriteriaHelper;
 /**
  * Activity test rule that launch {@link SettingsActivity} in tests.
  *
@@ -26,7 +28,7 @@
  * @param <T> Fragment that will be attached to the SettingsActivity.
  */
 public class SettingsActivityTestRule<T extends Fragment>
-        extends BaseActivityTestRule<SettingsActivity> {
+        extends ActivityTestRule<SettingsActivity> {
     private final Class<T> mFragmentClass;
 
     /**
@@ -34,7 +36,16 @@
      * @param fragmentClass Fragment that will be attached after the activity starts.
      */
     public SettingsActivityTestRule(Class<T> fragmentClass) {
-        super(SettingsActivity.class);
+        this(fragmentClass, false);
+    }
+
+    /**
+     * Create the settings activity test rule with an specific fragment class.
+     * @param fragmentClass Fragment that will be attached after the activity starts.
+     * @param initialTouchMode Whether in touch mode after the activity starts.
+     */
+    public SettingsActivityTestRule(Class<T> fragmentClass, boolean initialTouchMode) {
+        super(SettingsActivity.class, initialTouchMode, false);
         mFragmentClass = fragmentClass;
     }
 
@@ -56,9 +67,35 @@
         SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
         Intent intent = settingsLauncher.createSettingsActivityIntent(
                 context, mFragmentClass.getName(), fragmentArgs);
-        launchActivity(intent);
-        ApplicationTestUtils.waitForActivityState(getActivity(), Stage.RESUMED);
-        return getActivity();
+        SettingsActivity activity = super.launchActivity(intent);
+        Assert.assertNotNull(activity);
+
+        return activity;
+    }
+
+    /**
+     * We need to ensure that SettingsActivity gets destroyed in the TestRule because sometimes
+     * it uses the mock signin environment like fake AccountManagerFacade, if the activity starts
+     * with the stub then it also needs to finish with it. That's why we need to wait till the
+     * activity state becomes destroyed before tearing down the mock signin environment.
+     */
+    @Override
+    protected void afterActivityFinished() {
+        super.afterActivityFinished();
+        waitTillActivityIsDestroyed();
+    }
+
+    /**
+     * Block the execution till the SettingsActivity is destroyed.
+     */
+    public void waitTillActivityIsDestroyed() {
+        SettingsActivity activity = getActivity();
+        if (activity != null) {
+            CriteriaHelper.pollUiThread(() -> {
+                Criteria.checkThat(ApplicationStatus.getStateForActivity(activity),
+                        Matchers.is(ActivityState.DESTROYED));
+            });
+        }
     }
 
     /**
diff --git a/chrome/browser/signin/dice_intercepted_session_startup_helper.cc b/chrome/browser/signin/dice_intercepted_session_startup_helper.cc
index f802ef5..60be08c 100644
--- a/chrome/browser/signin/dice_intercepted_session_startup_helper.cc
+++ b/chrome/browser/signin/dice_intercepted_session_startup_helper.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "chrome/browser/signin/account_reconcilor_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
@@ -66,11 +67,13 @@
     MoveTab();
   } else {
     // TODO(https://crbug.com/1051864): cookie notifications are not triggered
-    // when the account is added by the reconcilor. Force an explicit cookie
-    // update.
+    // when the account is added by the reconcilor. Observe the reconcilor and
+    // re-trigger the cookie update when it completes.
+    reconcilor_observer_.Observe(
+        AccountReconcilorFactory::GetForProfile(profile_));
     identity_manager->GetAccountsCookieMutator()->TriggerCookieJarUpdate();
 
-    accounts_in_cookie_observer_.Add(identity_manager);
+    accounts_in_cookie_observer_.Observe(identity_manager);
     on_cookie_update_timeout_.Reset(base::BindOnce(
         &DiceInterceptedSessionStartupHelper::MoveTab, base::Unretained(this)));
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
@@ -91,10 +94,39 @@
   MoveTab();
 }
 
+void DiceInterceptedSessionStartupHelper::OnStateChanged(
+    signin_metrics::AccountReconcilorState state) {
+  if (state == signin_metrics::ACCOUNT_RECONCILOR_ERROR) {
+    reconcile_error_encountered_ = true;
+    return;
+  }
+
+  // TODO(https://crbug.com/1051864): remove this when the cookie updates are
+  // correctly sent after reconciliation.
+  if (state == signin_metrics::ACCOUNT_RECONCILOR_OK) {
+    signin::IdentityManager* identity_manager =
+        IdentityManagerFactory::GetForProfile(profile_);
+    // GetAccountsInCookieJar() automatically re-schedules a /ListAccounts call
+    // if the cookie is not fresh.
+    signin::AccountsInCookieJarInfo cookie_info =
+        identity_manager->GetAccountsInCookieJar();
+    OnAccountsInCookieUpdated(cookie_info,
+                              GoogleServiceAuthError::AuthErrorNone());
+  }
+}
+
 void DiceInterceptedSessionStartupHelper::MoveTab() {
-  accounts_in_cookie_observer_.RemoveAll();
+  if (accounts_in_cookie_observer_.IsObserving())
+    accounts_in_cookie_observer_.RemoveObservation();
+  if (reconcilor_observer_.IsObserving())
+    reconcilor_observer_.RemoveObservation();
   on_cookie_update_timeout_.Cancel();
 
+  // TODO(https://crbug.com/1151313): Remove this histogram when the cause
+  // for the timeouts is understood.
+  base::UmaHistogramBoolean("Signin.Intercept.SessionStartupReconcileError",
+                            reconcile_error_encountered_);
+
   // If the intercepted web contents is still alive, close it now.
   if (web_contents()) {
     // Update the URL once again to catch any potential navigation happening
diff --git a/chrome/browser/signin/dice_intercepted_session_startup_helper.h b/chrome/browser/signin/dice_intercepted_session_startup_helper.h
index 1adbcac..77338a9c 100644
--- a/chrome/browser/signin/dice_intercepted_session_startup_helper.h
+++ b/chrome/browser/signin/dice_intercepted_session_startup_helper.h
@@ -7,8 +7,9 @@
 
 #include "base/callback_forward.h"
 #include "base/cancelable_callback.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #include "base/time/time.h"
+#include "components/signin/core/browser/account_reconcilor.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "google_apis/gaia/core_account_id.h"
@@ -32,7 +33,8 @@
 // in the content area (cookies).
 class DiceInterceptedSessionStartupHelper
     : public content::WebContentsObserver,
-      public signin::IdentityManager::Observer {
+      public signin::IdentityManager::Observer,
+      public AccountReconcilor::Observer {
  public:
   // |profile| is the new profile that was created after signin interception.
   // |account_id| is the main account for the profile, it's already in the
@@ -58,6 +60,9 @@
       const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
       const GoogleServiceAuthError& error) override;
 
+  // AccountReconcilor::Observer:
+  void OnStateChanged(signin_metrics::AccountReconcilorState state) override;
+
  private:
   // Creates a browser with a new tab, and closes the intercepted tab if it's
   // still open.
@@ -66,8 +71,12 @@
   Profile* const profile_;
   CoreAccountId account_id_;
   base::OnceClosure callback_;
-  ScopedObserver<signin::IdentityManager, signin::IdentityManager::Observer>
+  bool reconcile_error_encountered_ = false;
+  base::ScopedObservation<signin::IdentityManager,
+                          signin::IdentityManager::Observer>
       accounts_in_cookie_observer_{this};
+  base::ScopedObservation<AccountReconcilor, AccountReconcilor::Observer>
+      reconcilor_observer_{this};
   base::TimeTicks session_startup_time_;
   // Timeout while waiting for the account to be added to the cookies in the new
   // profile.
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index 2162248..d0e20a8 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2591,6 +2591,9 @@
       <message name="IDS_SIGNIN_ACCOUNT_PICKER_AUTH_ERROR_SUBTITLE" desc="The subtitle of the account picker bottom sheet when there is an authentication error with the credentials of the account selected.">
         Sorry, we couldn’t validate your credentials
       </message>
+      <message name="IDS_SIGNIN_ACCOUNT_PICKER_DISMISS_BUTTON" desc="Dismiss button text of the account picker bottom sheet">
+        Skip
+      </message>
       <message name="IDS_SIGNIN_ACCOUNT_PICKER_GENERAL_ERROR_BUTTON" desc="Button text of the account picker bottom sheet when something went wrong in the sign-in process. User can try again if they click it.">
         Try again
       </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNIN_ACCOUNT_PICKER_DISMISS_BUTTON.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNIN_ACCOUNT_PICKER_DISMISS_BUTTON.png.sha1
new file mode 100644
index 0000000..2d1fcf7
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNIN_ACCOUNT_PICKER_DISMISS_BUTTON.png.sha1
@@ -0,0 +1 @@
+ffafa83c87636e34dca6a8a4ac91d0290e4686d7
\ No newline at end of file
diff --git a/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc b/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
index 0107376..62c8c59 100644
--- a/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
+++ b/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
@@ -16,6 +16,8 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "ui/accessibility/platform/ax_platform_node.h"
+#include "ui/accessibility/platform/ax_platform_node_base.h"
+#include "ui/views/accessibility/view_accessibility.h"
 
 class AuraLinuxAccessibilityInProcessBrowserTest : public InProcessBrowserTest {
  public:
@@ -219,3 +221,30 @@
   DevToolsWindowTesting::CloseDevToolsWindowSync(devtools);
   VerifyEmbedRelationships();
 }
+
+// Tests that it doesn't have DCHECK() error when GetIndexInParent() is called
+// with the WebView.
+IN_PROC_BROWSER_TEST_F(AuraLinuxAccessibilityInProcessBrowserTest,
+                       GetIndexInParent) {
+  content::WebContents* active_web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_NE(nullptr, active_web_contents->GetRenderWidgetHostView()
+                         ->GetNativeViewAccessible());
+  EXPECT_EQ(1, browser()->tab_strip_model()->count());
+  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
+
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
+  views::WebView* webview = browser_view->contents_web_view();
+  gfx::NativeViewAccessible accessible =
+      webview->GetViewAccessibility().GetNativeObject();
+
+  // Gets the index in its parents for the WebView.
+  base::Optional<int> index =
+      static_cast<ui::AXPlatformNodeBase*>(
+          ui::AXPlatformNode::FromNativeViewAccessible(accessible))
+          ->GetIndexInParent();
+
+  // As the WebView is not exposed in the child list when it has the web
+  // content, it doesn't have the index in its parent.
+  EXPECT_EQ(false, index.has_value());
+}
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
index be968264..fa4c6ff 100644
--- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
+++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
@@ -166,17 +166,6 @@
     base::OnceCallback<void(SigninInterceptionResult)> callback) {
   DCHECK(browser);
 
-  if (bubble_parameters.interception_type ==
-          DiceWebSigninInterceptor::SigninInterceptionType::kProfileSwitch &&
-      !base::FeatureList::IsEnabled(features::kProfilesUIRevamp)) {
-    // The bubble for profile switch is not enabled.
-    DiceWebSigninInterceptionBubbleView::RecordInterceptionResult(
-        bubble_parameters, browser->profile(),
-        SigninInterceptionResult::kNotDisplayed);
-    std::move(callback).Run(SigninInterceptionResult::kNotDisplayed);
-    return;
-  }
-
   views::View* anchor_view = BrowserView::GetBrowserViewForBrowser(browser)
                                  ->toolbar_button_provider()
                                  ->GetAvatarToolbarButton();
diff --git a/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc b/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc
index 25720020..6602035 100644
--- a/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc
@@ -75,9 +75,6 @@
     Browser* browser) {
   DCHECK(browser);
 
-  if (!base::FeatureList::IsEnabled(features::kProfilesUIRevamp))
-    return;
-
   views::View* anchor_view = BrowserView::GetBrowserViewForBrowser(browser)
                                  ->toolbar_button_provider()
                                  ->GetAvatarToolbarButton();
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.cc b/chrome/browser/ui/webui/settings/safety_check_handler.cc
index 6c35ffb..65063ade 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler.cc
+++ b/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -250,7 +250,7 @@
                                     GetStringForUpdates(update_status_));
   FireBasicSafetyCheckWebUiListener(
       kPasswordsEvent, static_cast<int>(passwords_status_),
-      GetStringForPasswords(passwords_status_, Compromised(0), Done(0),
+      GetStringForPasswords(passwords_status_, Compromised(0), Weak(0), Done(0),
                             Total(0)));
   FireBasicSafetyCheckWebUiListener(
       kSafeBrowsingEvent, static_cast<int>(safe_browsing_status_),
@@ -500,12 +500,13 @@
 
 void SafetyCheckHandler::OnPasswordsCheckResult(PasswordsStatus status,
                                                 Compromised compromised,
+                                                Weak weak,
                                                 Done done,
                                                 Total total) {
   base::DictionaryValue event;
   event.SetIntKey(kNewState, static_cast<int>(status));
-  event.SetStringKey(kDisplayString,
-                     GetStringForPasswords(status, compromised, done, total));
+  event.SetStringKey(kDisplayString, GetStringForPasswords(status, compromised,
+                                                           weak, done, total));
   FireWebUIListener(kPasswordsEvent, event);
   if (status != PasswordsStatus::kChecking) {
     base::UmaHistogramEnumeration("Settings.SafetyCheck.PasswordsResult",
@@ -634,6 +635,7 @@
 base::string16 SafetyCheckHandler::GetStringForPasswords(
     PasswordsStatus status,
     Compromised compromised,
+    Weak weak,
     Done done,
     Total total) {
   switch (status) {
@@ -647,11 +649,28 @@
                                         base::FormatNumber(total.value()));
     }
     case PasswordsStatus::kSafe:
-      return l10n_util::GetPluralStringFUTF16(
-          IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT, 0);
+      return l10n_util::GetStringUTF16(
+          IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_SAFE);
     case PasswordsStatus::kCompromisedExist:
+      if (weak.value() == 0) {
+        // Only compromised passwords, no weak passwords.
+        return l10n_util::GetPluralStringFUTF16(
+            IDS_SETTINGS_SAFETY_CHECK_COMPROMISED_PASSWORDS,
+            compromised.value());
+      } else {
+        // Both compromised and weak passwords.
+        return l10n_util::GetStringFUTF16(
+            IDS_SETTINGS_SAFETY_CHECK_STRING_TUPLE_WITH_COMMA,
+            l10n_util::GetPluralStringFUTF16(
+                IDS_SETTINGS_SAFETY_CHECK_COMPROMISED_PASSWORDS,
+                compromised.value()),
+            l10n_util::GetPluralStringFUTF16(
+                IDS_SETTINGS_SAFETY_CHECK_WEAK_PASSWORDS, weak.value()));
+      }
+    case PasswordsStatus::kWeakPasswordsExist:
+      // Only weak passwords.
       return l10n_util::GetPluralStringFUTF16(
-          IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT, compromised.value());
+          IDS_SETTINGS_SAFETY_CHECK_WEAK_PASSWORDS, weak.value());
     case PasswordsStatus::kOffline:
       return l10n_util::GetStringUTF16(
           IDS_SETTINGS_CHECK_PASSWORDS_ERROR_OFFLINE);
@@ -848,13 +867,14 @@
         passwords) {
   OnPasswordsCheckResult(passwords.empty() ? PasswordsStatus::kNoPasswords
                                            : PasswordsStatus::kSafe,
-                         Compromised(0), Done(0), Total(0));
+                         Compromised(0), Weak(0), Done(0), Total(0));
 }
 
 void SafetyCheckHandler::UpdatePasswordsResultOnCheckIdle() {
   size_t num_compromised =
       passwords_delegate_->GetCompromisedCredentials().size();
-  if (num_compromised == 0) {
+  size_t num_weak = passwords_delegate_->GetWeakCredentials().size();
+  if (num_compromised == 0 && num_weak == 0) {
     // If there are no |OnCredentialDone| callbacks with is_leaked = true, no
     // need to wait for InsecureCredentialsManager callbacks any longer, since
     // there should be none for the current password check.
@@ -864,9 +884,16 @@
     passwords_delegate_->GetSavedPasswordsList(
         base::BindOnce(&SafetyCheckHandler::DetermineIfNoPasswordsOrSafe,
                        base::Unretained(this)));
-  } else {
+  } else if (num_compromised > 0) {
+    // At least one compromised password. Treat as compromises.
     OnPasswordsCheckResult(PasswordsStatus::kCompromisedExist,
-                           Compromised(num_compromised), Done(0), Total(0));
+                           Compromised(num_compromised), Weak(num_weak),
+                           Done(0), Total(0));
+  } else {
+    // No compromised but weak passwords. Treat as weak passwords only.
+    OnPasswordsCheckResult(PasswordsStatus::kWeakPasswordsExist,
+                           Compromised(num_compromised), Weak(num_weak),
+                           Done(0), Total(0));
   }
 }
 
@@ -911,29 +938,29 @@
     }
     case BulkLeakCheckService::State::kRunning:
       OnPasswordsCheckResult(PasswordsStatus::kChecking, Compromised(0),
-                             Done(0), Total(0));
+                             Weak(0), Done(0), Total(0));
       // Non-terminal state, so nothing else needs to be done.
       return;
     case BulkLeakCheckService::State::kSignedOut:
       OnPasswordsCheckResult(PasswordsStatus::kSignedOut, Compromised(0),
-                             Done(0), Total(0));
+                             Weak(0), Done(0), Total(0));
       break;
     case BulkLeakCheckService::State::kNetworkError:
-      OnPasswordsCheckResult(PasswordsStatus::kOffline, Compromised(0), Done(0),
-                             Total(0));
+      OnPasswordsCheckResult(PasswordsStatus::kOffline, Compromised(0), Weak(0),
+                             Done(0), Total(0));
       break;
     case BulkLeakCheckService::State::kQuotaLimit:
       OnPasswordsCheckResult(PasswordsStatus::kQuotaLimit, Compromised(0),
-                             Done(0), Total(0));
+                             Weak(0), Done(0), Total(0));
       break;
     case BulkLeakCheckService::State::kTokenRequestFailure:
       OnPasswordsCheckResult(PasswordsStatus::kFeatureUnavailable,
-                             Compromised(0), Done(0), Total(0));
+                             Compromised(0), Weak(0), Done(0), Total(0));
       break;
     case BulkLeakCheckService::State::kHashingFailure:
     case BulkLeakCheckService::State::kServiceError:
-      OnPasswordsCheckResult(PasswordsStatus::kError, Compromised(0), Done(0),
-                             Total(0));
+      OnPasswordsCheckResult(PasswordsStatus::kError, Compromised(0), Weak(0),
+                             Done(0), Total(0));
       break;
   }
 
@@ -959,8 +986,8 @@
       status.already_processed && status.remaining_in_queue) {
     Done done = Done(*(status.already_processed));
     Total total = Total(*(status.remaining_in_queue) + done.value());
-    OnPasswordsCheckResult(PasswordsStatus::kChecking, Compromised(0), done,
-                           total);
+    OnPasswordsCheckResult(PasswordsStatus::kChecking, Compromised(0), Weak(0),
+                           done, total);
   }
 }
 
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.h b/chrome/browser/ui/webui/settings/safety_check_handler.h
index b361002f..7018360 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler.h
+++ b/chrome/browser/ui/webui/settings/safety_check_handler.h
@@ -179,6 +179,7 @@
   // These ensure integers are passed in the correct possitions in the extension
   // check methods.
   using Compromised = base::StrongAlias<class CompromisedTag, int>;
+  using Weak = base::StrongAlias<class WeakTag, int>;
   using Done = base::StrongAlias<class DoneTag, int>;
   using Total = base::StrongAlias<class TotalTag, int>;
   using Blocklisted = base::StrongAlias<class BlocklistedTag, int>;
@@ -214,6 +215,7 @@
   void OnUpdateCheckResult(UpdateStatus status);
   void OnPasswordsCheckResult(PasswordsStatus status,
                               Compromised compromised,
+                              Weak weak,
                               Done done,
                               Total total);
   void OnExtensionsCheckResult(ExtensionsStatus status,
@@ -231,6 +233,7 @@
   base::string16 GetStringForSafeBrowsing(SafeBrowsingStatus status);
   base::string16 GetStringForPasswords(PasswordsStatus status,
                                        Compromised compromised,
+                                       Weak weak,
                                        Done done,
                                        Total total);
   base::string16 GetStringForExtensions(ExtensionsStatus status,
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc b/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
index 66a6a3c..2a01caa 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
@@ -145,6 +145,10 @@
     compromised_password_count_ = compromised_password_count;
   }
 
+  void SetNumWeakCredentials(int weak_password_count) {
+    weak_password_count_ = weak_password_count;
+  }
+
   void SetPasswordCheckState(
       extensions::api::passwords_private::PasswordCheckState state) {
     state_ = state;
@@ -174,6 +178,16 @@
     return compromised;
   }
 
+  std::vector<extensions::api::passwords_private::InsecureCredential>
+  GetWeakCredentials() override {
+    std::vector<extensions::api::passwords_private::InsecureCredential> weak(
+        weak_password_count_);
+    for (int i = 0; i < weak_password_count_; ++i) {
+      weak[i].username = "test" + base::NumberToString(i);
+    }
+    return weak;
+  }
+
   extensions::api::passwords_private::PasswordCheckStatus
   GetPasswordCheckStatus() override {
     extensions::api::passwords_private::PasswordCheckStatus status;
@@ -193,6 +207,7 @@
  private:
   password_manager::BulkLeakCheckService* leak_service_ = nullptr;
   int compromised_password_count_ = 0;
+  int weak_password_count_ = 0;
   int done_ = 0;
   int total_ = 0;
   int test_credential_counter_ = 0;
@@ -865,7 +880,7 @@
           kPasswords,
           static_cast<int>(SafetyCheckHandler::PasswordsStatus::kSafe));
   EXPECT_TRUE(event);
-  VerifyDisplayString(event, "No compromised passwords found");
+  VerifyDisplayString(event, "No security issues found");
   histogram_tester_.ExpectBucketCount(
       "Settings.SafetyCheck.PasswordsResult",
       SafetyCheckHandler::PasswordsStatus::kSafe, 1);
@@ -956,7 +971,7 @@
   EXPECT_FALSE(event2);
 }
 
-TEST_F(SafetyCheckHandlerTest, CheckPasswords_CompromisedExist) {
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_OnlyCompromisedExist) {
   constexpr int kCompromised = 7;
   test_passwords_delegate_.SetNumCompromisedCredentials(kCompromised);
   safety_check_->PerformSafetyCheck();
@@ -982,6 +997,60 @@
       SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
 }
 
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_CompromisedAndWeakExist) {
+  constexpr int kCompromised = 7;
+  constexpr int kWeak = 13;
+  test_passwords_delegate_.SetNumCompromisedCredentials(kCompromised);
+  test_passwords_delegate_.SetNumWeakCredentials(kWeak);
+  safety_check_->PerformSafetyCheck();
+  // First, a "running" change of state.
+  test_leak_service_->set_state_and_notify(
+      password_manager::BulkLeakCheckService::State::kRunning);
+  EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+      kPasswords,
+      static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+  // Compromised passwords found state.
+  test_leak_service_->set_state_and_notify(
+      password_manager::BulkLeakCheckService::State::kIdle);
+  const base::DictionaryValue* event2 =
+      GetSafetyCheckStatusChangedWithDataIfExists(
+          kPasswords,
+          static_cast<int>(
+              SafetyCheckHandler::PasswordsStatus::kCompromisedExist));
+  ASSERT_TRUE(event2);
+  VerifyDisplayString(
+      event2, base::NumberToString(kCompromised) + " compromised passwords, " +
+                  base::NumberToString(kWeak) + " weak passwords");
+  histogram_tester_.ExpectBucketCount(
+      "Settings.SafetyCheck.PasswordsResult",
+      SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_OnlyWeakExist) {
+  constexpr int kWeak = 13;
+  test_passwords_delegate_.SetNumWeakCredentials(kWeak);
+  safety_check_->PerformSafetyCheck();
+  // First, a "running" change of state.
+  test_leak_service_->set_state_and_notify(
+      password_manager::BulkLeakCheckService::State::kRunning);
+  EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+      kPasswords,
+      static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+  // Compromised passwords found state.
+  test_leak_service_->set_state_and_notify(
+      password_manager::BulkLeakCheckService::State::kIdle);
+  const base::DictionaryValue* event2 =
+      GetSafetyCheckStatusChangedWithDataIfExists(
+          kPasswords,
+          static_cast<int>(
+              SafetyCheckHandler::PasswordsStatus::kWeakPasswordsExist));
+  ASSERT_TRUE(event2);
+  VerifyDisplayString(event2, base::NumberToString(kWeak) + " weak passwords");
+  histogram_tester_.ExpectBucketCount(
+      "Settings.SafetyCheck.PasswordsResult",
+      SafetyCheckHandler::PasswordsStatus::kWeakPasswordsExist, 1);
+}
+
 TEST_F(SafetyCheckHandlerTest, CheckPasswords_Error) {
   safety_check_->PerformSafetyCheck();
   EXPECT_TRUE(test_passwords_delegate_.StartPasswordCheckTriggered());
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 c079d57..d93a43e4 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1241,7 +1241,7 @@
                           ProfileShortcutManager::IsFeatureEnabled());
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
   html_source->AddLocalizedString(
-      "editPerson", base::FeatureList::IsEnabled(features::kProfilesUIRevamp)
+      "editPerson", base::FeatureList::IsEnabled(features::kNewProfilePicker)
                         ? IDS_SETTINGS_CUSTOMIZE_PROFILE
                         : IDS_SETTINGS_EDIT_PERSON);
 #endif
@@ -1948,6 +1948,8 @@
      IDS_SETTINGS_SITE_SETTINGS_DEFAULT_BEHAVIOR_DESCRIPTION},
     {"siteSettingsCustomizedBehaviors",
      IDS_SETTINGS_SITE_SETTINGS_CUSTOMIZED_BEHAVIORS},
+    {"siteSettingsCustomizedBehaviorsDescription",
+     IDS_SETTINGS_SITE_SETTINGS_CUSTOMIZED_BEHAVIORS_DESCRIPTION},
     {"siteSettingsAdsDescription", IDS_SETTINGS_SITE_SETTINGS_ADS_DESCRIPTION},
     {"siteSettingsAdsAllowed", IDS_SETTINGS_SITE_SETTINGS_ADS_ALLOWED},
     {"siteSettingsAdsBlocked", IDS_SETTINGS_SITE_SETTINGS_ADS_BLOCKED},
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
index 8857dc6..dbad124 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -150,8 +150,7 @@
       profiles::GetCustomProfileAvatarIconsAndLabels(selected_avatar_idx));
 
   if (entry->GetSigninState() == SigninState::kNotSignedIn) {
-    if (base::FeatureList::IsEnabled(features::kNewProfilePicker) &&
-        base::FeatureList::IsEnabled(features::kProfilesUIRevamp)) {
+    if (base::FeatureList::IsEnabled(features::kNewProfilePicker)) {
       ProfileThemeColors colors = entry->GetProfileThemeColors();
       auto generic_avatar_info = profiles::GetDefaultProfileAvatarIconAndLabel(
           colors.default_avatar_fill_color, colors.default_avatar_stroke_color,
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
index d3c2814..5938a35 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
@@ -291,8 +291,7 @@
 
 TEST_F(ManageProfileHandlerTest, GetAvailableIconsLocalProfile) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      {features::kNewProfilePicker, features::kProfilesUIRevamp}, {});
+  scoped_feature_list.InitAndEnableFeature(features::kNewProfilePicker);
   EXPECT_FALSE(entry()->IsUsingGAIAPicture());
   EXPECT_EQ(entry()->GetAvatarIconIndex(),
             profiles::GetPlaceholderAvatarIndex());
@@ -341,8 +340,7 @@
 
 TEST_F(ManageProfileHandlerTest, ProfileThemeColorsChangedWebUIEvent) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      {features::kNewProfilePicker, features::kProfilesUIRevamp}, {});
+  scoped_feature_list.InitAndEnableFeature(features::kNewProfilePicker);
   ProfileThemeColors colors = {SK_ColorTRANSPARENT, SK_ColorBLACK,
                                SK_ColorWHITE};
   entry()->SetProfileThemeColors(colors);
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc
index 340a0f9..e50cbaf 100644
--- a/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -309,8 +309,8 @@
   // This is the browser settings page.
   html_source->AddBoolean("isOSSettings", false);
 #else   // BUILDFLAG(IS_CHROMEOS_ASH)
-  html_source->AddBoolean("profilesUIRevamp", base::FeatureList::IsEnabled(
-                                                  features::kProfilesUIRevamp));
+  html_source->AddBoolean("newProfilePicker", base::FeatureList::IsEnabled(
+                                                  features::kNewProfilePicker));
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
   AddSettingsPageUIHandler(std::make_unique<AboutHandler>(profile));
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 878469f6..48cd2f65 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-master-1606175959-14a3411953113a2fe64aa457a295c32153a3500e.profdata
+chrome-linux-master-1606218923-9c6085eb8d1087e580649b9899e3b8b35853f279.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 60a5b79..d83fc3ff 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-master-1606175959-25d181192b782b01bd229877ae9d4ba54da15043.profdata
+chrome-mac-master-1606218923-39c9d0a9fc77b1c3938c028a8199ea0790d9dbca.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 15a6f07..a3d8d221 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1606165050-a3d889677a06d0e206b82027c298bfd0cf0af279.profdata
+chrome-win64-master-1606196878-8e98c60eb2828a7469f5671822f6024fb48eb0e5.profdata
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index bcc047f6..c25b097c 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -390,7 +390,7 @@
 
 // Enum that specifies whether Incognito mode is:
 // 0 - Enabled. Default behaviour. Default mode is available on demand.
-// 1 - Disabled. Used cannot browse pages in Incognito mode.
+// 1 - Disabled. User cannot browse pages in Incognito mode.
 // 2 - Forced. All pages/sessions are forced into Incognito.
 const char kIncognitoModeAvailability[] = "incognito.mode_availability";
 
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 2284b46..18b0801 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1635,9 +1635,6 @@
            host_piece == chrome::kChromeUIMultiDeviceSetupHost ||
            // TODO(crbug.com/1111852): Remove when migrated to Polymer3.
            host_piece == chrome::kChromeUINetworkHost ||
-           // TODO(crbug.com/1111387): Remove when migrated away from HTML
-           // Imports.
-           host_piece == chrome::kChromeUIOobeHost ||
            // TODO(crbug.com/1045266): Remove when migrated to Polymer3.
            host_piece == chrome::kChromeUIOSSettingsHost ||
            // TODO(crbug.com/1022192): Remove when migrated to Polymer3.
diff --git a/chrome/renderer/chrome_render_thread_observer.cc b/chrome/renderer/chrome_render_thread_observer.cc
index ec72b21..d553f2f7 100644
--- a/chrome/renderer/chrome_render_thread_observer.cc
+++ b/chrome/renderer/chrome_render_thread_observer.cc
@@ -87,8 +87,8 @@
     }
   }
 
-  std::unique_ptr<content::RequestPeer> OnReceivedResponse(
-      std::unique_ptr<content::RequestPeer> current_peer,
+  std::unique_ptr<blink::WebRequestPeer> OnReceivedResponse(
+      std::unique_ptr<blink::WebRequestPeer> current_peer,
       const std::string& mime_type,
       const GURL& url) override {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/renderer/extensions/extension_localization_peer.cc b/chrome/renderer/extensions/extension_localization_peer.cc
index d7d680c7..f307e21 100644
--- a/chrome/renderer/extensions/extension_localization_peer.cc
+++ b/chrome/renderer/extensions/extension_localization_peer.cc
@@ -27,7 +27,7 @@
 ExtensionLocalizationPeer::DataPipeState::~DataPipeState() = default;
 
 ExtensionLocalizationPeer::ExtensionLocalizationPeer(
-    std::unique_ptr<content::RequestPeer> peer,
+    std::unique_ptr<blink::WebRequestPeer> peer,
     IPC::Sender* message_sender,
     const GURL& request_url)
     : original_peer_(std::move(peer)),
@@ -38,9 +38,9 @@
 }
 
 // static
-std::unique_ptr<content::RequestPeer>
+std::unique_ptr<blink::WebRequestPeer>
 ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
-    std::unique_ptr<content::RequestPeer> peer,
+    std::unique_ptr<blink::WebRequestPeer> peer,
     IPC::Sender* message_sender,
     const std::string& mime_type,
     const GURL& request_url) {
diff --git a/chrome/renderer/extensions/extension_localization_peer.h b/chrome/renderer/extensions/extension_localization_peer.h
index 6cbf2ad..fc85808 100644
--- a/chrome/renderer/extensions/extension_localization_peer.h
+++ b/chrome/renderer/extensions/extension_localization_peer.h
@@ -11,18 +11,18 @@
 #include <string>
 
 #include "base/macros.h"
-#include "content/public/renderer/request_peer.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
+#include "third_party/blink/public/platform/web_request_peer.h"
 
 namespace IPC {
 class Sender;
 }
 
 // The ExtensionLocalizationPeer is a proxy to a
-// content::RequestPeer instance.  It is used to pre-process
+// blink::WebRequestPeer instance.  It is used to pre-process
 // CSS files requested by extensions to replace localization templates with the
 // appropriate localized strings.
 //
@@ -43,17 +43,17 @@
 //
 // Note that OnCompletedRequest() can be called at any time, even before
 // OnReceivedResponse().
-class ExtensionLocalizationPeer : public content::RequestPeer {
+class ExtensionLocalizationPeer : public blink::WebRequestPeer {
  public:
   ~ExtensionLocalizationPeer() override;
 
-  static std::unique_ptr<content::RequestPeer> CreateExtensionLocalizationPeer(
-      std::unique_ptr<content::RequestPeer> peer,
+  static std::unique_ptr<blink::WebRequestPeer> CreateExtensionLocalizationPeer(
+      std::unique_ptr<blink::WebRequestPeer> peer,
       IPC::Sender* message_sender,
       const std::string& mime_type,
       const GURL& request_url);
 
-  // content::RequestPeer methods.
+  // blink::WebRequestPeer methods.
   void OnUploadProgress(uint64_t position, uint64_t size) override;
   bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
                           network::mojom::URLResponseHeadPtr head,
@@ -69,7 +69,7 @@
   friend class ExtensionLocalizationPeerTest;
 
   // Use CreateExtensionLocalizationPeer to create an instance.
-  ExtensionLocalizationPeer(std::unique_ptr<content::RequestPeer> peer,
+  ExtensionLocalizationPeer(std::unique_ptr<blink::WebRequestPeer> peer,
                             IPC::Sender* message_sender,
                             const GURL& request_url);
 
@@ -84,7 +84,7 @@
   void CompleteRequest();
 
   // Original peer that handles the request once we are done processing data_.
-  std::unique_ptr<content::RequestPeer> original_peer_;
+  std::unique_ptr<blink::WebRequestPeer> original_peer_;
 
   // We just pass though the response info. This holds the copy of the original.
   network::mojom::URLResponseHeadPtr response_head_;
diff --git a/chrome/renderer/extensions/extension_localization_peer_unittest.cc b/chrome/renderer/extensions/extension_localization_peer_unittest.cc
index 06ac79f..10102ec 100644
--- a/chrome/renderer/extensions/extension_localization_peer_unittest.cc
+++ b/chrome/renderer/extensions/extension_localization_peer_unittest.cc
@@ -60,7 +60,7 @@
   DISALLOW_COPY_AND_ASSIGN(MockIpcMessageSender);
 };
 
-class MockRequestPeer : public content::RequestPeer {
+class MockRequestPeer : public blink::WebRequestPeer {
  public:
   MockRequestPeer()
       : body_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {
@@ -180,7 +180,7 @@
 };
 
 TEST_F(ExtensionLocalizationPeerTest, CreateWithWrongMimeType) {
-  std::unique_ptr<content::RequestPeer> peer =
+  std::unique_ptr<blink::WebRequestPeer> peer =
       ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
           nullptr, sender_.get(), "text/html", GURL(kExtensionUrl_1));
   EXPECT_EQ(nullptr, peer);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index be5fd37..8203ffd4 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/buildflags_paint_preview.gni")
 import("//build/config/chrome_build.gni")
+import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/compiler/compiler.gni")
 import("//build/config/crypto.gni")
 import("//build/config/features.gni")
@@ -78,7 +79,7 @@
     data += [ "$root_out_dir/pyproto/components/policy/proto/chrome_extension_policy_pb2.py" ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     # Used by chrome/browser/policy/test/policy_testserver.py
     data += [ "$root_out_dir/pyproto/components/policy/proto/chrome_device_policy_pb2.py" ]
   }
@@ -198,6 +199,7 @@
   configs += [ "//build/config:precompiled_headers" ]
 
   deps = [
+    "//build:chromeos_buildflags",
     "//components/security_interstitials/content:security_interstitial_page",
   ]
 
@@ -351,7 +353,7 @@
     libs = [ "runtimeobject.lib" ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [
       "../browser/chromeos/accessibility/speech_monitor.cc",
       "../browser/chromeos/accessibility/speech_monitor.h",
@@ -400,7 +402,7 @@
     ]
   }
 
-  if (is_win || is_mac || (is_linux && !is_chromeos)) {
+  if (is_win || is_mac || (is_linux || is_chromeos_lacros)) {
     public_deps += [ "//ui/base:pixel_diff_test_support" ]
     sources += [
       "pixel/browser_skia_gold_pixel_diff.cc",
@@ -488,7 +490,7 @@
     public_deps += [ "//ppapi/shared_impl" ]
   }
 
-  if (enable_print_preview && !is_chromeos) {
+  if (enable_print_preview && !is_chromeos_ash) {
     public_deps += [ "//chrome/service" ]
   }
 }
@@ -734,7 +736,7 @@
 
   deps = [ ":test_support" ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [ "base/browser_tests_main_chromeos.cc" ]
   } else {
     sources += [ "base/browser_tests_main.cc" ]
@@ -1617,7 +1619,7 @@
       ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../browser/chrome_main_browsertest.cc",
         "../browser/chromeos/login/saml/test_client_cert_saml_idp_mixin.cc",
@@ -1671,7 +1673,7 @@
       sources += [ "../browser/metrics/power_metrics_provider_mac_unittest.cc" ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       data += [
         # TODO(GYP): figure out which of these things are
         # actually needed and also which should be pulled in via
@@ -1753,7 +1755,7 @@
       ]
     }
 
-    if (!is_chromeos) {
+    if (!is_chromeos_ash) {
       sources += [
         "../browser/policy/native_messaging_policy_browsertest.cc",
         "../browser/ui/views/accessibility/accessibility_focus_highlight_browsertest.cc",
@@ -1767,7 +1769,7 @@
         "//chrome/test/data/webui:browser_tests_js_mojo_webui",
         "//chrome/test/data/webui:browser_tests_js_webui",
       ]
-      if (is_chromeos) {
+      if (is_chromeos_ash) {
         deps += [
           "//chrome/browser/resources/gaia_auth_host:browser_tests",
           "//chromeos/components/help_app_ui:browser_tests_js",
@@ -1799,7 +1801,7 @@
           [ "../browser/ssl/captive_portal_blocking_page_browsertest.cc" ]
     }
 
-    if (!is_chromeos) {
+    if (!is_chromeos_ash) {
       sources += [
         "../browser/external_protocol/external_protocol_handler_browsertest.cc",
         "../browser/external_protocol/external_protocol_policy_browsertest.cc",
@@ -1809,7 +1811,7 @@
       ]
     }
 
-    if (is_win || is_chromeos) {
+    if (is_win || is_chromeos_ash) {
       sources += [ "../browser/webshare/share_service_browsertest.cc" ]
     }
 
@@ -1848,7 +1850,7 @@
         "//ppapi/native_client:irt",
         "//ppapi/tests/extensions",
       ]
-      if (is_chromeos) {
+      if (is_chromeos_ash) {
         sources += [
           "../browser/ui/views/extensions/request_file_system_dialog_browsertest.cc",
           "//third_party/liblouis/wasm/liblouis_wrapper_browsertest.cc",
@@ -2135,7 +2137,7 @@
         ]
       }
 
-      if (is_chromeos) {
+      if (is_chromeos_ash) {
         sources += [
           "../browser/accessibility/accessibility_extension_api_browsertest.cc",
           "../browser/apps/platform_apps/api/arc_apps_private/arc_apps_private_apitest.cc",
@@ -2330,7 +2332,7 @@
           "../browser/ui/views/status_bubble_views_browsertest_mac.mm",
         ]
       }
-      if (!is_chromeos) {
+      if (!is_chromeos_ash) {
         sources += [
           "../browser/ui/views/bookmarks/bookmark_bubble_sign_in_delegate_browsertest.cc",
           "../browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc",
@@ -2369,12 +2371,12 @@
 
     # Browser tests for functionality that is only intended to be present in
     # ash-chrome, not lacros-chrome.
-    if (is_chromeos && !chromeos_is_browser_only) {
+    if (is_chromeos_ash && !is_chromeos_lacros) {
       sources +=
           [ "../browser/chromeos/crosapi/screen_manager_ash_browsertest.cc" ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../browser/apps/platform_apps/app_window_interactive_uitest_base.cc",
         "../browser/apps/platform_apps/app_window_interactive_uitest_base.h",
@@ -2825,14 +2827,14 @@
         "base/interactive_test_utils_views.cc",
       ]
       data += [ "../browser/resources/chromeos/accessibility/switch_access/test_support.js" ]
-      if (is_chromeos && !is_official_build) {
+      if (is_chromeos_ash && !is_official_build) {
         sources += [
           "../browser/chromeos/web_applications/sample_system_web_app_integration_browsertest.cc",
           "../browser/chromeos/web_applications/telemetry_extension_integration_browsertest.cc",
         ]
       }
       if (use_cups) {
-        if (is_chromeos) {
+        if (is_chromeos_ash) {
           sources += [
             "../browser/chromeos/extensions/printing/fake_print_job_controller.cc",
             "../browser/chromeos/extensions/printing/fake_print_job_controller.h",
@@ -2890,7 +2892,7 @@
         "//chromeos/ui/frame:test_support",
         "//components/crash/content/browser/error_reporting:mock_crash_endpoint",
       ]
-    } else {  # !is_chromeos
+    } else {  # !is_chromeos_ash
       sources -= [
         "../browser/invalidation/profile_invalidation_provider_factory_browsertest.cc",
         "../browser/net/nss_context_chromeos_browsertest.cc",
@@ -3021,11 +3023,11 @@
         "../browser/renderer_context_menu/spelling_options_submenu_observer_browsertest.cc",
       ]
     }
-    if (!is_posix || is_chromeos) {
+    if (!is_posix || is_chromeos_ash) {
       sources -= [ "../common/time_format_browsertest.cc" ]
     }
 
-    if (is_mac || is_win || is_linux) {
+    if (is_mac || is_win || (is_linux || is_chromeos_lacros)) {
       sources += [
         # Tests for non mobile and non CrOS (includes Linux, Win, Mac).
         "../browser/browser_switcher/browser_switcher_browsertest.cc",
@@ -3036,10 +3038,10 @@
         "../browser/profiles/profile_statistics_browsertest.cc",
       ]
     }
-    if (is_mac || is_win || is_chromeos) {
+    if (is_mac || is_win || is_chromeos_ash) {
       sources += [ "../browser/extensions/api/networking_cast_private/networking_cast_private_apitest.cc" ]
     }
-    if ((is_linux && !chromeos_is_browser_only) || is_mac) {
+    if (((is_linux || is_chromeos_lacros) && !is_chromeos_lacros) || is_mac) {
       sources +=
           [ "../browser/first_run/first_run_internal_posix_browsertest.cc" ]
     }
@@ -3095,7 +3097,7 @@
         "../browser/printing/pwg_raster_converter_browsertest.cc",
         "../browser/ui/webui/print_preview/print_preview_ui_browsertest.cc",
       ]
-      if (enable_extensions && !is_chromeos) {
+      if (enable_extensions && !is_chromeos_ash) {
         sources += [ "../browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc" ]
       }
       if (!is_mac && !is_chromeos_ash && !is_chromeos_lacros) {
@@ -3105,7 +3107,7 @@
           "../browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc",
         ]
       }
-      if (!is_chromeos) {
+      if (!is_chromeos_ash) {
         sources += [
           # Not intended to run on ChromeOS.
           "../browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc",
@@ -3150,11 +3152,11 @@
       }
     }
 
-    if (is_chromeos || (is_linux && use_dbus)) {
+    if (is_chromeos_ash || ((is_linux || is_chromeos_lacros) && use_dbus)) {
       sources += [ "../browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc" ]
     }
 
-    if (toolkit_views && !is_chromeos) {
+    if (toolkit_views && !is_chromeos_ash) {
       sources +=
           [ "../browser/ui/screen_capture_notification_ui_browsertest.cc" ]
     }
@@ -3177,7 +3179,8 @@
           [ "../browser/site_isolation/spellcheck_per_process_browsertest.cc" ]
     }
 
-    if (is_win || is_mac || (is_linux && !chromeos_is_browser_only)) {
+    if (is_win || is_mac ||
+        ((is_linux || is_chromeos_lacros) && !is_chromeos_lacros)) {
       sources +=
           [ "../browser/ui/views/profiles/profile_picker_view_browsertest.cc" ]
     }
@@ -3186,7 +3189,7 @@
   }
 }
 
-if (chromeos_is_browser_only) {
+if (is_chromeos_lacros) {
   # This test target is intended for lacros chrome specific tests that depend
   # on crosapi, for generic tests, please use 'browser_tests' target instead.
   test("lacros_chrome_browsertests") {
@@ -3946,7 +3949,7 @@
     ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [
       "../browser/notifications/notification_platform_bridge_chromeos_unittest.cc",
       "../browser/performance_manager/policies/dynamic_tcmalloc_policy_chromeos_unittest.cc",
@@ -3988,7 +3991,7 @@
     }
   }
 
-  if (is_win || is_chromeos) {
+  if (is_win || is_chromeos_ash) {
     sources += [ "../browser/webshare/share_service_unittest.cc" ]
   }
 
@@ -4049,7 +4052,7 @@
       "../browser/webauthn/chrome_authenticator_request_delegate_unittest.cc",
     ]
   }
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [
       "../../chromeos/memory/userspace_swap/userspace_swap.cc",
       "../browser/device_identity/chromeos/device_oauth2_token_store_chromeos_unittest.cc",
@@ -4061,7 +4064,7 @@
     ]
   }
 
-  if (is_win || is_mac || (is_linux && !is_chromeos)) {
+  if (is_win || is_mac || (is_linux || is_chromeos_lacros)) {
     sources += [ "../test/pixel/browser_skia_gold_pixel_diff_unittest.cc" ]
   }
 
@@ -4711,7 +4714,7 @@
     if (is_posix || is_fuchsia) {
       sources += [ "../browser/process_singleton_posix_unittest.cc" ]
     }
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc",
         "../browser/ui/webui/help/version_updater_chromeos_unittest.cc",
@@ -4773,7 +4776,7 @@
     if (is_mac) {
       deps += [ ":firefox_importer_interface" ]
     }
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       deps += [
         "//chrome/services/sharing/public/cpp",
         "//chrome/services/sharing/public/cpp:unit_tests",
@@ -4850,7 +4853,7 @@
 
     if (include_js_tests) {
       deps += [ "//chrome/test/data/webui:unit_tests_js" ]
-      if (is_chromeos) {
+      if (is_chromeos_ash) {
         deps += [
           "//chrome/browser/resources/chromeos/accessibility:unit_tests_js",
         ]
@@ -4859,8 +4862,8 @@
   }
 
   if (enable_native_notifications) {
-    # TODO(crbug.com/1052397): Rename chromeos_is_browser_only to is_lacros.
-    if (is_linux && !chromeos_is_browser_only) {
+    # TODO(crbug.com/1052397): Rename is_chromeos_lacros to is_chromeos_lacros.
+    if ((is_linux || is_chromeos_lacros) && !is_chromeos_lacros) {
       sources += [ "../browser/notifications/notification_platform_bridge_linux_unittest.cc" ]
     }
 
@@ -4889,7 +4892,7 @@
     ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources -= [
       "../browser/notifications/notification_ui_manager_unittest.cc",
       "../browser/signin/chrome_signin_status_metrics_provider_delegate_unittest.cc",
@@ -5448,7 +5451,7 @@
       ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc",
         "../browser/extensions/extension_garbage_collector_chromeos_unittest.cc",
@@ -5513,7 +5516,7 @@
       sources +=
           [ "../browser/ui/startup/mac_system_infobar_delegate_unittest.cc" ]
     }
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc",
         "../browser/chromeos/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc",
@@ -5544,7 +5547,7 @@
       "//ui/wm",
     ]
   }
-  if (!is_chromeos && is_linux) {
+  if (is_linux || is_chromeos_lacros) {
     sources += [
       "../browser/shell_integration_linux_unittest.cc",
       "../browser/ui/global_media_controls/media_notification_device_monitor_unittest.cc",
@@ -5553,7 +5556,7 @@
     ]
   }
 
-  if (is_android || is_chromeos) {
+  if (is_android || is_chromeos_ash) {
     sources += [
       "../browser/installable/digital_asset_links/digital_asset_links_handler_unittest.cc",
       "../browser/media/protected_media_identifier_permission_context_unittest.cc",
@@ -5763,7 +5766,7 @@
 
       deps += [ "//ipc" ]
 
-      if (!is_chromeos) {
+      if (!is_chromeos_ash) {
         sources += [
           "../browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc",
           "../common/cloud_print/cloud_print_helpers_unittest.cc",
@@ -5798,7 +5801,7 @@
       "../browser/sessions/tab_loader_unittest.cc",
     ]
   }
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     deps += [
       "//chrome/browser/chromeos:unit_tests",
       "//chromeos/ime:gencode",
@@ -5881,7 +5884,7 @@
     sources +=
         [ "../browser/notifications/notification_image_retainer_unittest.cc" ]
   }
-  if (is_win || is_mac || is_chromeos) {
+  if (is_win || is_mac || is_chromeos_ash) {
     sources += [ "../browser/extensions/api/networking_private/networking_private_crypto_unittest.cc" ]
   }
   if (enable_rlz) {
@@ -5940,7 +5943,7 @@
       ]
     }
   }
-  if (!is_android && !is_chromeos) {
+  if (!is_android && !is_chromeos_ash) {
     sources += [
       "../browser/device_identity/device_oauth2_token_store_desktop_unittest.cc",
       "../browser/enterprise/remote_commands/clear_browsing_data_job_unittest.cc",
@@ -5962,7 +5965,7 @@
 
     deps += [ "//components/enterprise:test_support" ]
   }
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [
       "../browser/upgrade_detector/installed_version_updater_chromeos_unittest.cc",
       "../browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc",
@@ -6065,7 +6068,7 @@
       "../browser/ui/views/user_education/feature_promo_controller_views_unittest.cc",
       "../browser/ui/views/window_name_prompt_unittest.cc",
     ]
-    if (is_linux) {
+    if (is_linux || is_chromeos_lacros) {
       sources += [ "../browser/ui/views/frame/desktop_linux_browser_frame_view_layout_unittest.cc" ]
     }
     if (enable_plugins) {
@@ -6082,14 +6085,14 @@
         "../browser/ui/views/frame/browser_non_client_frame_view_mac_unittest.mm",
       ]
     }
-    if (!is_chromeos) {
+    if (!is_chromeos_ash) {
       sources += [
         "../browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc",
         "../browser/ui/views/sync/one_click_signin_dialog_view_unittest.cc",
         "../browser/ui/views/sync/profile_signin_confirmation_dialog_views_unittest.cc",
       ]
     }
-    if ((is_linux && !is_chromeos) || is_win) {
+    if (is_linux || is_chromeos_lacros || is_win) {
       sources +=
           [ "../browser/notifications/popups_only_ui_controller_unittest.cc" ]
     }
@@ -6145,7 +6148,7 @@
     sources += [ "../browser/extensions/blocklist_unittest.cc" ]
   }
 
-  if (is_win || is_mac || (is_linux && !is_chromeos)) {
+  if (is_win || is_mac || (is_linux || is_chromeos_lacros)) {
     sources += [
       "../browser/browser_switcher/alternative_browser_driver_unittest.cc",
       "../browser/browser_switcher/browser_switcher_navigation_throttle_unittest.cc",
@@ -6156,7 +6159,7 @@
     ]
   }
 
-  if (enable_widevine_cdm_component && is_linux) {
+  if (enable_widevine_cdm_component && (is_linux || is_chromeos_lacros)) {
     sources +=
         [ "../common/media/component_widevine_cdm_hint_file_linux_unittest.cc" ]
   }
@@ -6202,7 +6205,7 @@
     deps = [ "//chrome/install_static/test:test_support" ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [
       "base/chrome_ash_test_base.cc",
       "base/chrome_ash_test_base.h",
@@ -6293,7 +6296,7 @@
       deps += [ "//extensions/browser" ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       deps += [
         "//ash/public/cpp",
         "//chromeos/services/device_sync",
@@ -6313,7 +6316,7 @@
     sources = [ "../common/safe_browsing/ipc_protobuf_message_test.proto" ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     assert(enable_extensions)
 
     # These tests are only meant to run on an FYI bot because they
@@ -6336,6 +6339,7 @@
       deps = [
         ":test_support",
         ":test_support_ui",
+        "//build:chromeos_buildflags",
         "//chrome:packed_resources",
         "//chrome:resources",
         "//chrome:strings",
@@ -6649,7 +6653,7 @@
         "//ui/views:views_interactive_ui_tests",
         "//ui/views/controls/webview:test_support",
       ]
-      if (is_linux && !is_chromeos) {
+      if (is_linux || is_chromeos_lacros) {
         # Desktop linux.
         sources -= [
           # TODO(port): This times out. Attempts have been made to fix the
@@ -6658,7 +6662,7 @@
           "../browser/ui/views/keyboard_access_browsertest.cc",
         ]
       }
-      if (!is_chromeos) {
+      if (!is_chromeos_ash) {
         sources += [ "../browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc" ]
         deps += [
           "../browser/media/router:test_support",
@@ -6687,7 +6691,7 @@
           [ "../browser/notifications/notification_interactive_uitest_mac.mm" ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       deps += [
         "//chrome/browser/media/router:test_support",
         "//chromeos/dbus",
@@ -6697,7 +6701,7 @@
           [ "../browser/ui/signin_view_controller_interactive_uitest.cc" ]
       sources +=
           [ "../browser/ui/app_list/app_list_client_interactive_uitest.cc" ]
-    } else {  # ! is_chromeos
+    } else {  # ! is_chromeos_ash
       # Non-ChromeOS notifications tests.
       sources += [
         "../browser/notifications/notification_interactive_uitest.cc",
@@ -6792,7 +6796,7 @@
       configs += [ "//build/config/linux/atk" ]
     }
 
-    if (is_linux && !is_chromeos) {
+    if (is_linux || is_chromeos_lacros) {
       deps += [ "//ui/base/ime/linux" ]
     }
 
@@ -7020,7 +7024,7 @@
         "../browser/sync/test/integration/dictionary_load_observer.h",
       ]
     }
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../browser/sync/test/integration/os_sync_test.cc",
         "../browser/sync/test/integration/os_sync_test.h",
@@ -7168,7 +7172,7 @@
         "//ui/resources",
       ]
     }
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../browser/sync/test/integration/single_client_app_list_sync_test.cc",
         "../browser/sync/test/integration/single_client_arc_package_sync_test.cc",
@@ -7492,7 +7496,7 @@
 }
 
 # Test binary for the ChromeOS usage time limit processor tests.
-if (is_chromeos) {
+if (is_chromeos_ash) {
   test("usage_time_limit_unittests") {
     testonly = true
     sources = [
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
index ec2abf63..be13b4b 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
@@ -5,31 +5,30 @@
 package org.chromium.chrome.test;
 
 import android.app.Activity;
+import android.app.Instrumentation;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.internal.runner.listener.InstrumentationResultPrinter;
+import android.support.test.rule.ActivityTestRule;
 import android.view.Menu;
 
-import androidx.annotation.NonNull;
-
 import org.hamcrest.Matchers;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
+import org.chromium.base.ActivityState;
 import org.chromium.base.ApplicationStatus;
+import org.chromium.base.ApplicationStatus.ActivityStateListener;
 import org.chromium.base.CommandLine;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseActivityTestRule;
+import org.chromium.base.Log;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.ScalableTimeout;
-import org.chromium.chrome.browser.DeferredStartupHandler;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -42,9 +41,7 @@
 import org.chromium.chrome.browser.ui.appmenu.AppMenuTestSupport;
 import org.chromium.chrome.test.util.ChromeApplicationTestUtils;
 import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.NewTabPageTestUtils;
 import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.components.infobars.InfoBar;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
@@ -62,13 +59,14 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Custom  {@link ActivityTestRule} for test using  {@link ChromeActivity}.
  *
  * @param <T> The {@link Activity} class under test.
  */
-public class ChromeActivityTestRule<T extends ChromeActivity> extends BaseActivityTestRule<T> {
+public class ChromeActivityTestRule<T extends ChromeActivity> extends ActivityTestRule<T> {
     private static final String TAG = "ChromeATR";
 
     // The number of ms to wait for the rendering activity to be started.
@@ -77,13 +75,20 @@
     private static final long OMNIBOX_FIND_SUGGESTION_TIMEOUT_MS = 10 * 1000;
 
     private Thread.UncaughtExceptionHandler mDefaultUncaughtExceptionHandler;
+    private Class<T> mChromeActivityClass;
+    private T mSetActivity;
     private String mCurrentTestName;
 
     @Rule
     private EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule();
 
     protected ChromeActivityTestRule(Class<T> activityClass) {
-        super(activityClass);
+        this(activityClass, false);
+    }
+
+    protected ChromeActivityTestRule(Class<T> activityClass, boolean initialTouchMode) {
+        super(activityClass, initialTouchMode, false);
+        mChromeActivityClass = activityClass;
     }
 
     @Override
@@ -130,11 +135,13 @@
         return ACTIVITY_START_TIMEOUT_MS;
     }
 
-    // This has to be here or getActivity will return a T that extends Activity, not a T that
-    // extends ChromeActivity.
+    // TODO(yolandyan): remove this once startActivityCompletely is refactored out of
+    // ChromeActivityTestRule
     @Override
-    @SuppressWarnings("RedundantOverride")
     public T getActivity() {
+        if (mSetActivity != null) {
+            return mSetActivity;
+        }
         return super.getActivity();
     }
 
@@ -145,14 +152,6 @@
     }
 
     /**
-     * TODO(https://crbug.com/1146574): This only exists here because legacy ActivityTestRule
-     * inherited from UiThreadTestRule. This function should be removed.
-     */
-    public void runOnUiThread(Runnable r) {
-        ThreadUtils.runOnUiThreadBlocking(r);
-    }
-
-    /**
      * @return The {@link AppMenuCoordinator} for the activity.
      */
     public AppMenuCoordinator getAppMenuCoordinator() {
@@ -197,37 +196,49 @@
     }
 
     /**
-     * Similar to #launchActivity(Intent), but waits for the Activity tab to be initialized.
+     * Invokes {@link Instrumentation#startActivitySync(Intent)} and sets the
+     * test case's activity to the result. See the documentation for
+     * {@link Instrumentation#startActivitySync(Intent)} on the timing of the
+     * return, but generally speaking the activity's "onCreate" has completed
+     * and the activity's main looper has become idle.
+     *
+     * TODO(yolandyan): very similar to ActivityTestRule#launchActivity(Intent),
+     * yet small differences remains (e.g. launchActivity() uses FLAG_ACTIVITY_NEW_TASK while
+     * startActivityCompletely doesn't), need to refactor and use only launchActivity
+     * after the JUnit4 migration
      */
     public void startActivityCompletely(Intent intent) {
-        DeferredStartupHandler.setExpectingActivityStartupForTesting();
-        launchActivity(intent);
-        waitForActivityNativeInitializationComplete();
-
-        CriteriaHelper.pollUiThread(
-                () -> getActivity().getActivityTab() != null, "Tab never selected/initialized.");
-        Tab tab = getActivity().getActivityTab();
-
-        ChromeTabUtils.waitForTabPageLoaded(tab, (String) null);
-
-        if (tab != null && UrlUtilities.isNTPUrl(ChromeTabUtils.getUrlStringOnUiThread(tab))
-                && !getActivity().isInOverviewMode()) {
-            NewTabPageTestUtils.waitForNtpLoaded(tab);
-        }
-
-        Assert.assertTrue("Deferred startup never completed. Did you try to start an Activity "
-                        + "that was already started?",
-                DeferredStartupHandler.waitForDeferredStartupCompleteForTesting(
-                        ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL)));
-
-        Assert.assertNotNull(tab);
-        Assert.assertNotNull(tab.getView());
-    }
-
-    @Override
-    public void launchActivity(@NonNull Intent startIntent) {
         Features.ensureCommandLineIsUpToDate();
-        super.launchActivity(startIntent);
+
+        final CallbackHelper activityCallback = new CallbackHelper();
+        final AtomicReference<T> activityRef = new AtomicReference<>();
+        ActivityStateListener stateListener = new ActivityStateListener() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void onActivityStateChange(Activity activity, int newState) {
+                if (newState == ActivityState.RESUMED) {
+                    if (!mChromeActivityClass.isAssignableFrom(activity.getClass())) return;
+
+                    activityRef.set((T) activity);
+                    activityCallback.notifyCalled();
+                    ApplicationStatus.unregisterActivityStateListener(this);
+                }
+            }
+        };
+        ApplicationStatus.registerStateListenerForAllActivities(stateListener);
+
+        try {
+            InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
+            activityCallback.waitForCallback("Activity did not start as expected", 0);
+            T activity = activityRef.get();
+            Assert.assertNotNull("Activity reference is null.", activity);
+            setActivity(activity);
+            Log.d(TAG, "startActivityCompletely <<");
+        } catch (TimeoutException e) {
+            throw new RuntimeException(e);
+        } finally {
+            ApplicationStatus.unregisterActivityStateListener(stateListener);
+        }
     }
 
     /**
@@ -461,6 +472,10 @@
         return getActivity().getWindowAndroid().getKeyboardDelegate();
     }
 
+    public void setActivity(T chromeActivity) {
+        mSetActivity = chromeActivity;
+    }
+
     /**
      * Waits for an Activity of the given class to be started.
      * @return The Activity.
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeTabbedActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeTabbedActivityTestRule.java
index 65e683d2..cc708d7 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeTabbedActivityTestRule.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeTabbedActivityTestRule.java
@@ -20,8 +20,11 @@
 import org.chromium.base.Log;
 import org.chromium.base.test.util.ApplicationTestUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
+import org.chromium.chrome.browser.DeferredStartupHandler;
 import org.chromium.chrome.browser.omnibox.UrlBar;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabCreationState;
@@ -33,6 +36,7 @@
 import org.chromium.chrome.test.util.MenuUtils;
 import org.chromium.chrome.test.util.NewTabPageTestUtils;
 import org.chromium.chrome.test.util.WaitForFocusHelper;
+import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 import java.util.concurrent.TimeoutException;
@@ -109,7 +113,31 @@
      */
     public void startMainActivityFromIntent(Intent intent, String url) {
         prepareUrlIntent(intent, url);
+
+        DeferredStartupHandler.setExpectingActivityStartupForTesting();
         startActivityCompletely(intent);
+        waitForActivityNativeInitializationComplete();
+
+        CriteriaHelper.pollUiThread(
+                () -> getActivity().getActivityTab() != null, "Tab never selected/initialized.");
+        Tab tab = getActivity().getActivityTab();
+
+        ChromeTabUtils.waitForTabPageLoaded(tab, (String) null);
+
+        if (tab != null && UrlUtilities.isNTPUrl(ChromeTabUtils.getUrlStringOnUiThread(tab))
+                && !getActivity().isInOverviewMode()) {
+            NewTabPageTestUtils.waitForNtpLoaded(tab);
+        }
+
+        Assert.assertTrue("Deferred startup never completed. Did you try to start an Activity "
+                        + "that was already started?",
+                DeferredStartupHandler.waitForDeferredStartupCompleteForTesting(
+                        ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL)));
+
+        Assert.assertNotNull(tab);
+        Assert.assertNotNull(tab.getView());
+
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     /**
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java
index dba985d0..e401694 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java
@@ -39,7 +39,6 @@
         super();
         mActivityTestRule = activityTestRule;
         mClearAllTabState = clearAllTabState;
-        mActivityTestRule.setFinishActivity(false);
     }
 
     @Override
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc
index 921b072..f6fe4b1 100644
--- a/chrome/test/base/browser_with_test_window_test.cc
+++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -7,6 +7,7 @@
 #include "base/location.h"
 #include "base/run_loop.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "chrome/browser/profiles/profile_destroyer.h"
 #include "chrome/browser/ui/browser.h"
@@ -28,7 +29,7 @@
 #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
 #include "components/constrained_window/constrained_window_views.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "content/public/browser/context_factory.h"
 #endif
@@ -43,7 +44,7 @@
 
 void BrowserWithTestWindowTest::SetUp() {
   testing::Test::SetUp();
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   ash_test_helper_.SetUp();
 #endif
 
@@ -103,7 +104,7 @@
   tablet_state_.reset();
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // If initialized, the KioskAppManager will register an observer to
   // CrosSettings and will need to be destroyed before it. Having it destroyed
   // as part of the teardown will avoid unexpected test failures.
@@ -124,7 +125,7 @@
 }
 
 gfx::NativeWindow BrowserWithTestWindowTest::GetContext() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   return ash_test_helper_.GetContext();
 #elif defined(TOOLKIT_VIEWS)
   return views_test_helper_->GetContext();
@@ -207,7 +208,7 @@
   return std::unique_ptr<Browser>(Browser::Create(params));
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 chromeos::ScopedCrosSettingsTestHelper*
 BrowserWithTestWindowTest::GetCrosSettingsHelper() {
   return &cros_settings_test_helper_;
@@ -217,7 +218,7 @@
 BrowserWithTestWindowTest::GetInstallAttributes() {
   return GetCrosSettingsHelper()->InstallAttributes();
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 BrowserWithTestWindowTest::BrowserWithTestWindowTest(
     std::unique_ptr<content::BrowserTaskEnvironment> task_environment,
diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h
index 23638d3d..1191129 100644
--- a/chrome/test/base/browser_with_test_window_test.h
+++ b/chrome/test/base/browser_with_test_window_test.h
@@ -21,7 +21,7 @@
 #if defined(TOOLKIT_VIEWS)
 #include "chrome/test/views/chrome_test_views_delegate.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/test/ash_test_helper.h"
 #include "ash/test/ash_test_views_delegate.h"
 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
@@ -137,7 +137,7 @@
     return window_.release();
   }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   ash::AshTestHelper* ash_test_helper() { return &ash_test_helper_; }
 #endif
 
@@ -189,7 +189,7 @@
 
 #if defined(TOOLKIT_VIEWS)
   views::TestViewsDelegate* test_views_delegate() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     return test_views_delegate_.get();
 #else
     return views_test_helper_->test_views_delegate();
@@ -197,7 +197,7 @@
   }
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::ScopedCrosSettingsTestHelper* GetCrosSettingsHelper();
   chromeos::StubInstallAttributes* GetInstallAttributes();
 #endif
@@ -213,7 +213,7 @@
   // We need to create a MessageLoop, otherwise a bunch of things fails.
   std::unique_ptr<content::BrowserTaskEnvironment> task_environment_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
   chromeos::ScopedTestUserManager test_user_manager_;
 #endif
@@ -228,7 +228,7 @@
   std::unique_ptr<BrowserWindow> window_;  // Usually a TestBrowserWindow.
   std::unique_ptr<Browser> browser_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   ash::AshTestHelper ash_test_helper_;
   std::unique_ptr<views::TestViewsDelegate> test_views_delegate_ =
       std::make_unique<ChromeTestViewsDelegate<ash::AshTestViewsDelegate>>();
diff --git a/chrome/test/base/chrome_render_view_host_test_harness.cc b/chrome/test/base/chrome_render_view_host_test_harness.cc
index b21500c..0c6a9ace 100644
--- a/chrome/test/base/chrome_render_view_host_test_harness.cc
+++ b/chrome/test/base/chrome_render_view_host_test_harness.cc
@@ -8,10 +8,11 @@
 
 #include "base/bind.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/signin/signin_error_controller_factory.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/shell.h"
 #endif
 
@@ -26,7 +27,7 @@
 
 void ChromeRenderViewHostTestHarness::TearDown() {
   RenderViewHostTestHarness::TearDown();
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   ash::Shell::DeleteInstance();
 #endif
 }
diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc
index 2984a87..789ed297 100644
--- a/chrome/test/base/chrome_test_launcher.cc
+++ b/chrome/test/base/chrome_test_launcher.cc
@@ -21,6 +21,7 @@
 #include "base/test/test_file_util.h"
 #include "base/test/test_switches.h"
 #include "base/time/time.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/app/chrome_main_delegate.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_switches.h"
@@ -59,8 +60,10 @@
 #include "chrome/installer/util/firewall_manager_win.h"
 #endif
 
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
 #if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 #include "chrome/browser/first_run/scoped_relaunch_chrome_browser_override.h"
 #include "chrome/browser/upgrade_detector/installed_version_poller.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -74,8 +77,10 @@
   // Android browser tests run child processes as threads instead.
   content::ContentTestSuiteBase::RegisterInProcessThreads();
 #endif
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
 #if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   InstalledVersionPoller::ScopedDisableForTesting disable_polling(
       InstalledVersionPoller::MakeScopedDisableForTesting());
 #endif
@@ -225,8 +230,10 @@
         network_service_test_helper.get()));
   }
 
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
 #if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   // Cause a test failure for any test that triggers an unexpected relaunch.
   // Tests that fail here should likely be restructured to put the "before
   // relaunch" code into a PRE_ test with its own
diff --git a/chrome/test/base/chrome_test_suite.cc b/chrome/test/base/chrome_test_suite.cc
index 5008ae51..4c9c645 100644
--- a/chrome/test/base/chrome_test_suite.cc
+++ b/chrome/test/base/chrome_test_suite.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/test/base/chrome_test_suite.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include <stdio.h>
 #include <unistd.h>
 #endif
@@ -27,7 +27,7 @@
 #include "media/base/media.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/process/process_metrics.h"
 #include "chromeos/constants/chromeos_paths.h"
 #endif
@@ -46,7 +46,7 @@
 namespace {
 
 bool IsCrosPythonProcess() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   char buf[80];
   int num_read = readlink(base::kProcSelfExe, buf, sizeof(buf) - 1);
   if (num_read == -1)
@@ -56,7 +56,7 @@
   return !strncmp(strrchr(buf, '/'), kPythonPrefix, sizeof(kPythonPrefix) - 1);
 #else
   return false;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 }  // namespace
diff --git a/chrome/test/base/chrome_unit_test_suite.cc b/chrome/test/base/chrome_unit_test_suite.cc
index 506b3ca..18c1024 100644
--- a/chrome/test/base/chrome_unit_test_suite.cc
+++ b/chrome/test/base/chrome_unit_test_suite.cc
@@ -9,6 +9,7 @@
 #include "base/path_service.h"
 #include "base/process/process_handle.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_content_browser_client.h"
 #include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
@@ -31,7 +32,7 @@
 #include "ui/base/ui_base_paths.h"
 #include "ui/gl/test/gl_surface_test_support.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chromeos/constants/chromeos_paths.h"
 #endif
 
@@ -141,14 +142,14 @@
   content::RegisterPathProvider();
   ui::RegisterPathProvider();
   component_updater::RegisterPathProvider(chrome::DIR_COMPONENTS,
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
                                           chromeos::DIR_PREINSTALLED_COMPONENTS,
 #else
                                           chrome::DIR_INTERNAL_PLUGINS,
 #endif
                                           chrome::DIR_USER_DATA);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::RegisterPathProvider();
 #endif
 
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc
index 281dbd47..8c95a5a3 100644
--- a/chrome/test/base/in_process_browser_test.cc
+++ b/chrome/test/base/in_process_browser_test.cc
@@ -94,7 +94,7 @@
 #include "components/storage_monitor/test_storage_monitor.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/public/cpp/test/shell_test_api.h"
 #include "ash/shell.h"
 #include "base/system/sys_info.h"
@@ -106,9 +106,9 @@
 #include "components/user_manager/user_names.h"
 #include "ui/display/display_switches.h"
 #include "ui/events/test/event_generator.h"
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if !defined(OS_CHROMEOS) && defined(USE_X11)
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(USE_X11)
 #include "ui/views/test/test_desktop_screen_x11.h"
 #endif
 
@@ -121,14 +121,14 @@
 #include "ui/views/widget/widget.h"
 #endif
 
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "ui/aura/test/ui_controls_factory_aura.h"
 #include "ui/base/test/ui_controls.h"
 #endif
 
 namespace {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 class FakeDeviceSyncImplFactory
     : public chromeos::device_sync::DeviceSyncImpl::Factory {
  public:
@@ -154,7 +154,7 @@
   static base::NoDestructor<FakeDeviceSyncImplFactory> factory;
   return factory.get();
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if !defined(OS_ANDROID)
 // An observer that returns back to test code after a new profile is
@@ -192,14 +192,14 @@
 #if defined(TOOLKIT_VIEWS)
   views::Widget::Widgets widgets_to_layout;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // WidgetTest::GetAllWidgets() doesn't work for ChromeOS in a production
   // environment. We must get the Widgets ourself.
   for (aura::Window* root_window : ash::Shell::GetAllRootWindows())
     views::Widget::GetAllChildWidgets(root_window, &widgets_to_layout);
 #else
   widgets_to_layout = views::test::WidgetTest::GetAllWidgets();
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   for (views::Widget* widget : widgets_to_layout)
     widget->LayoutRootViewIfNecessary();
@@ -260,7 +260,7 @@
   ASSERT_TRUE(SetUpUserDataDirectory())
       << "Could not set up user data directory.";
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // No need to redirect log for test.
   command_line->AppendSwitch(switches::kDisableLoggingRedirect);
 
@@ -317,7 +317,7 @@
   chrome_browser_net::NetErrorTabHelper::set_state_for_testing(
       chrome_browser_net::NetErrorTabHelper::TESTING_FORCE_DISABLED);
 
-#if defined(OS_CHROMEOS) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
   // On Chrome OS, access to files via file: scheme is restricted. Enable
   // access to all files here since browser_tests and interactive_ui_tests
   // rely on the ability to open any files via file: scheme.
@@ -372,7 +372,7 @@
   OSCryptMocker::TearDown();
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::device_sync::DeviceSyncImpl::Factory::SetCustomFactory(nullptr);
 #endif
 }
@@ -443,7 +443,7 @@
 }
 
 void InProcessBrowserTest::SetScreenInstance() {
-#if defined(USE_X11) && !defined(OS_CHROMEOS)
+#if defined(USE_X11) && !BUILDFLAG(IS_CHROMEOS_ASH)
   if (!features::IsUsingOzonePlatform()) {
     DCHECK(!display::Screen::GetScreen());
     display::Screen::SetScreenInstance(
@@ -579,7 +579,7 @@
 
   SelectFirstBrowser();
   if (browser_) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     // There are cases where windows get created maximized by default.
     if (browser_->window()->IsMaximized())
       browser_->window()->Restore();
@@ -594,7 +594,7 @@
     // The ozone implementation of CreateUIControlsAura differs from other
     // implementation in that it requires a WindowTreeHost. Thus, it must be
     // initialized here rather than earlier.
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
     BrowserWindow* window = browser_->window();
     CHECK(window);
     ui_controls::InstallUIControlsAura(
diff --git a/chrome/test/base/interactive_test_utils_win.cc b/chrome/test/base/interactive_test_utils_win.cc
index 8329f145..828013a 100644
--- a/chrome/test/base/interactive_test_utils_win.cc
+++ b/chrome/test/base/interactive_test_utils_win.cc
@@ -19,6 +19,7 @@
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/base/interactive_test_utils_aura.h"
 #include "chrome/test/base/process_lineage_win.h"
 #include "chrome/test/base/save_desktop_snapshot_win.h"
@@ -31,18 +32,18 @@
 namespace ui_test_utils {
 
 void HideNativeWindow(gfx::NativeWindow window) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   HideNativeWindowAura(window);
 #else
   HWND hwnd = window->GetHost()->GetAcceleratedWidget();
   ::ShowWindow(hwnd, SW_HIDE);
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 bool ShowAndFocusNativeWindow(gfx::NativeWindow window) {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   ShowAndFocusNativeWindowAura(window);
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   window->Show();
   // Always make sure the window hosting ash is visible and focused.
   HWND hwnd = window->GetHost()->GetAcceleratedWidget();
diff --git a/chrome/test/base/interactive_ui_tests_main.cc b/chrome/test/base/interactive_ui_tests_main.cc
index 475c08f..35ac201 100644
--- a/chrome/test/base/interactive_ui_tests_main.cc
+++ b/chrome/test/base/interactive_ui_tests_main.cc
@@ -7,6 +7,7 @@
 #include "base/command_line.h"
 #include "base/test/launcher/test_launcher.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/base/chrome_test_suite.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
@@ -16,7 +17,7 @@
 #if defined(USE_AURA)
 #include "ui/aura/test/ui_controls_factory_aura.h"
 #include "ui/base/test/ui_controls_aura.h"
-#if defined(USE_OZONE) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#if defined(USE_OZONE) && (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 #include "ui/base/ui_base_features.h"
 #include "ui/ozone/public/ozone_platform.h"
 #include "ui/views/test/ui_controls_factory_desktop_aura_ozone.h"
@@ -26,7 +27,7 @@
 #endif
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/test/ui_controls_factory_ash.h"
 #endif
 
@@ -48,20 +49,20 @@
 
     ChromeTestSuite::Initialize();
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     ui_controls::InstallUIControlsAura(ash::test::CreateAshUIControls());
 #elif defined(OS_WIN)
     com_initializer_.reset(new base::win::ScopedCOMInitializer());
     ui_controls::InstallUIControlsAura(
         aura::test::CreateUIControlsAura(nullptr));
-#elif defined(OS_LINUX)
+#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 #if defined(USE_OZONE)
     if (features::IsUsingOzonePlatform()) {
       ui::OzonePlatform::InitParams params;
       params.single_process = true;
       ui::OzonePlatform::InitializeForUI(params);
 
-#if !BUILDFLAG(IS_LACROS)
+#if !BUILDFLAG(IS_CHROMEOS_LACROS)
       // TODO(1134495): when ozone/wayland implements ui controls test helper,
       // make lacros also use the ui controls created below.
       //
@@ -154,7 +155,7 @@
 int main(int argc, char** argv) {
   base::CommandLine::Init(argc, argv);
 
-#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+#if BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
   // Force software-gl. This is necessary for mus tests to avoid an msan warning
   // in gl init.
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
diff --git a/chrome/test/base/javascript_browser_test.cc b/chrome/test/base/javascript_browser_test.cc
index 233d925e..06f1f8b 100644
--- a/chrome/test/base/javascript_browser_test.cc
+++ b/chrome/test/base/javascript_browser_test.cc
@@ -8,6 +8,7 @@
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/js_test_api.h"
 #include "components/nacl/common/buildflags.h"
@@ -38,7 +39,7 @@
 // js2gtest GN template.
 #if (!defined(MEMORY_SANITIZER) && !defined(ADDRESS_SANITIZER) && \
      !defined(LEAK_SANITIZER)) ||                                 \
-    BUILDFLAG(ENABLE_NACL) || defined(OS_CHROMEOS)
+    BUILDFLAG(ENABLE_NACL) || BUILDFLAG(IS_CHROMEOS_ASH)
   base::FilePath gen_test_data_directory;
   ASSERT_TRUE(base::PathService::Get(chrome::DIR_GEN_TEST_DATA,
                                      &gen_test_data_directory));
diff --git a/chrome/test/base/perf/performance_test.cc b/chrome/test/base/perf/performance_test.cc
index e22a695..bece169e 100644
--- a/chrome/test/base/perf/performance_test.cc
+++ b/chrome/test/base/perf/performance_test.cc
@@ -9,6 +9,7 @@
 #include "base/metrics/histogram_samples.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/trace_event/trace_event.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/base/test_switches.h"
 #include "content/public/browser/tracing_controller.h"
 #include "services/tracing/public/cpp/trace_event_agent.h"
@@ -16,7 +17,7 @@
 #include "ui/compositor/compositor_switches.h"
 #include "ui/gl/gl_switches.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/public/cpp/wallpaper_types.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
@@ -24,13 +25,13 @@
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 #include "ui/gfx/image/image_skia.h"
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 namespace {
 
 constexpr char kTraceDir[] = "trace-dir";
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Watches if the wallpaper has been changed and runs a passed callback if so.
 class TestWallpaperObserver : public ash::WallpaperControllerObserver {
  public:
@@ -72,7 +73,7 @@
       image, /*preview_mode=*/false);
   run_loop.Run();
 }
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 perf_test::LuciTestResult CreateTestResult(
     const base::FilePath& trace_file,
@@ -191,9 +192,9 @@
 
 void UIPerformanceTest::SetUpOnMainThread() {
   PerformanceTest::SetUpOnMainThread();
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   CreateAndSetWallpaper();
-#endif  // OS_CHROMEOS
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 const std::string UIPerformanceTest::GetTracingCategories() const {
diff --git a/chrome/test/base/test_launcher_utils.cc b/chrome/test/base/test_launcher_utils.cc
index 8bbd4a9..c46c85c0 100644
--- a/chrome/test/base/test_launcher_utils.cc
+++ b/chrome/test/base/test_launcher_utils.cc
@@ -14,6 +14,7 @@
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
@@ -54,7 +55,7 @@
       wm::switches::kWindowAnimationsDisabled);
 #endif
 
-#if defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_CHROMEOS)
+#if defined(OS_POSIX) && !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_ASH)
   // Don't use the native password stores on Linux since they may
   // prompt for additional UI during tests and cause test failures or
   // timeouts.  Win, Mac and ChromeOS don't look at the kPasswordStore
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index 725b3a9..40a22ed 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -10,6 +10,7 @@
 #include "base/time/default_clock.h"
 #include "base/time/default_tick_clock.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_impl.h"
 #include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
@@ -65,7 +66,7 @@
 #include "components/keep_alive_registry/keep_alive_registry.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #endif
 
@@ -227,13 +228,13 @@
         chrome::DIR_POLICY_FILES, local_policy_path, true, false));
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     browser_policy_connector_ =
         std::make_unique<policy::BrowserPolicyConnectorChromeOS>();
 #else
     browser_policy_connector_ =
         std::make_unique<policy::ChromeBrowserPolicyConnector>();
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
     // Note: creating the ChromeBrowserPolicyConnector invokes BrowserThread::
     // GetTaskRunnerForThread(), which initializes a base::LazyInstance of
@@ -300,7 +301,7 @@
 }
 
 NotificationUIManager* TestingBrowserProcess::notification_ui_manager() {
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
   if (!notification_ui_manager_.get())
     notification_ui_manager_ = NotificationUIManager::Create();
   return notification_ui_manager_.get();
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h
index 9ba8ce3..1d7aee67 100644
--- a/chrome/test/base/testing_browser_process.h
+++ b/chrome/test/base/testing_browser_process.h
@@ -17,6 +17,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/test/base/testing_browser_process_platform_part.h"
@@ -125,7 +126,9 @@
   DownloadRequestLimiter* download_request_limiter() override;
   StartupData* startup_data() override;
 
-#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if defined(OS_WIN) || defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   void StartAutoupdateTimer() override {}
 #endif
 
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index cfa4873..455f6d31 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -22,6 +22,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/autocomplete/in_memory_url_index_factory.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/background_fetch/background_fetch_delegate_factory.h"
@@ -127,7 +128,7 @@
 #include "extensions/browser/extension_system.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/arc/session/arc_service_launcher.h"
 #include "chrome/browser/chromeos/net/delay_network_call.h"
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
@@ -178,7 +179,7 @@
 }  // namespace
 
 // static
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Must be kept in sync with
 // ChromeBrowserMainPartsChromeos::PreEarlyInitialization.
 const char TestingProfile::kTestUserProfileDir[] = "test-user";
@@ -191,8 +192,10 @@
     base::test::ScopedFeatureList& scoped_feature_list,
     bool enabled) {
 // This feature is now only supported on Windows, Linux, and Mac.
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
 #if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
   if (enabled)
     scoped_feature_list.InitAndEnableFeature(
         features::kEnableEphemeralGuestProfilesOnDesktop);
@@ -202,8 +205,8 @@
   return true;
 #else
   return false;
-#endif  // defined(OS_WIN) || defined(OS_MAC) || (defined(OS_LINUX) &&
-        // !defined(OS_CHROMEOS))
+#endif  // defined(OS_WIN) || defined(OS_MAC) || (defined(OS_LINUX) ||
+        // BUILDFLAG(IS_CHROMEOS_LACROS))
 }
 
 TestingProfile::TestingProfile() : TestingProfile(base::FilePath()) {}
@@ -252,11 +255,11 @@
     bool allows_browser_windows,
     base::Optional<bool> is_new_profile,
     const std::string& supervised_user_id,
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     std::unique_ptr<policy::UserCloudPolicyManagerChromeOS> policy_manager,
 #else
     std::unique_ptr<policy::UserCloudPolicyManager> policy_manager,
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
     std::unique_ptr<policy::PolicyService> policy_service,
     TestingFactories testing_factories,
     const std::string& profile_name,
@@ -390,7 +393,7 @@
   if (!base::PathExists(profile_path_))
     base::CreateDirectory(profile_path_);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Initialize |chromeos::AccountManager|.
   chromeos::AccountManagerFactory* factory =
       g_browser_process->platform_part()->GetAccountManagerFactory();
@@ -866,7 +869,7 @@
   return schema_registry_service_.get();
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 policy::UserCloudPolicyManagerChromeOS*
 TestingProfile::GetUserCloudPolicyManagerChromeOS() {
   return user_cloud_policy_manager_.get();
@@ -880,7 +883,7 @@
 policy::UserCloudPolicyManager* TestingProfile::GetUserCloudPolicyManager() {
   return user_cloud_policy_manager_.get();
 }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 policy::ProfilePolicyConnector* TestingProfile::GetProfilePolicyConnector() {
   return profile_policy_connector_.get();
@@ -899,7 +902,7 @@
   last_selected_directory_ = path;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void TestingProfile::ChangeAppLocale(const std::string& locale,
                                      AppLocaleChangedVia via) {
   requested_locale_ = locale;
@@ -1054,7 +1057,7 @@
   supervised_user_id_ = supervised_user_id;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void TestingProfile::Builder::SetUserCloudPolicyManagerChromeOS(
     std::unique_ptr<policy::UserCloudPolicyManagerChromeOS>
         user_cloud_policy_manager) {
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index ad5c0b0..1b4ca2d 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -16,6 +16,7 @@
 #include "base/optional.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/buildflags.h"
 #include "components/domain_reliability/clear_mode.h"
@@ -29,7 +30,7 @@
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "services/service_manager/public/mojom/service.mojom.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #endif
 
@@ -55,11 +56,11 @@
 class PolicyService;
 class ProfilePolicyConnector;
 class SchemaRegistryService;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 class UserCloudPolicyManagerChromeOS;
 #else
 class UserCloudPolicyManager;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }  // namespace policy
 
 namespace storage {
@@ -153,7 +154,7 @@
     // a non-empty string, the profile is supervised.
     void SetSupervisedUserId(const std::string& supervised_user_id);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     void SetUserCloudPolicyManagerChromeOS(
         std::unique_ptr<policy::UserCloudPolicyManagerChromeOS>
             user_cloud_policy_manager);
@@ -161,7 +162,7 @@
     void SetUserCloudPolicyManager(
         std::unique_ptr<policy::UserCloudPolicyManager>
             user_cloud_policy_manager);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
     // Sets the PolicyService to be used by this profile.
     void SetPolicyService(
@@ -198,7 +199,7 @@
     bool allows_browser_windows_;
     base::Optional<bool> is_new_profile_;
     std::string supervised_user_id_;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     std::unique_ptr<policy::UserCloudPolicyManagerChromeOS>
         user_cloud_policy_manager_;
 #else
@@ -237,11 +238,11 @@
       bool allows_browser_windows,
       base::Optional<bool> is_new_profile,
       const std::string& supervised_user_id,
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
       std::unique_ptr<policy::UserCloudPolicyManagerChromeOS> policy_manager,
 #else
       std::unique_ptr<policy::UserCloudPolicyManager> policy_manager,
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
       std::unique_ptr<policy::PolicyService> policy_service,
       TestingFactories testing_factories,
       const std::string& profile_name,
@@ -352,14 +353,14 @@
   base::Time GetStartTime() const override;
   ProfileKey* GetProfileKey() const override;
   policy::SchemaRegistryService* GetPolicySchemaRegistryService() override;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   policy::UserCloudPolicyManagerChromeOS* GetUserCloudPolicyManagerChromeOS()
       override;
   policy::ActiveDirectoryPolicyManager* GetActiveDirectoryPolicyManager()
       override;
 #else
   policy::UserCloudPolicyManager* GetUserCloudPolicyManager() override;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   policy::ProfilePolicyConnector* GetProfilePolicyConnector() override;
   const policy::ProfilePolicyConnector* GetProfilePolicyConnector()
       const override;
@@ -372,14 +373,14 @@
   void SetExitType(ExitType exit_type) override {}
   ExitType GetLastSessionExitType() const override;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void ChangeAppLocale(const std::string&, AppLocaleChangedVia) override;
   void OnLogin() override {}
   void InitChromeOSPreferences() override {}
   chromeos::ScopedCrosSettingsTestHelper* ScopedCrosSettingsTestHelper();
 
   base::Optional<std::string> requested_locale() { return requested_locale_; }
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   // Schedules a task on the history backend and runs a nested loop until the
   // task is processed.  This has the effect of blocking the caller until the
@@ -484,12 +485,12 @@
   content::MockResourceContext* resource_context_;
 
   std::unique_ptr<policy::SchemaRegistryService> schema_registry_service_;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<policy::UserCloudPolicyManagerChromeOS>
       user_cloud_policy_manager_;
 #else
   std::unique_ptr<policy::UserCloudPolicyManager> user_cloud_policy_manager_;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<policy::ProfilePolicyConnector> profile_policy_connector_;
 
   // Weak pointer to a delegate for indicating that a profile was created.
@@ -500,12 +501,12 @@
   base::Optional<bool> override_policy_connector_is_managed_;
   base::Optional<OTRProfileID> otr_profile_id_;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<chromeos::ScopedCrosSettingsTestHelper>
       scoped_cros_settings_test_helper_;
 
   base::Optional<std::string> requested_locale_;
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   std::unique_ptr<policy::PolicyService> policy_service_;
 
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc
index d9c185a..a320aedf 100644
--- a/chrome/test/base/testing_profile_manager.cc
+++ b/chrome/test/base/testing_profile_manager.cc
@@ -12,6 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_file_util.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
@@ -22,7 +23,7 @@
 #include "components/sync_preferences/pref_service_syncable.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #endif
 
@@ -85,7 +86,7 @@
 
   // Create a path for the profile based on the name.
   base::FilePath profile_path(profiles_path_);
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (profile_name != chrome::kInitialProfile &&
       profile_name != chromeos::ProfileHelper::GetLockScreenAppProfileName()) {
     profile_path =
diff --git a/chrome/test/chromedriver/BUILD.gn b/chrome/test/chromedriver/BUILD.gn
index a5e2f91e..35f8cd16 100644
--- a/chrome/test/chromedriver/BUILD.gn
+++ b/chrome/test/chromedriver/BUILD.gn
@@ -312,6 +312,7 @@
   deps = [
     ":automation_client_lib",
     ":lib",
+    "//build:chromeos_buildflags",
     "//build/win:default_exe_manifest",
     "//mojo/core/embedder",
     "//net/server:http_server",
@@ -424,6 +425,7 @@
     ":lib",
     "//base",
     "//base/test:run_all_unittests",
+    "//build:chromeos_buildflags",
     "//chrome/common",
     "//mojo/core/embedder",
     "//net",
diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc
index 8ab7987..1eded78 100644
--- a/chrome/test/chromedriver/chrome_launcher.cc
+++ b/chrome/test/chromedriver/chrome_launcher.cc
@@ -1189,7 +1189,7 @@
     case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
       return "exited abnormally";
     case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
-#if defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
     case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
 #endif
     case base::TERMINATION_STATUS_OOM:
diff --git a/chrome/test/chromedriver/keycode_text_conversion_unittest.cc b/chrome/test/chromedriver/keycode_text_conversion_unittest.cc
index 1020e25..6507f8d 100644
--- a/chrome/test/chromedriver/keycode_text_conversion_unittest.cc
+++ b/chrome/test/chromedriver/keycode_text_conversion_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/chromedriver/chrome/ui_events.h"
 #include "chrome/test/chromedriver/keycode_text_conversion.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -61,7 +62,9 @@
 
 }  // namespace
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 // Fails on bots: crbug.com/174962
 #define MAYBE_KeyCodeToText DISABLED_KeyCodeToText
 #else
@@ -96,7 +99,9 @@
       ConvertKeyCodeToTextNoError(ui::VKEY_SHIFT, kShiftKeyModifierMask));
 }
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 // Fails on bots: crbug.com/174962
 #define MAYBE_CharToKeyCode DISABLED_CharToKeyCode
 #else
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc
index 2756444a..61d624a 100644
--- a/chrome/test/chromedriver/server/chromedriver_server.cc
+++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -36,6 +36,7 @@
 #include "base/threading/thread_local.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/chromedriver/constants/version.h"
 #include "chrome/test/chromedriver/logging.h"
 #include "chrome/test/chromedriver/server/http_handler.h"
@@ -48,7 +49,9 @@
 
 namespace {
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 // Ensure that there is a writable shared memory directory. We use
 // network::SimpleURLLoader to connect to Chrome, and it calls
 // base::subtle::PlatformSharedMemoryRegion::Create to get a shared memory
@@ -300,36 +303,38 @@
   if (cmd_line->HasSwitch("h") || cmd_line->HasSwitch("help")) {
     std::string options;
     const char* const kOptionAndDescriptions[] = {
-        "port=PORT",
-            "port to listen on",
-        "adb-port=PORT",
-            "adb server port",
-        "log-path=FILE",
-            "write server log to file instead of stderr, "
-            "increases log level to INFO",
-        "log-level=LEVEL",
-            "set log level: ALL, DEBUG, INFO, WARNING, SEVERE, OFF",
-        "verbose",
-            "log verbosely (equivalent to --log-level=ALL)",
-        "silent",
-            "log nothing (equivalent to --log-level=OFF)",
-        "append-log",
-            "append log file instead of rewriting",
-        "replayable",
-            "(experimental) log verbosely and don't truncate long "
-            "strings so that the log can be replayed.",
-        "version",
-            "print the version number and exit",
-        "url-base",
-            "base URL path prefix for commands, e.g. wd/url",
-        "readable-timestamp",
-            "add readable timestamps to log",
-        "enable-chrome-logs",
-            "show logs from the browser (overrides other logging options)",
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
-        "disable-dev-shm-usage",
-            "do not use /dev/shm "
-            "(add this switch if seeing errors related to shared memory)",
+      "port=PORT",
+      "port to listen on",
+      "adb-port=PORT",
+      "adb server port",
+      "log-path=FILE",
+      "write server log to file instead of stderr, "
+      "increases log level to INFO",
+      "log-level=LEVEL",
+      "set log level: ALL, DEBUG, INFO, WARNING, SEVERE, OFF",
+      "verbose",
+      "log verbosely (equivalent to --log-level=ALL)",
+      "silent",
+      "log nothing (equivalent to --log-level=OFF)",
+      "append-log",
+      "append log file instead of rewriting",
+      "replayable",
+      "(experimental) log verbosely and don't truncate long "
+      "strings so that the log can be replayed.",
+      "version",
+      "print the version number and exit",
+      "url-base",
+      "base URL path prefix for commands, e.g. wd/url",
+      "readable-timestamp",
+      "add readable timestamps to log",
+      "enable-chrome-logs",
+      "show logs from the browser (overrides other logging options)",
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+      "disable-dev-shm-usage",
+      "do not use /dev/shm "
+      "(add this switch if seeing errors related to shared memory)",
 #endif
     };
     for (size_t i = 0; i < base::size(kOptionAndDescriptions) - 1; i += 2) {
@@ -436,7 +441,9 @@
     return 1;
   }
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   EnsureSharedMemory(cmd_line);
 #endif
 
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index ce6306f..c722203 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/crypto.gni")
 import("//chrome/common/features.gni")
 import("//chrome/test/base/js2gtest.gni")
@@ -108,7 +109,7 @@
       "//third_party/axe-core/axe.js",
     ]
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       gen_include_files += [
         "settings/chromeos/a11y/os_settings_accessibility_test.js",
         "settings/chromeos/a11y/crostini_accessibility_test.js",
@@ -122,11 +123,11 @@
       "//chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js",
     ]
 
-    if (is_chromeos || is_win) {
+    if (is_chromeos_ash || is_win) {
       sources += [ "inline_login/inline_login_browsertest.js" ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "../../../browser/resources/chromeos/login/components/oobe_types.js",
         "../../../browser/resources/chromeos/login/security_token_pin_browsertest.js",
@@ -257,7 +258,7 @@
       ]
     }
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       data += [
         "$root_gen_dir/chrome/test/data/webui/chromeos/fake_network_config_mojom.m.js",
         "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.m.js",
@@ -385,7 +386,7 @@
 
     deps = [ "//chrome/browser/ui" ]
 
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [
         "chromeos/crostini_installer_browsertest.js",
         "chromeos/crostini_upgrader_browsertest.js",
@@ -456,7 +457,7 @@
       "../../../renderer/resources/extensions/notifications_test_util.js",
       "//ui/webui/resources/js/cr.js",
     ]
-    if (is_chromeos) {
+    if (is_chromeos_ash) {
       sources += [ "../../../browser/resources/chromeos/machine_learning/machine_learning_internals_utils_unittest.js" ]
       extra_js_files += [ "../../../browser/resources/chromeos/machine_learning/machine_learning_internals_utils.js" ]
     }
@@ -474,7 +475,7 @@
     "./settings:modulize",
   ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     deps += [ "./nearby_share/shared:modulize" ]
   }
 }
@@ -510,7 +511,7 @@
 
     # TODO(crbug.com/1000989): Add page specific targets here.
   ]
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     deps += [
       "chromeos:closure_compile",
       "nearby_share:closure_compile",
diff --git a/chrome/test/data/webui/chromeos/BUILD.gn b/chrome/test/data/webui/chromeos/BUILD.gn
index 555c02e..c5d19542 100644
--- a/chrome/test/data/webui/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chromeos/ui_mode.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//ui/webui/resources/tools/js_modulizer.gni")
 
@@ -11,7 +12,7 @@
 
 js_library("fake_network_config_mojom.m") {
   sources = []
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [ "$root_gen_dir/chrome/test/data/webui/chromeos/fake_network_config_mojom.m.js" ]
   }
   extra_deps = [ ":modulize" ]
@@ -20,7 +21,7 @@
 group("closure_compile") {
   public_deps = []
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     public_deps += [
       "account_manager:closure_compile",
       "diagnostics:closure_compile",
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn
index 3354457..be53baa 100644
--- a/chrome/test/data/webui/cr_elements/BUILD.gn
+++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chromeos/ui_mode.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//ui/webui/resources/tools/js_modulizer.gni")
 import("../namespace_rewrites.gni")
@@ -44,7 +45,7 @@
   ]
   namespace_rewrites = test_namespace_rewrites + [ "Polymer.Base|Base" ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     input_files += [ "cr_searchable_drop_down_tests.js" ]
   }
 }
@@ -90,7 +91,7 @@
     ":iron_list_focus_test.m",
   ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     deps += [ ":cr_searchable_drop_down_tests.m" ]
   }
 }
@@ -528,7 +529,7 @@
   extra_deps = [ ":modulize" ]
 }
 
-if (is_chromeos) {
+if (is_chromeos_ash) {
   js_library("cr_searchable_drop_down_tests.m") {
     sources = [ "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.m.js" ]
     deps = [
diff --git a/chrome/test/data/webui/print_preview/BUILD.gn b/chrome/test/data/webui/print_preview/BUILD.gn
index ee13a72..34313e36 100644
--- a/chrome/test/data/webui/print_preview/BUILD.gn
+++ b/chrome/test/data/webui/print_preview/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chromeos/ui_mode.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/preprocess_grit.gni")
 
@@ -86,7 +87,7 @@
     #":user_manager_test",
   ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     deps += [
       ":destination_dialog_cros_interactive_test",
       ":destination_dialog_cros_test",
@@ -224,7 +225,7 @@
   externs_list = [ "$externs_path/mocha-2.5.js" ]
 }
 
-if (is_chromeos) {
+if (is_chromeos_ash) {
   js_library("destination_dialog_cros_test") {
     deps = [
       ":cloud_print_interface_stub",
@@ -252,7 +253,7 @@
   }
 }
 
-if (is_chromeos) {
+if (is_chromeos_ash) {
   js_library("destination_dialog_cros_interactive_test") {
     deps = [
       ":cloud_print_interface_stub",
@@ -301,7 +302,7 @@
   externs_list = [ "$externs_path/mocha-2.5.js" ]
 }
 
-if (is_chromeos) {
+if (is_chromeos_ash) {
   js_library("native_layer_cros_stub") {
     deps = [
       "..:test_browser_proxy.m",
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn
index f4efd1a..2905606 100644
--- a/chrome/test/data/webui/settings/BUILD.gn
+++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chromeos/ui_mode.gni")
 import("//chrome/browser/resources/settings/settings.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 import("//ui/webui/resources/tools/js_modulizer.gni")
@@ -10,7 +11,7 @@
 group("modulize") {
   public_deps = [ ":modulize_local" ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     deps = [ "./chromeos:modulize" ]
   }
 }
diff --git a/chrome/test/data/webui/settings/people_page_manage_profile_test.js b/chrome/test/data/webui/settings/people_page_manage_profile_test.js
index a5060e50..0bce4ea 100644
--- a/chrome/test/data/webui/settings/people_page_manage_profile_test.js
+++ b/chrome/test/data/webui/settings/people_page_manage_profile_test.js
@@ -80,7 +80,7 @@
   setup(function() {
     browserProxy = new TestManageProfileBrowserProxy();
     ManageProfileBrowserProxyImpl.instance_ = browserProxy;
-    setFlags({profilesUIRevamp: false, profileShortcutsEnabled: false});
+    setFlags({newProfilePicker: false, profileShortcutsEnabled: false});
     Router.getInstance().navigateTo(routes.MANAGE_PROFILE);
   });
 
@@ -137,7 +137,7 @@
     }
     await changeIcon();
     browserProxy.reset();
-    setFlags({profilesUIRevamp: true});
+    setFlags({newProfilePicker: true});
     await changeIcon();
   });
 
@@ -158,7 +158,7 @@
     }
     await changeName();
     browserProxy.resetResolver('setProfileName');
-    setFlags({profilesUIRevamp: true});
+    setFlags({newProfilePicker: true});
     await changeName();
   });
 
@@ -173,7 +173,7 @@
       assertTrue(!!nameField.disabled);
     }
     profileNameDisabledForSupervisedUser();
-    setFlags({profilesUIRevamp: true});
+    setFlags({newProfilePicker: true});
     profileNameDisabledForSupervisedUser();
   });
 
@@ -192,7 +192,7 @@
     }
     await profileNameUpdated();
     browserProxy.resetResolver('getAvailableIcons');
-    setFlags({profilesUIRevamp: true});
+    setFlags({newProfilePicker: true});
     await profileNameUpdated();
   });
 
@@ -210,7 +210,7 @@
     assertFalse(!!manageProfile.$$('#themeSelector'));
 
     // Recreate a manage profile element with overridden loadTimeData.
-    setFlags({profilesUIRevamp: true});
+    setFlags({newProfilePicker: true});
 
     assertTrue(!!manageProfile.$$('#themeSelector'));
   });
@@ -243,10 +243,10 @@
       hasShortcutToggle.click();
       return browserProxy.whenCalled('addProfileShortcut');
     }
-    setFlags({profilesUIRevamp: false, profileShortcutsEnabled: true});
+    setFlags({newProfilePicker: false, profileShortcutsEnabled: true});
     await profileShortcutToggle();
     browserProxy.reset();
-    setFlags({profilesUIRevamp: true, profileShortcutsEnabled: true});
+    setFlags({newProfilePicker: true, profileShortcutsEnabled: true});
     await profileShortcutToggle();
   });
 
@@ -267,10 +267,10 @@
 
       assertFalse(hasShortcutToggle.checked);
     }
-    setFlags({profilesUIRevamp: false, profileShortcutsEnabled: true});
+    setFlags({newProfilePicker: false, profileShortcutsEnabled: true});
     await profileShortcutToggleShortcutNotFound();
     browserProxy.resetResolver('getProfileShortcutStatus');
-    setFlags({profilesUIRevamp: true, profileShortcutsEnabled: true});
+    setFlags({newProfilePicker: true, profileShortcutsEnabled: true});
     await profileShortcutToggleShortcutNotFound();
   });
 
@@ -289,10 +289,10 @@
 
       assertFalse(!!manageProfile.$$('#hasShortcutToggle'));
     }
-    setFlags({profilesUIRevamp: false, profileShortcutsEnabled: true});
+    setFlags({newProfilePicker: false, profileShortcutsEnabled: true});
     await profileShortcutSettingHidden();
     browserProxy.resetResolver('getProfileShortcutStatus');
-    setFlags({profilesUIRevamp: true, profileShortcutsEnabled: true});
+    setFlags({newProfilePicker: true, profileShortcutsEnabled: true});
     await profileShortcutSettingHidden();
   });
 });
diff --git a/chrome/test/data/webui/settings/safety_check_page_test.js b/chrome/test/data/webui/settings/safety_check_page_test.js
index 0914133..9746a906 100644
--- a/chrome/test/data/webui/settings/safety_check_page_test.js
+++ b/chrome/test/data/webui/settings/safety_check_page_test.js
@@ -639,6 +639,7 @@
           break;
         case SafetyCheckPasswordsStatus.QUOTA_LIMIT:
         case SafetyCheckPasswordsStatus.ERROR:
+        case SafetyCheckPasswordsStatus.WEAK_PASSWORDS_EXIST:
           assertSafetyCheckChild({
             page: page,
             iconStatus: SafetyCheckIconStatus.INFO,
diff --git a/chrome/test/data/webui/signin/signin_browsertest.js b/chrome/test/data/webui/signin/signin_browsertest.js
index 30eb7aed..512b6f0 100644
--- a/chrome/test/data/webui/signin/signin_browsertest.js
+++ b/chrome/test/data/webui/signin/signin_browsertest.js
@@ -171,15 +171,6 @@
   get browsePreload() {
     return 'chrome://profile-customization/test_loader.html?module=signin/profile_customization_test.js';
   }
-
-  /** @override */
-  get featureList() {
-    return {
-      enabled: [
-        'features::kProfilesUIRevamp',
-      ]
-    };
-  }
 };
 
 TEST_F('ProfileCustomizationTest', 'Bubble', function() {
diff --git a/chrome/test/data/webui/tab_search/tab_search_browsertest.js b/chrome/test/data/webui/tab_search/tab_search_browsertest.js
index e0298ee..0ba3a0b 100644
--- a/chrome/test/data/webui/tab_search/tab_search_browsertest.js
+++ b/chrome/test/data/webui/tab_search/tab_search_browsertest.js
@@ -40,7 +40,14 @@
   }
 };
 
-TEST_F('TabSearchAppTest', 'All', function() {
+// Disabled on Windows because of random crash on Win 7 Tests x64 (1).
+// See: https://crbug.com/1152287
+GEN('#if defined(OS_WIN)');
+GEN('#define MAYBE_All DISABLED_All');
+GEN('#else');
+GEN('#define MAYBE_All All');
+GEN('#endif');
+TEST_F('TabSearchAppTest', 'MAYBE_All', function() {
   mocha.run();
 });
 
diff --git a/chrome/test/data/webui/webui_resource_browsertest.cc b/chrome/test/data/webui/webui_resource_browsertest.cc
index e03a10b..f1ab04c 100644
--- a/chrome/test/data/webui/webui_resource_browsertest.cc
+++ b/chrome/test/data/webui/webui_resource_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -51,7 +52,7 @@
   LoadTestUrl("js/cr/ui/array_data_model_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, ArrayDataModelModuleTest) {
   LoadTestUrl("?module=js/cr/ui/array_data_model_test.m.js");
 }
@@ -131,7 +132,7 @@
   LoadTestUrl("js/cr/ui/list_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, ListModuleTest) {
   LoadTestUrl("?module=js/cr/ui/list_test.m.js");
 }
@@ -149,7 +150,7 @@
   LoadTestUrl("js/cr/ui/list_selection_model_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, ListSelectionModeModulelTest) {
   LoadTestUrl("?module=js/cr/ui/list_selection_model_test.m.js");
 }
@@ -159,7 +160,7 @@
   LoadTestUrl("js/cr/ui/list_single_selection_model_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest,
                        ListSingleSelectionModelModuleTest) {
   LoadTestUrl("?module=js/cr/ui/list_single_selection_model_test.m.js");
@@ -170,7 +171,7 @@
   LoadTestUrl("js/cr/ui/menu_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, MenuModuleTest) {
   LoadTestUrl("?module=js/cr/ui/menu_test.m.js");
 }
@@ -188,7 +189,7 @@
   LoadTestUrl("js/cr/ui/position_util_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, PositionUtilModuleTest) {
   LoadTestUrl("?module=js/cr/ui/position_util_test.m.js");
 }
@@ -198,7 +199,7 @@
   LoadTestUrl("js/cr/ui/command_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, CommandModuleTest) {
   LoadTestUrl("?module=js/cr/ui/command_test.m.js");
 }
@@ -208,7 +209,7 @@
   LoadTestUrl("js/cr/ui/context_menu_handler_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, ContextMenuHandlerModuleTest) {
   LoadTestUrl("?module=js/cr/ui/context_menu_handler_test.m.js");
 }
@@ -218,7 +219,7 @@
   LoadTestUrl("js/cr/ui/menu_button_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, MenuButtonModuleTest) {
   LoadTestUrl("?module=js/cr/ui/menu_button_test.m.js");
 }
@@ -228,7 +229,7 @@
   LoadTestUrl("js/cr/ui/splitter_test.html");
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, SplitterModuleTest) {
   LoadTestUrl("?module=js/cr/ui/splitter_test.m.js");
 }
diff --git a/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc b/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc
index a267e972..d50593d 100644
--- a/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc
+++ b/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/test/media_router/media_router_integration_browsertest.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_utils.h"
@@ -44,7 +45,7 @@
 };
 
 // TODO(https://crbug.com/822231): Flaky in Chromium waterfall.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_Basic DISABLED_Basic
 #else
 #define MAYBE_Basic Basic
@@ -68,7 +69,7 @@
 }
 
 // TODO(https://crbug.com/822231): Flaky in Chromium waterfall.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_Fail_SendMessage DISABLED_Fail_SendMessage
 #else
 #define MAYBE_Fail_SendMessage Fail_SendMessage
@@ -97,7 +98,7 @@
 #undef MAYBE_ReconnectSession
 
 // TODO(https://crbug.com/822231): Flaky in Chromium waterfall.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_ReconnectSessionSameTab DISABLED_ReconnectSessionSameTab
 #else
 #define MAYBE_ReconnectSessionSameTab ReconnectSessionSameTab
@@ -118,7 +119,7 @@
 };
 
 // TODO(https://crbug.com/822231): Flaky in Chromium waterfall.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_Basic DISABLED_Basic
 #else
 #define MAYBE_Basic Basic
@@ -130,7 +131,7 @@
 #undef MAYBE_Basic
 
 // TODO(https://crbug.com/822231): Flaky in Chromium waterfall.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_Fail_SendMessage DISABLED_Fail_SendMessage
 #else
 #define MAYBE_Fail_SendMessage Fail_SendMessage
@@ -142,7 +143,7 @@
 #undef MAYBE_Fail_SendMessage
 
 // TODO(https://crbug.com/822231): Flaky in Chromium waterfall.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_ReconnectSession DISABLED_ReconnectSession
 #else
 #define MAYBE_ReconnectSession ReconnectSession
@@ -153,7 +154,7 @@
 }
 
 // TODO(https://crbug.com/822231): Flaky in Chromium waterfall.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_ReconnectSessionSameTab DISABLED_ReconnectSessionSameTab
 #else
 #define MAYBE_ReconnectSessionSameTab ReconnectSessionSameTab
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index 61f5bec..2cd6fed 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/test/test_timeouts.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
@@ -2121,7 +2122,7 @@
 TEST_PPAPI_NACL(NetworkProxy)
 
 // TODO(crbug.com/602875), TODO(crbug.com/602876) Flaky on Win and CrOS.
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_WIN)
 #define MAYBE_VideoDecoder DISABLED_VideoDecoder
 #else
 #define MAYBE_VideoDecoder VideoDecoder
diff --git a/chrome/test/views/chrome_views_test_base.cc b/chrome/test/views/chrome_views_test_base.cc
index 4e02c5b..1cb1d4a 100644
--- a/chrome/test/views/chrome_views_test_base.cc
+++ b/chrome/test/views/chrome_views_test_base.cc
@@ -6,18 +6,19 @@
 
 #include <memory>
 
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/test/views/chrome_test_widget.h"
 #include "content/public/test/browser_task_environment.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/test/ash_test_helper.h"
 #include "ui/views/test/views_test_helper_aura.h"
 #endif
 
 namespace {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 std::unique_ptr<aura::test::AuraTestHelper> MakeTestHelper() {
   return std::make_unique<ash::AshTestHelper>();
 }
@@ -34,7 +35,7 @@
 ChromeViewsTestBase::~ChromeViewsTestBase() = default;
 
 void ChromeViewsTestBase::SetUp() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   views::ViewsTestHelperAura::SetAuraTestHelperFactory(&MakeTestHelper);
 #endif
 
@@ -48,7 +49,7 @@
       ChromeLayoutProvider::CreateLayoutProvider());
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void ChromeViewsTestBase::TearDown() {
   views::ViewsTestHelperAura::SetAuraTestHelperFactory(nullptr);
 
diff --git a/chrome/test/views/chrome_views_test_base.h b/chrome/test/views/chrome_views_test_base.h
index 059acaa..944d84e 100644
--- a/chrome/test/views/chrome_views_test_base.h
+++ b/chrome/test/views/chrome_views_test_base.h
@@ -6,6 +6,7 @@
 #define CHROME_TEST_VIEWS_CHROME_VIEWS_TEST_BASE_H_
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "ui/views/test/views_test_base.h"
 
 // A base class for Chrome views unit tests. Changes the dependencies when they
@@ -19,7 +20,7 @@
 
   // views::ViewsTestBase:
   void SetUp() override;
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void TearDown() override;
 #endif
   std::unique_ptr<views::Widget> AllocateTestWidget() override;
diff --git a/chromeos/components/camera_app_ui/resources/views/main.html b/chromeos/components/camera_app_ui/resources/views/main.html
index e0d6dcb..aa7a0f9 100644
--- a/chromeos/components/camera_app_ui/resources/views/main.html
+++ b/chromeos/components/camera_app_ui/resources/views/main.html
@@ -242,17 +242,17 @@
           <button class="icon" tabindex="0" i18n-aria="back_button"></button>
           <div i18n-content="grid_type_button"></div>
         </div>
-        <label class="menu-item circle" for="grid-3x3">
+        <label class="menu-item circle">
           <input class="icon" id="grid-3x3" type="radio" tabindex="0"
                  name="gridtype" data-state="_3x3" data-key="toggle3x3" checked>
           <span i18n-content="label_grid_3x3" i18n-aria="aria_grid_3x3"></span>
         </label>
-        <label class="menu-item circle" for="grid-4x4">
+        <label class="menu-item circle">
           <input class="icon" id="grid-4x4" type="radio" tabindex="0"
                  name="gridtype" data-state="_4x4" data-key="toggle4x4">
           <span i18n-content="label_grid_4x4" i18n-aria="aria_grid_4x4"></span>
         </label>
-        <label class="menu-item circle" for="grid-golden">
+        <label class="menu-item circle">
           <input class="icon" id="grid-golden" type="radio" tabindex="0"
                  name="gridtype" data-state="golden" data-key="toggleGolden">
           <span i18n-content="label_grid_golden"></span>
@@ -265,13 +265,13 @@
           <button class="icon" tabindex="0" i18n-aria="back_button"></button>
           <div i18n-content="timer_duration_button"></div>
         </div>
-        <label class="menu-item circle" for="timer-3s">
+        <label class="menu-item circle">
           <input class="icon" id="timer-3s" type="radio" tabindex="0"
                  name="timerdur" data-state="_3sec" data-key="toggle3sec"
                  checked>
           <span i18n-content="label_timer_3s"></span>
         </label>
-        <label class="menu-item circle" for="timer-10s">
+        <label class="menu-item circle">
           <input class="icon" id="timer-10s" type="radio" tabindex="0"
                  name="timerdur" data-state="_10sec" data-key="toggle10sec">
           <span i18n-content="label_timer_10s"></span>
@@ -357,19 +357,19 @@
           <button class="icon" tabindex="0" i18n-aria="back_button"></button>
           <div i18n-content="expert_mode_button"></div>
         </div>
-        <label class="menu-item" for="expert-show-metadata">
+        <label class="menu-item">
           <input class="icon" id="expert-show-metadata" type="checkbox"
                  tabindex="0" data-state="show-metadata"
                  data-key="showMetadata">
           <span i18n-content="expert_preview_metadata"></span>
         </label>
-        <label class="menu-item" for="expert-save-metadata">
+        <label class="menu-item">
           <input class="icon" id="expert-save-metadata" type="checkbox"
                  tabindex="0" data-state="save-metadata"
                  data-key="saveMetadata">
           <span i18n-content="expert_save_metadata"></span>
         </label>
-        <label class="menu-item" for="expert-print-performance-logs">
+        <label class="menu-item">
           <input class="icon" id="expert-print-performance-logs" type="checkbox"
                  tabindex="0" data-state="print-performance-logs"
                  data-key="printPerformanceLogs">
diff --git a/chromeos/services/ime/decoder/proto_conversion.cc b/chromeos/services/ime/decoder/proto_conversion.cc
index 1fb5896..eb2a4eb 100644
--- a/chromeos/services/ime/decoder/proto_conversion.cc
+++ b/chromeos/services/ime/decoder/proto_conversion.cc
@@ -138,5 +138,15 @@
   return message;
 }
 
+mojom::AutocorrectSpanPtr ProtoToAutocorrectSpan(
+    const chromeos::ime::AutocorrectSpan& autocorrect_span) {
+  auto mojo_autocorrect_span = mojom::AutocorrectSpan::New();
+  mojo_autocorrect_span->autocorrect_range =
+      gfx::Range(autocorrect_span.autocorrect_range().start(),
+                 autocorrect_span.autocorrect_range().end());
+  mojo_autocorrect_span->original_text = autocorrect_span.original_text();
+  return mojo_autocorrect_span;
+}
+
 }  // namespace ime
 }  // namespace chromeos
diff --git a/chromeos/services/ime/decoder/proto_conversion.h b/chromeos/services/ime/decoder/proto_conversion.h
index 9e5a9a0f..2b06a5e 100644
--- a/chromeos/services/ime/decoder/proto_conversion.h
+++ b/chromeos/services/ime/decoder/proto_conversion.h
@@ -41,6 +41,10 @@
 // a proto.
 ime::PublicMessage OnCompositionCanceledToProto(uint64_t seq_id);
 
+// Converts a proto to InputChannel::AutocorrectSpan.
+mojom::AutocorrectSpanPtr ProtoToAutocorrectSpan(
+    const chromeos::ime::AutocorrectSpan& autocorrect_span);
+
 }  // namespace ime
 }  // namespace chromeos
 
diff --git a/chromeos/services/ime/decoder/proto_conversion_unittest.cc b/chromeos/services/ime/decoder/proto_conversion_unittest.cc
index 4deefb2..825ba65 100644
--- a/chromeos/services/ime/decoder/proto_conversion_unittest.cc
+++ b/chromeos/services/ime/decoder/proto_conversion_unittest.cc
@@ -117,5 +117,16 @@
             expected_message.SerializeAsString());
 }
 
+TEST(ProtoConversionTest, ProtoToAutocorrectSpan) {
+  ime::AutocorrectSpan autocorrect_span;
+  autocorrect_span.mutable_autocorrect_range()->set_start(1);
+  autocorrect_span.mutable_autocorrect_range()->set_end(2);
+  autocorrect_span.set_original_text("hello");
+
+  mojom::AutocorrectSpanPtr result = ProtoToAutocorrectSpan(autocorrect_span);
+
+  EXPECT_EQ(result, mojom::AutocorrectSpan::New(gfx::Range(1, 2), "hello"));
+}
+
 }  // namespace ime
 }  // namespace chromeos
diff --git a/chromeos/services/ime/decoder/system_engine.cc b/chromeos/services/ime/decoder/system_engine.cc
index 299e36d..e288f8f6 100644
--- a/chromeos/services/ime/decoder/system_engine.cc
+++ b/chromeos/services/ime/decoder/system_engine.cc
@@ -249,6 +249,11 @@
       remote->CommitText(reply.commit_text().text());
       break;
     }
+    case ime::PublicMessage::kHandleAutocorrect: {
+      remote->HandleAutocorrect(ProtoToAutocorrectSpan(
+          reply.handle_autocorrect().autocorrect_span()));
+      break;
+    }
     default:
       NOTREACHED();
       break;
diff --git a/chromeos/services/ime/input_engine.cc b/chromeos/services/ime/input_engine.cc
index f8440c1f3..6e9e20d 100644
--- a/chromeos/services/ime/input_engine.cc
+++ b/chromeos/services/ime/input_engine.cc
@@ -216,5 +216,10 @@
   NOTIMPLEMENTED();  // Not used in the rulebased engine.
 }
 
+void InputEngine::HandleAutocorrect(
+    mojom::AutocorrectSpanPtr autocorrect_span) {
+  NOTIMPLEMENTED();  // Not used in the rulebased engine.
+}
+
 }  // namespace ime
 }  // namespace chromeos
diff --git a/chromeos/services/ime/input_engine.h b/chromeos/services/ime/input_engine.h
index 1368bc6..56fd0ccc 100644
--- a/chromeos/services/ime/input_engine.h
+++ b/chromeos/services/ime/input_engine.h
@@ -69,6 +69,7 @@
   void FinishComposition() override;
   void DeleteSurroundingText(uint32_t num_bytes_before_cursor,
                              uint32_t num_bytes_after_cursor) override;
+  void HandleAutocorrect(mojom::AutocorrectSpanPtr autocorrect_span) override;
 
   // TODO(https://crbug.com/837156): Implement a state for the interface.
 
diff --git a/chromeos/services/ime/mock_input_channel.h b/chromeos/services/ime/mock_input_channel.h
index 582139ad..1a6ce3c 100644
--- a/chromeos/services/ime/mock_input_channel.h
+++ b/chromeos/services/ime/mock_input_channel.h
@@ -72,6 +72,10 @@
               (uint32_t num_bytes_before_cursor,
                uint32_t num_bytes_after_cursor),
               (override));
+  MOCK_METHOD(void,
+              HandleAutocorrect,
+              (mojom::AutocorrectSpanPtr autocorrect_span),
+              (override));
 
  private:
   mojo::Receiver<mojom::InputChannel> receiver_;
diff --git a/chromeos/services/ime/public/mojom/BUILD.gn b/chromeos/services/ime/public/mojom/BUILD.gn
index 0460ad18..d4ad629 100644
--- a/chromeos/services/ime/public/mojom/BUILD.gn
+++ b/chromeos/services/ime/public/mojom/BUILD.gn
@@ -9,6 +9,7 @@
 
   public_deps = [
     "//mojo/public/mojom/base",
+    "//ui/gfx/range/mojom",
     "//url/mojom:url_mojom_gurl",
   ]
 }
diff --git a/chromeos/services/ime/public/mojom/input_engine.mojom b/chromeos/services/ime/public/mojom/input_engine.mojom
index 96082cc..13fa13d 100644
--- a/chromeos/services/ime/public/mojom/input_engine.mojom
+++ b/chromeos/services/ime/public/mojom/input_engine.mojom
@@ -6,6 +6,7 @@
 
 import "mojo/public/mojom/base/file_path.mojom";
 import "url/mojom/url.mojom";
+import "ui/gfx/range/mojom/range.mojom";
 
 // IME on ChromeOS consists of three parts:
 // - The IME running in an extension to provide a soft keyboard
@@ -134,6 +135,14 @@
   PersonalizationMode personalization;
 };
 
+struct AutocorrectSpan {
+  // The range to set the autocorrect span to.
+  gfx.mojom.Range autocorrect_range;
+
+  // The original text that was replaced by autocorrect.
+  string original_text;
+};
+
 // Manages access to a set of IME engines, implemented by the IME service
 // itself. The IME framework in the browser process is responsible for brokering
 // the connection between the IME service and the IME extension, but does not
@@ -243,6 +252,15 @@
   // TODO(b/161490915): Determine the right behaviour when there is a selection.
   DeleteSurroundingText(uint32 num_bytes_before_cursor,
                         uint32 num_bytes_after_cursor);
+
+  // Asks the input field to mark the region represented by `autocorrect_span`
+  // as having been autocorrected. This usually involves showing some UI
+  // (e.g. flashing the text or showing an underline).
+  // There can only be at most one active autocorrect span. If this method is
+  // called when there is already an active autocorrect span, any UI related to
+  // the old span is removed first.
+  // This method does not modify the input field text.
+  HandleAutocorrect(AutocorrectSpan autocorrect_span);
 };
 
 // Implemented in the browser process, used to perform network requests or
diff --git a/chromeos/services/ime/public/proto/messages.proto b/chromeos/services/ime/public/proto/messages.proto
index 03b6182d..c1dcca0 100644
--- a/chromeos/services/ime/public/proto/messages.proto
+++ b/chromeos/services/ime/public/proto/messages.proto
@@ -39,6 +39,7 @@
     SetCompositionRange set_composition_range = 11;
     FinishComposition finish_composition = 12;
     DeleteSurroundingText delete_surrounding_text = 13;
+    HandleAutocorrect handle_autocorrect = 14;
   }
 }
 
@@ -135,6 +136,20 @@
   optional uint32 focus = 2;
 }
 
+// Protobuf version of gfx.mojom.Range in
+// ui/gfx/range/mojom/range.mojom
+message Range {
+  optional uint32 start = 1;
+  optional uint32 end = 2;
+}
+
+// Protobuf version of InputEngine::AutocorrectSpan in
+// chromeos/services/ime/public/mojom/input_engine.mojom
+message AutocorrectSpan {
+  optional Range autocorrect_range = 1;
+  optional string original_text = 2;
+};
+
 // Protobuf version of InputEngine::OnSurroundingTextChanged in
 // chromeos/services/ime/public/mojom/input_engine.mojom
 message OnSurroundingTextChanged {
@@ -176,3 +191,9 @@
   optional uint32 num_bytes_before_cursor = 1;
   optional uint32 num_bytes_after_cursor = 2;
 }
+
+// Protobuf version of InputEngine::HandleAutocorrect in
+// chromeos/services/ime/public/mojom/input_engine.mojom
+message HandleAutocorrect {
+  optional AutocorrectSpan autocorrect_span = 1;
+}
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
index 26e0c5c..000ee2e6 100644
--- a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
+++ b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
@@ -16,6 +16,7 @@
 #include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/arc_features.h"
 #include "components/arc/arc_prefs.h"
+#include "components/arc/arc_util.h"
 #include "components/arc/session/arc_bridge_service.h"
 #include "components/prefs/pref_service.h"
 #include "components/user_prefs/user_prefs.h"
@@ -131,9 +132,11 @@
   // TODO(niwa): Add a new DeviceType enum value for MyFiles.
   chromeos::DeviceType device_type = chromeos::DeviceType::DEVICE_TYPE_SD;
 
+  // Conditionally set MyFiles to be visible for P and invisible for R. In R, we use IsVisibleRead
+  // so this is not needed.
   volume_mounter_instance->OnMountEvent(mojom::MountPointInfo::New(
       DiskMountManager::MOUNTING, kMyFilesPath, kMyFilesPath, kMyFilesUuid,
-      device_label, device_type, false));
+      device_label, device_type, !IsArcVmEnabled()));
 }
 
 bool ArcVolumeMounterBridge::IsVisibleToAndroidApps(
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
index 15bd5f4..cf4e3bfe 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
@@ -259,10 +259,10 @@
     }
 
     /**
-     * @return A {@link Drawable} that is the blocked version of the icon passed in. Achieved by
-     *         adding a diagonal strike through the icon.
+     * @return A {@link Drawable} that is the blocked version of the square icon passed in.
+     *         Achieved by adding a diagonal strike through the icon.
      */
-    public static Drawable getBlockedIcon(Resources resources, Drawable icon) {
+    public static Drawable getBlockedSquareIcon(Resources resources, Drawable icon) {
         if (icon == null) return null;
         // Save color filter in order to re-apply later
         ColorFilter filter = icon.getColorFilter();
@@ -271,25 +271,39 @@
         Bitmap iconBitmap = Bitmap.createBitmap(
                 icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
         Canvas canvas = new Canvas(iconBitmap);
-        int width = canvas.getWidth();
-        int height = canvas.getHeight();
-        icon.setBounds(0, 0, width, height);
+        int side = canvas.getWidth();
+        assert side == canvas.getHeight();
+        icon.setBounds(0, 0, side, side);
         icon.draw(canvas);
 
+        // Thickness of the strikethrough line in pixels, relative to the icon size.
+        float thickness = 0.08f * side;
+        // Determines the axis bounds for where the line should start and finish.
+        float padding = side * 0.15f;
+        // The scaling ratio to get the axis bias. sin(45 degrees).
+        float ratio = 0.7071f;
+        // Calculated axis shift for the line in order to only be on one side of the transparent
+        // line.
+        float bias = (thickness / 2) * ratio;
+
         // Draw diagonal transparent line
         Paint paint = new Paint();
         paint.setAntiAlias(true);
         paint.setColor(Color.TRANSPARENT);
         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
-        paint.setStrokeWidth(12);
-        canvas.drawLine(0, 0, width, height, paint);
+        // Scale by 1.5 then shift up by half of bias in order to ensure no weird gap between lines
+        // due to rounding.
+        float halfBias = 0.5f * bias;
+        paint.setStrokeWidth(1.5f * thickness);
+        canvas.drawLine(padding + halfBias, padding - halfBias, side - padding + halfBias,
+                side - padding - halfBias, paint);
 
-        // Draw a strikethrough on top
+        // Draw a strikethrough directly below.
         paint.setColor(Color.BLACK);
         paint.setXfermode(null);
-        paint.setStrokeWidth(4);
-        canvas.drawLine(
-                width * 0.1f, height * 0.1f, width - width * 0.1f, height - height * 0.1f, paint);
+        paint.setStrokeWidth(thickness);
+        canvas.drawLine(padding - bias, padding + bias, side - padding - bias,
+                side - padding + bias, paint);
 
         Drawable blocked = new BitmapDrawable(resources, iconBitmap);
         // Re-apply color filter
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
index 69327950..0cf0c1cf 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -362,7 +362,7 @@
                 : ContentSettingsResources.getDisabledIcon(contentSettingsType, getResources());
         if (getSiteSettingsClient().isPageInfoV2Enabled() && value != null
                 && value == ContentSettingValues.BLOCK) {
-            return ContentSettingsResources.getBlockedIcon(getResources(), icon);
+            return ContentSettingsResources.getBlockedSquareIcon(getResources(), icon);
         }
         return icon;
     }
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationDelegate.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationDelegate.java
index 77a97b23..62b3ff7 100644
--- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationDelegate.java
+++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationDelegate.java
@@ -11,7 +11,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
@@ -100,9 +100,9 @@
      * @param intent The intent to be handled by the embedder.
      * @param referrerUrl The referrer for the current navigation.
      * @param fallbackUrl The fallback URL to load if the intent cannot be handled by the embedder.
-     * @return The OverrideUrlLoadingResult for the action taken by the embedder.
+     * @return The OverrideUrlLoadingResultType for the action taken by the embedder.
      */
-    @OverrideUrlLoadingResult
+    @OverrideUrlLoadingResultType
     int handleIncognitoIntentTargetingSelf(Intent intent, String referrerUrl, String fallbackUrl);
 
     /**
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java
index 612bade..a89afce 100644
--- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java
+++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java
@@ -184,12 +184,12 @@
      * NOTE: this enum is used in UMA, do not reorder values. Changes should be append only.
      * Values should be numerated from 0 and can't have gaps.
      */
-    @IntDef({OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
-            OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB,
-            OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION,
-            OverrideUrlLoadingResult.NO_OVERRIDE})
+    @IntDef({OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
+            OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB,
+            OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION,
+            OverrideUrlLoadingResultType.NO_OVERRIDE})
     @Retention(RetentionPolicy.SOURCE)
-    public @interface OverrideUrlLoadingResult {
+    public @interface OverrideUrlLoadingResultType {
         /* We should override the URL loading and launch an intent. */
         int OVERRIDE_WITH_EXTERNAL_INTENT = 0;
         /* We should override the URL loading and clobber the current tab. */
@@ -217,7 +217,8 @@
      * @return Whether the URL generated an intent, caused a navigation in
      *         current tab, or wasn't handled at all.
      */
-    public @OverrideUrlLoadingResult int shouldOverrideUrlLoading(ExternalNavigationParams params) {
+    public @OverrideUrlLoadingResultType int shouldOverrideUrlLoading(
+            ExternalNavigationParams params) {
         if (DEBUG) Log.i(TAG, "shouldOverrideUrlLoading called on " + params.getUrl());
         Intent targetIntent;
         // Perform generic parsing of the URI to turn it into an Intent.
@@ -225,7 +226,7 @@
             targetIntent = Intent.parseUri(params.getUrl(), Intent.URI_INTENT_SCHEME);
         } catch (Exception ex) {
             Log.w(TAG, "Bad URI %s", params.getUrl(), ex);
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         String browserFallbackUrl =
@@ -240,14 +241,14 @@
         MutableBoolean canLaunchExternalFallbackResult = new MutableBoolean();
 
         long time = SystemClock.elapsedRealtime();
-        @OverrideUrlLoadingResult
+        @OverrideUrlLoadingResultType
         int result = shouldOverrideUrlLoadingInternal(
                 params, targetIntent, browserFallbackUrl, canLaunchExternalFallbackResult);
         assert canLaunchExternalFallbackResult.get() != null;
         RecordHistogram.recordTimesHistogram(
                 "Android.StrictMode.OverrideUrlLoadingTime", SystemClock.elapsedRealtime() - time);
 
-        if (result != OverrideUrlLoadingResult.NO_OVERRIDE) {
+        if (result != OverrideUrlLoadingResultType.NO_OVERRIDE) {
             int pageTransitionCore = params.getPageTransition() & PageTransition.CORE_MASK;
             boolean isFormSubmit = pageTransitionCore == PageTransition.FORM_SUBMIT;
             boolean isRedirectFromFormSubmit = isFormSubmit && params.isRedirect();
@@ -256,18 +257,18 @@
                         "Android.Intent.LaunchExternalAppFormSubmitHasUserGesture",
                         params.hasUserGesture());
             }
-        } else if (result == OverrideUrlLoadingResult.NO_OVERRIDE && browserFallbackUrl != null
+        } else if (result == OverrideUrlLoadingResultType.NO_OVERRIDE && browserFallbackUrl != null
                 && (params.getRedirectHandler() == null
                         // For instance, if this is a chained fallback URL, we ignore it.
                         || !params.getRedirectHandler().shouldNotOverrideUrlLoading())) {
             result = handleFallbackUrl(params, targetIntent, browserFallbackUrl,
                     canLaunchExternalFallbackResult.get());
         }
-        if (DEBUG) printDebugShouldOverrideUrlLoadingResult(result);
+        if (DEBUG) printDebugShouldOverrideUrlLoadingResultType(result);
         return result;
     }
 
-    private @OverrideUrlLoadingResult int handleFallbackUrl(ExternalNavigationParams params,
+    private @OverrideUrlLoadingResultType int handleFallbackUrl(ExternalNavigationParams params,
             Intent targetIntent, String browserFallbackUrl, boolean canLaunchExternalFallback) {
         if (mDelegate.isIntentToInstantApp(targetIntent)) {
             RecordHistogram.recordEnumeratedHistogram("Android.InstantApps.DirectInstantAppsIntent",
@@ -285,7 +286,7 @@
                 List<ResolveInfo> resolvingInfos = queryIntentActivities(intent);
                 if (!isAlreadyInTargetWebApk(resolvingInfos, params)
                         && launchWebApkIfSoleIntentHandler(resolvingInfos, intent)) {
-                    return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+                    return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
                 }
             } catch (Exception e) {
                 if (DEBUG) Log.i(TAG, "Could not parse fallback url as intent");
@@ -306,7 +307,7 @@
         // http://crbug.com/364522.
         if (!params.isMainFrame()) {
             if (DEBUG) Log.i(TAG, "Don't support fallback url in subframes");
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         // NOTE: any further redirection from fall-back URL should not override URL loading.
@@ -320,19 +321,19 @@
         return clobberCurrentTab(browserFallbackUrl, params.getReferrerUrl());
     }
 
-    private void printDebugShouldOverrideUrlLoadingResult(int result) {
+    private void printDebugShouldOverrideUrlLoadingResultType(int result) {
         String resultString;
         switch (result) {
-            case OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT:
+            case OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT:
                 resultString = "OVERRIDE_WITH_EXTERNAL_INTENT";
                 break;
-            case OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB:
+            case OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB:
                 resultString = "OVERRIDE_WITH_CLOBBERING_TAB";
                 break;
-            case OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION:
+            case OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION:
                 resultString = "OVERRIDE_WITH_ASYNC_ACTION";
                 break;
-            case OverrideUrlLoadingResult.NO_OVERRIDE: // Fall through.
+            case OverrideUrlLoadingResultType.NO_OVERRIDE: // Fall through.
             default:
                 resultString = "NO_OVERRIDE";
                 break;
@@ -466,11 +467,11 @@
      *
      * @param url The new URL after clobbering the current tab.
      * @param referrerUrl The HTTP referrer URL.
-     * @return OverrideUrlLoadingResult (if the tab has been clobbered, or we're launching an
+     * @return OverrideUrlLoadingResultType (if the tab has been clobbered, or we're launching an
      *         intent.)
      */
     @VisibleForTesting
-    protected @OverrideUrlLoadingResult int clobberCurrentTab(String url, String referrerUrl) {
+    protected @OverrideUrlLoadingResultType int clobberCurrentTab(String url, String referrerUrl) {
         int transitionType = PageTransition.LINK;
         final LoadUrlParams loadUrlParams = new LoadUrlParams(url, transitionType);
         if (!TextUtils.isEmpty(referrerUrl)) {
@@ -487,7 +488,7 @@
                     mDelegate.loadUrlIfPossible(loadUrlParams);
                 }
             });
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB;
         } else {
             assert false : "clobberCurrentTab was called with an empty tab.";
             Uri uri = Uri.parse(url);
@@ -497,7 +498,7 @@
             intent.addCategory(Intent.CATEGORY_BROWSABLE);
             intent.setPackage(packageName);
             startActivity(intent, false, mDelegate);
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
         }
     }
 
@@ -781,14 +782,14 @@
     private int handleUnresolvableIntent(
             ExternalNavigationParams params, Intent targetIntent, String browserFallbackUrl) {
         // Fallback URL will be handled by the caller of shouldOverrideUrlLoadingInternal.
-        if (browserFallbackUrl != null) return OverrideUrlLoadingResult.NO_OVERRIDE;
+        if (browserFallbackUrl != null) return OverrideUrlLoadingResultType.NO_OVERRIDE;
         if (targetIntent.getPackage() != null) return handleWithMarketIntent(params, targetIntent);
 
         if (DEBUG) Log.i(TAG, "Could not find an external activity to use");
-        return OverrideUrlLoadingResult.NO_OVERRIDE;
+        return OverrideUrlLoadingResultType.NO_OVERRIDE;
     }
 
-    private @OverrideUrlLoadingResult int handleWithMarketIntent(
+    private @OverrideUrlLoadingResultType int handleWithMarketIntent(
             ExternalNavigationParams params, Intent intent) {
         String marketReferrer = IntentUtils.safeGetStringExtra(intent, EXTRA_MARKET_REFERRER);
         if (TextUtils.isEmpty(marketReferrer)) {
@@ -850,9 +851,9 @@
      * This is the catch-all path for any intent that the app can handle that doesn't have a
      * specialized external app handling it.
      */
-    private @OverrideUrlLoadingResult int fallBackToHandlingInApp() {
+    private @OverrideUrlLoadingResultType int fallBackToHandlingInApp() {
         if (DEBUG) Log.i(TAG, "No specialized handler for URL");
-        return OverrideUrlLoadingResult.NO_OVERRIDE;
+        return OverrideUrlLoadingResultType.NO_OVERRIDE;
     }
 
     /**
@@ -949,7 +950,7 @@
                 params.isRendererInitiated(), params.getInitiatorOrigin());
     }
 
-    private @OverrideUrlLoadingResult int handleExternalIncognitoIntent(Intent targetIntent,
+    private @OverrideUrlLoadingResultType int handleExternalIncognitoIntent(Intent targetIntent,
             ExternalNavigationParams params, String browserFallbackUrl,
             boolean shouldProxyForInstantApps) {
         // This intent may leave this app. Warn the user that incognito does not carry over
@@ -958,10 +959,10 @@
                     params.shouldCloseContentsOnOverrideUrlLoadingAndLaunchIntent(),
                     shouldProxyForInstantApps)) {
             if (DEBUG) Log.i(TAG, "Incognito navigation out");
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION;
         }
         if (DEBUG) Log.i(TAG, "Failed to show incognito alert dialog.");
-        return OverrideUrlLoadingResult.NO_OVERRIDE;
+        return OverrideUrlLoadingResultType.NO_OVERRIDE;
     }
 
     /**
@@ -1128,35 +1129,37 @@
                 || blockExternalNavFromBackgroundTab(params) || ignoreBackForwardNav(params);
     }
 
-    private @OverrideUrlLoadingResult int shouldOverrideUrlLoadingInternal(
+    private @OverrideUrlLoadingResultType int shouldOverrideUrlLoadingInternal(
             ExternalNavigationParams params, Intent targetIntent,
             @Nullable String browserFallbackUrl, MutableBoolean canLaunchExternalFallbackResult) {
         sanitizeQueryIntentActivitiesIntent(targetIntent);
         // Don't allow external fallback URLs by default.
         canLaunchExternalFallbackResult.set(false);
 
-        if (shouldBlockAllExternalAppLaunches(params)) return OverrideUrlLoadingResult.NO_OVERRIDE;
+        if (shouldBlockAllExternalAppLaunches(params)) {
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
+        }
 
         if (handleWithAutofillAssistant(params, targetIntent, browserFallbackUrl)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         boolean isExternalProtocol = !UrlUtilities.isAcceptedScheme(params.getUrl());
 
         if (isInternalPdfDownload(isExternalProtocol, params)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         // This check should happen for reloads, navigations, etc..., which is why
         // it occurs before the subsequent blocks.
         if (startFileIntentIfNecessary(params, targetIntent)) {
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION;
         }
 
         // This should come after file intents, but before any returns of
         // OVERRIDE_WITH_EXTERNAL_INTENT.
         if (externalIntentRequestsDisabledForUrl(params)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         int pageTransitionCore = params.getPageTransition() & PageTransition.CORE_MASK;
@@ -1175,42 +1178,42 @@
                 (isLink && isFromIntent && params.isRedirect()) || isOnEffectiveIntentRedirect;
 
         if (handleCCTRedirectsToInstantApps(params, isExternalProtocol, incomingIntentRedirect)) {
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
         } else if (redirectShouldStayInApp(params, isExternalProtocol, targetIntent)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         if (!preferToShowIntentPicker(params, pageTransitionCore, isExternalProtocol, isFormSubmit,
                     linkNotFromIntent, incomingIntentRedirect)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
-        if (isLinkFromChromeInternalPage(params)) return OverrideUrlLoadingResult.NO_OVERRIDE;
+        if (isLinkFromChromeInternalPage(params)) return OverrideUrlLoadingResultType.NO_OVERRIDE;
 
         if (handleWtaiMcProtocol(params)) {
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
         }
         // TODO: handle other WTAI schemes.
-        if (isUnhandledWtaiProtocol(params)) return OverrideUrlLoadingResult.NO_OVERRIDE;
+        if (isUnhandledWtaiProtocol(params)) return OverrideUrlLoadingResultType.NO_OVERRIDE;
 
         boolean hasIntentScheme = params.getUrl().startsWith(UrlConstants.INTENT_URL_SHORT_PREFIX)
                 || params.getUrl().startsWith(UrlConstants.APP_INTENT_URL_SHORT_PREFIX);
         if (hasInternalScheme(params, targetIntent, hasIntentScheme)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         if (hasContentScheme(params, targetIntent, hasIntentScheme)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         if (hasFileSchemeInIntentURI(targetIntent, hasIntentScheme)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
-        if (isYoutubePairingCode(params)) return OverrideUrlLoadingResult.NO_OVERRIDE;
+        if (isYoutubePairingCode(params)) return OverrideUrlLoadingResultType.NO_OVERRIDE;
 
         if (shouldStayInIncognito(params, isExternalProtocol)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         if (!maybeSetSmsPackage(targetIntent)) maybeRecordPhoneIntentMetrics(targetIntent);
@@ -1233,7 +1236,7 @@
         if (!isExternalProtocol && !hasSpecializedHandler) {
             if (fallBackToHandlingWithInstantApp(
                         params, incomingIntentRedirect, linkNotFromIntent)) {
-                return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+                return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
             }
             return fallBackToHandlingInApp();
         }
@@ -1243,14 +1246,14 @@
 
         if (shouldStayWithinHost(
                     params, isLink, isFormSubmit, resolvingInfos, isExternalProtocol)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         boolean isDirectInstantAppsIntent =
                 isExternalProtocol && mDelegate.isIntentToInstantApp(targetIntent);
         boolean shouldProxyForInstantApps = isDirectInstantAppsIntent && isSerpReferrer();
         if (preventDirectInstantAppsIntent(isDirectInstantAppsIntent, shouldProxyForInstantApps)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         prepareExternalIntent(targetIntent, params, resolvingInfos, shouldProxyForInstantApps);
@@ -1276,18 +1279,18 @@
 
         if (shouldKeepIntentRedirectInApp(
                     params, incomingIntentRedirect, resolvingInfos, isExternalProtocol)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         if (isAlreadyInTargetWebApk(resolvingInfos, params)) {
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         } else if (launchWebApkIfSoleIntentHandler(resolvingInfos, targetIntent)) {
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
         }
         if (launchExternalIntent(targetIntent, shouldProxyForInstantApps)) {
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
         }
-        return OverrideUrlLoadingResult.NO_OVERRIDE;
+        return OverrideUrlLoadingResultType.NO_OVERRIDE;
     }
 
     /**
@@ -1309,7 +1312,7 @@
      * @return OVERRIDE_WITH_EXTERNAL_INTENT when we successfully started market activity,
      *         NO_OVERRIDE otherwise.
      */
-    private @OverrideUrlLoadingResult int sendIntentToMarket(
+    private @OverrideUrlLoadingResultType int sendIntentToMarket(
             String packageName, String marketReferrer, ExternalNavigationParams params) {
         Uri marketUri =
                 new Uri.Builder()
@@ -1329,7 +1332,7 @@
         if (!deviceCanHandleIntent(intent)) {
             // Exit early if the Play Store isn't available. (https://crbug.com/820709)
             if (DEBUG) Log.i(TAG, "Play Store not installed.");
-            return OverrideUrlLoadingResult.NO_OVERRIDE;
+            return OverrideUrlLoadingResultType.NO_OVERRIDE;
         }
 
         if (params.isIncognito()) {
@@ -1337,14 +1340,14 @@
 
                         params.shouldCloseContentsOnOverrideUrlLoadingAndLaunchIntent(), false)) {
                 if (DEBUG) Log.i(TAG, "Failed to show incognito alert dialog.");
-                return OverrideUrlLoadingResult.NO_OVERRIDE;
+                return OverrideUrlLoadingResultType.NO_OVERRIDE;
             }
             if (DEBUG) Log.i(TAG, "Incognito intent to Play Store.");
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION;
         } else {
             startActivity(intent, false, mDelegate);
             if (DEBUG) Log.i(TAG, "Intent to Play Store.");
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
         }
     }
 
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java
index 68672116..7b46d1a 100644
--- a/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java
+++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java
@@ -10,7 +10,7 @@
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.task.PostTask;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
 import org.chromium.components.navigation_interception.NavigationParams;
 import org.chromium.content_public.browser.NavigationController;
@@ -31,8 +31,8 @@
 public class InterceptNavigationDelegateImpl implements InterceptNavigationDelegate {
     private final AuthenticatorNavigationInterceptor mAuthenticatorHelper;
     private InterceptNavigationDelegateClient mClient;
-    private @OverrideUrlLoadingResult int mLastOverrideUrlLoadingResult =
-            OverrideUrlLoadingResult.NO_OVERRIDE;
+    private @OverrideUrlLoadingResultType int mLastOverrideUrlLoadingResultType =
+            OverrideUrlLoadingResultType.NO_OVERRIDE;
     private WebContents mWebContents;
     private ExternalNavigationHandler mExternalNavHandler;
 
@@ -81,14 +81,14 @@
 
         ExternalNavigationParams params =
                 new ExternalNavigationParams.Builder(url, incognito).setOpenInNewTab(true).build();
-        mLastOverrideUrlLoadingResult = mExternalNavHandler.shouldOverrideUrlLoading(params);
-        return mLastOverrideUrlLoadingResult
-                != ExternalNavigationHandler.OverrideUrlLoadingResult.NO_OVERRIDE;
+        mLastOverrideUrlLoadingResultType = mExternalNavHandler.shouldOverrideUrlLoading(params);
+        return mLastOverrideUrlLoadingResultType
+                != ExternalNavigationHandler.OverrideUrlLoadingResultType.NO_OVERRIDE;
     }
 
     @VisibleForTesting
-    public @OverrideUrlLoadingResult int getLastOverrideUrlLoadingResultForTests() {
-        return mLastOverrideUrlLoadingResult;
+    public @OverrideUrlLoadingResultType int getLastOverrideUrlLoadingResultTypeForTests() {
+        return mLastOverrideUrlLoadingResultType;
     }
 
     @Override
@@ -130,26 +130,26 @@
         ExternalNavigationParams params =
                 buildExternalNavigationParams(navigationParams, redirectHandler, shouldCloseTab)
                         .build();
-        @OverrideUrlLoadingResult
+        @OverrideUrlLoadingResultType
         int result = mExternalNavHandler.shouldOverrideUrlLoading(params);
-        mLastOverrideUrlLoadingResult = result;
+        mLastOverrideUrlLoadingResultType = result;
 
         switch (result) {
-            case OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT:
+            case OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT:
                 assert mExternalNavHandler.canExternalAppHandleUrl(url);
                 if (navigationParams.isMainFrame) {
                     onOverrideUrlLoadingAndLaunchIntent(shouldCloseTab);
                 }
                 return true;
-            case OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB:
+            case OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB:
                 mShouldClearRedirectHistoryForTabClobbering = true;
                 return true;
-            case OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION:
+            case OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION:
                 if (!shouldCloseTab && navigationParams.isMainFrame) {
                     onOverrideUrlLoadingAndLaunchIntent(shouldCloseTab);
                 }
                 return true;
-            case OverrideUrlLoadingResult.NO_OVERRIDE:
+            case OverrideUrlLoadingResultType.NO_OVERRIDE:
             default:
                 if (navigationParams.isExternalProtocol) {
                     logBlockedNavigationToDevToolsConsole(url);
diff --git a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java
index 13c0438..5165306 100644
--- a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java
+++ b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java
@@ -34,7 +34,7 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
@@ -180,13 +180,13 @@
 
         checkUrl(YOUTUBE_URL)
                 .withRedirectHandler(handler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         mDelegate.setIsCallingAppTrusted(true);
 
         checkUrl(YOUTUBE_URL)
                 .withRedirectHandler(handler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -199,7 +199,7 @@
         // it within the browser.
         checkUrl(YOUTUBE_URL)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -210,10 +210,10 @@
         // http://crbug.com/159153: Don't override http or https URLs from the NTP or bookmarks.
         checkUrl(YOUTUBE_URL)
                 .withReferrer("chrome://about")
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
         checkUrl("tel:012345678")
                 .withReferrer("chrome://about")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -226,7 +226,7 @@
         // forwards or backwards navigations.
         checkUrl(YOUTUBE_URL)
                 .withPageTransition(PageTransition.LINK | PageTransition.FORWARD_BACK)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -240,13 +240,13 @@
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         checkUrl("http://youtube.com://")
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         // If the page matches the referrer, then continue loading in Chrome.
@@ -255,7 +255,7 @@
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(true)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // If the page does not match the referrer, then prompt an intent.
         checkUrl("http://youtube.com://")
@@ -263,7 +263,7 @@
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         // It doesn't make sense to allow intent picker without redirect, since form data
@@ -272,7 +272,7 @@
         checkUrl("http://youtube.com://")
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withHasUserGesture(true)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -285,12 +285,12 @@
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(false)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
         checkUrl("http://youtube.com://")
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(false)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -312,14 +312,14 @@
                 .withIsRedirect(true)
                 .withHasUserGesture(false)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         checkUrl("http://youtube.com://")
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(false)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -329,7 +329,7 @@
         mDelegate.add(new IntentActivity(YOUTUBE_URL, YOUTUBE_PACKAGE_NAME));
         mDelegate.setDisableExternalIntentRequests(true);
 
-        checkUrl(YOUTUBE_URL).expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+        checkUrl(YOUTUBE_URL).expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -344,9 +344,9 @@
                 "intent://com.android.chrome.FileProvider/foo.html#Intent;scheme=content;end;",
                 "intent:///x.mhtml#Intent;package=com.android.chrome;action=android.intent.action.VIEW;scheme=file;end;"};
         for (String url : urlsToIgnore) {
-            checkUrl(url).expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+            checkUrl(url).expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
             checkUrl(url).withIsIncognito(true).expecting(
-                    OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                    OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
         }
     }
 
@@ -357,23 +357,23 @@
 
         // Non-link page transition type are ignored.
         checkUrl(YOUTUBE_URL)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         checkUrl(YOUTUBE_URL)
                 .withIsRedirect(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         // http://crbug.com/143118 - Don't show the picker for directly typed URLs, unless
         // the URL results in a redirect.
         checkUrl(YOUTUBE_URL)
                 .withPageTransition(PageTransition.TYPED)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // http://crbug.com/162106 - Don't show the picker on reload.
         checkUrl(YOUTUBE_URL)
                 .withPageTransition(PageTransition.RELOAD)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -382,20 +382,20 @@
         // Start the telephone application with the given number.
         checkUrl("wtai://wp/mc;0123456789")
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY | INTENT_SANITIZATION_EXCEPTION);
 
         // These two cases are currently unimplemented.
         checkUrl("wtai://wp/sd;0123456789")
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE,
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE,
                         IGNORE | INTENT_SANITIZATION_EXCEPTION);
         checkUrl("wtai://wp/ap;0123456789")
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE,
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE,
                         IGNORE | INTENT_SANITIZATION_EXCEPTION);
 
         // Ignore other WTAI urls.
         checkUrl("wtai://wp/invalid")
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE,
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE,
                         IGNORE | INTENT_SANITIZATION_EXCEPTION);
     }
 
@@ -406,7 +406,7 @@
 
         checkUrl(INTENT_APP_NOT_INSTALLED_WITH_MARKET_REFERRER)
                 .withReferrer(KEEP_URL)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertNotNull(mDelegate.startActivityIntent);
@@ -423,7 +423,7 @@
         mDelegate.setCanResolveActivityForExternalSchemes(false);
 
         checkUrl(INTENT_APP_NOT_INSTALLED_DEFAULT_MARKET_REFERRER)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertNotNull(mDelegate.startActivityIntent);
@@ -436,7 +436,7 @@
     @SmallTest
     public void testExternalUri() {
         checkUrl("tel:012345678")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -447,20 +447,20 @@
         checkUrl("market://1234")
                 .withPageTransition(PageTransition.TYPED)
                 .withIsRedirect(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         // http://crbug.com/709217
         checkUrl("market://1234")
                 .withPageTransition(PageTransition.FROM_ADDRESS_BAR)
                 .withIsRedirect(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         // http://crbug.com/143118
         checkUrl("market://1234")
                 .withPageTransition(PageTransition.TYPED)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -472,13 +472,13 @@
         // http://crbug.com/149218
         checkUrl(YOUTUBE_URL)
                 .withPageTransition(transitionTypeIncomingIntent)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // http://crbug.com/170925
         checkUrl(YOUTUBE_URL)
                 .withPageTransition(transitionTypeIncomingIntent)
                 .withIsRedirect(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -493,15 +493,15 @@
                 + "action=android.settings.SETTINGS;end";
 
         checkUrl(url).expecting(
-                OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
+                OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
 
         // http://crbug.com/370399
         checkUrl(urlWithSel)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         checkUrl(urlWithNullData)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -525,23 +525,24 @@
         for (String url : goodUrls) {
             // http://crbug/386600 - it makes no sense to switch activities for pairing code URLs.
             checkUrl(url).withIsRedirect(true).expecting(
-                    OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                    OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
             checkUrl(url)
                     .withPageTransition(transitionTypeIncomingIntent)
                     .withIsRedirect(true)
-                    .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                    .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
         }
 
         // The pairing code URL regex shouldn't cause NO_OVERRIDE on invalid URLs.
         for (String url : badUrls) {
             checkUrl(url).withIsRedirect(true).expecting(
-                    OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
+                    OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
+                    START_OTHER_ACTIVITY);
 
             checkUrl(url)
                     .withPageTransition(transitionTypeIncomingIntent)
                     .withIsRedirect(true)
-                    .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                    .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                             START_OTHER_ACTIVITY);
         }
     }
@@ -567,7 +568,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // Do not ignore if a new intent has any new resolver.
         redirectHandler.updateIntent(fooIntent, !IS_CUSTOM_TAB_INTENT, !SEND_TO_EXTERNAL_APPS,
@@ -578,7 +579,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         // Do not ignore if a new intent cannot be handled by Chrome.
@@ -590,7 +591,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -613,7 +614,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // Do not ignore if the URI has an external protocol.
         redirectHandler.updateIntent(fooIntent, !IS_CUSTOM_TAB_INTENT, !SEND_TO_EXTERNAL_APPS,
@@ -624,7 +625,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -645,7 +646,7 @@
         checkUrl(YOUTUBE_URL)
                 .withPageTransition(transTypeLinkFromIntent)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // In Custom Tabs, if the first url is a redirect, don't allow it to intent out.
         Intent fooIntent = Intent.parseUri("http://foo.com/", Intent.URI_INTENT_SCHEME);
@@ -658,7 +659,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // In Custom Tabs, if the external handler extra is present, intent out if the first
         // url is a redirect.
@@ -672,7 +673,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Intent extraIntent3 = Intent.parseUri(YOUTUBE_URL, Intent.URI_INTENT_SCHEME);
@@ -685,7 +686,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         // External intent for a user-initiated navigation should always be allowed.
@@ -698,7 +699,7 @@
         checkUrl(YOUTUBE_URL)
                 .withPageTransition(PageTransition.LINK)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -723,7 +724,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
     }
 
     @Test
@@ -732,7 +733,7 @@
         mDelegate.setCanLoadUrlInTab(false);
         checkUrl(INTENT_URL_FOR_CHROME_CUSTOM_TABS)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
         Assert.assertTrue(mDelegate.handleIncognitoIntentTargetingSelfCalled);
     }
 
@@ -741,7 +742,7 @@
     public void testCCTIntentUriFiresCCT_InRegular() throws Exception {
         checkUrl(INTENT_URL_FOR_CHROME_CUSTOM_TABS)
                 .withIsIncognito(false)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertFalse(mDelegate.handleIncognitoIntentTargetingSelfCalled);
     }
@@ -752,7 +753,7 @@
         mDelegate.setCanLoadUrlInTab(false);
         checkUrl(INTENT_URL_FOR_CHROME)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
         Assert.assertTrue(mDelegate.handleIncognitoIntentTargetingSelfCalled);
     }
 
@@ -773,7 +774,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
 
         // URL that cannot be handled with instant apps should stay in Chrome.
         mDelegate.setCanHandleWithInstantApp(false);
@@ -781,7 +782,7 @@
                 .withPageTransition(transTypeLinkFromIntent)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -790,12 +791,12 @@
         mDelegate.setCanHandleWithInstantApp(false);
         checkUrl("http://maybeinstantapp.com")
                 .withPageTransition(PageTransition.LINK)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         mDelegate.setCanHandleWithInstantApp(true);
         checkUrl("http://maybeinstantapp.com")
                 .withPageTransition(PageTransition.LINK)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, IGNORE);
     }
 
     @Test
@@ -811,21 +812,21 @@
 
         mUrlHandler.mIsSerpReferrer = true;
         mDelegate.setIsIntentToInstantApp(true);
-        checkUrl(intentUrl).expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+        checkUrl(intentUrl).expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                 START_OTHER_ACTIVITY | PROXY_FOR_INSTANT_APPS);
         Assert.assertTrue(
                 mDelegate.startActivityIntent.getBooleanExtra(IS_INSTANT_APP_EXTRA, false));
 
         // Check that we block all instant app intent:// URLs not from SERP.
         mUrlHandler.mIsSerpReferrer = false;
-        checkUrl(intentUrl).expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+        checkUrl(intentUrl).expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // Check that that just having the SERP referrer alone doesn't cause intents to be treated
         // as intents to instant apps if the delegate indicates that they shouldn't be.
         mUrlHandler.mIsSerpReferrer = true;
         mDelegate.setIsIntentToInstantApp(false);
         checkUrl(intentUrl).expecting(
-                OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
+                OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
         Assert.assertFalse(
                 mDelegate.startActivityIntent.getBooleanExtra(IS_INSTANT_APP_EXTRA, true));
     }
@@ -838,7 +839,7 @@
 
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Intent invokedIntent = mDelegate.startActivityIntent;
@@ -859,7 +860,7 @@
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withIsIncognito(true)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION,
                         START_INCOGNITO | START_OTHER_ACTIVITY);
 
         Assert.assertNull(mUrlHandler.mNewUrlAfterClobbering);
@@ -875,7 +876,8 @@
         mDelegate.add(new IntentActivity(IMDB_WEBPAGE_FOR_TOM_HANKS, WEBAPK_PACKAGE_NAME));
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_WEBAPK);
+                .expecting(
+                        OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_WEBAPK);
     }
 
     @Test
@@ -888,7 +890,7 @@
         mDelegate.add(new IntentActivity(IMDB_WEBPAGE_FOR_TOM_HANKS, TEXT_APP_1_PACKAGE_NAME));
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
         Assert.assertNull(mDelegate.startActivityIntent);
         Assert.assertEquals(IMDB_WEBPAGE_FOR_TOM_HANKS, mUrlHandler.mNewUrlAfterClobbering);
         Assert.assertEquals(SEARCH_RESULT_URL_FOR_TOM_HANKS, mUrlHandler.mReferrerUrlForClobbering);
@@ -904,7 +906,7 @@
         // the current tab.
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
         Assert.assertEquals(IMDB_WEBPAGE_FOR_TOM_HANKS, mUrlHandler.mNewUrlAfterClobbering);
@@ -921,7 +923,7 @@
                 + "https://play.google.com/store/apps/details?id=com.imdb.mobile"
                 + "&referrer=mypage;end";
         checkUrl(intent).expecting(
-                OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
+                OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
 
         Assert.assertEquals("market://details?id=com.imdb.mobile&referrer=mypage",
                 mDelegate.startActivityIntent.getDataString());
@@ -930,7 +932,7 @@
                 + "S." + ExternalNavigationHandler.EXTRA_BROWSER_FALLBACK_URL + "="
                 + "https://play.google.com/store/apps/details?id=com.imdb.mobile;end";
         checkUrl(intentNoRef)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertEquals("market://details?id=com.imdb.mobile&referrer=" + getPackageName(),
@@ -940,7 +942,7 @@
                 + "S." + ExternalNavigationHandler.EXTRA_BROWSER_FALLBACK_URL + "="
                 + "https://play.google.com/store/search?q=pub:imdb;end";
         checkUrl(intentBadUrl)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
     }
 
     @Test
@@ -959,7 +961,7 @@
                 .withHasUserGesture(true)
                 .withRedirectHandler(redirectHandler)
                 .withPageTransition(PageTransition.LINK)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertEquals("market://details?id=com.imdb.mobile&referrer=mypage",
                 mDelegate.startActivityIntent.getDataString());
@@ -974,7 +976,7 @@
                 .withHasUserGesture(true)
                 .withRedirectHandler(redirectHandler)
                 .withPageTransition(PageTransition.LINK)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -988,7 +990,7 @@
         checkUrl("http://goo.gl/abcdefg")
                 .withPageTransition(PageTransition.LINK)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, true, true, 0, 0);
         String realIntent = "intent:///name/nm0000158#Intent;scheme=imdb;package=com.imdb.mobile;"
@@ -1000,7 +1002,7 @@
                 .withPageTransition(PageTransition.LINK)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertEquals("market://details?id=com.imdb.mobile&referrer=mypage",
@@ -1024,7 +1026,7 @@
                 .withRedirectHandler(redirectHandler)
                 .withPageTransition(PageTransition.AUTO_SUBFRAME)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1040,7 +1042,7 @@
                 .withRedirectHandler(redirectHandler)
                 .withPageTransition(PageTransition.LINK)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
     }
 
     @Test
@@ -1052,7 +1054,7 @@
         // Fallback URL should work even when package name isn't given.
         checkUrl(INTENT_URL_WITH_FALLBACK_URL_WITHOUT_PACKAGE_NAME)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
         Assert.assertEquals(IMDB_WEBPAGE_FOR_TOM_HANKS, mUrlHandler.mNewUrlAfterClobbering);
@@ -1068,7 +1070,7 @@
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
         Assert.assertEquals(IMDB_WEBPAGE_FOR_TOM_HANKS, mUrlHandler.mNewUrlAfterClobbering);
@@ -1085,7 +1087,7 @@
         checkUrl(INTENT_URL_WITH_JAVASCRIPT_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION,
                         START_INCOGNITO | START_OTHER_ACTIVITY);
 
         Intent invokedIntent = mUrlHandler.mStartActivityInIncognitoIntent;
@@ -1105,18 +1107,18 @@
         checkUrl("http://goo.gl/abcdefg")
                 .withPageTransition(PageTransition.TYPED)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, false, 0, 0);
         checkUrl(INTENT_URL_WITH_FALLBACK_URL_WITHOUT_PACKAGE_NAME)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
 
         // Now the user opens a link.
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, true, 0, 1);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1130,7 +1132,7 @@
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, true, 0, 0);
         checkUrl(INTENT_URL_WITH_CHAIN_FALLBACK_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
 
         // As a result of intent resolution fallback, we have clobberred the current tab.
         // The fall-back URL was HTTP-schemed, but it was effectively redirected to a new intent
@@ -1139,7 +1141,7 @@
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, false, 0, 0);
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         // Now enough time (2 seconds) have passed.
         // New URL loading should not be affected.
@@ -1151,7 +1153,7 @@
                 PageTransition.LINK, false, true, lastUserInteractionTimeInMillis, 1);
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
     }
 
     @Test
@@ -1165,19 +1167,19 @@
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withPageTransition(PageTransition.TYPED)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.TYPED, true, false, 0, 0);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withPageTransition(PageTransition.TYPED)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, false, 0, 1);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1190,18 +1192,18 @@
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, false, 1, 0);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, true, false, 1, 0);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, false, 1, 1);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1209,7 +1211,7 @@
     public void testChromeAppInBackground() {
         mDelegate.add(new IntentActivity(YOUTUBE_URL, YOUTUBE_PACKAGE_NAME));
         mDelegate.setIsChromeAppInForeground(false);
-        checkUrl(YOUTUBE_URL).expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+        checkUrl(YOUTUBE_URL).expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1219,7 +1221,7 @@
         mDelegate.setIsChromeAppInForeground(false);
         checkUrl(YOUTUBE_URL)
                 .withChromeAppInForegroundRequired(false)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -1233,9 +1235,9 @@
                 new ExternalNavigationParams.Builder(YOUTUBE_MOBILE_URL, false)
                         .setOpenInNewTab(true)
                         .build();
-        @OverrideUrlLoadingResult
+        @OverrideUrlLoadingResultType
         int result = mUrlHandler.shouldOverrideUrlLoading(params);
-        Assert.assertEquals(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, result);
+        Assert.assertEquals(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, result);
         Assert.assertTrue(mDelegate.startActivityIntent != null);
         Assert.assertTrue(
                 mDelegate.startActivityIntent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false));
@@ -1262,7 +1264,7 @@
 
         checkUrl(PLUS_STREAM_URL)
                 .withReferrer(PLUS_STREAM_URL)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1272,7 +1274,7 @@
 
         checkUrl(CALENDAR_URL)
                 .withReferrer(KEEP_URL)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -1284,7 +1286,7 @@
         checkUrl(CALENDAR_URL)
                 .withReferrer(KEEP_URL)
                 .withPageTransition(PageTransition.FORM_SUBMIT)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1294,7 +1296,7 @@
 
         checkUrl(YOUTUBE_URL)
                 .withIsBackgroundTabNavigation(true)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1303,7 +1305,7 @@
         mDelegate.add(new IntentActivity(CALENDAR_URL, "calendar"));
 
         checkUrl(CALENDAR_URL + "/file.pdf")
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1311,7 +1313,7 @@
     public void testIntentToPdfFileOpensApp() {
         checkUrl("intent://yoursite.com/mypdf.pdf#Intent;action=VIEW;category=BROWSABLE;"
                 + "scheme=http;package=com.adobe.reader;end;")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -1319,7 +1321,7 @@
     @SmallTest
     public void testUsafeIntentFlagsFiltered() {
         checkUrl("intent://#Intent;package=com.test.package;launchFlags=0x7FFFFFFF;end;")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertEquals(ExternalNavigationHandler.ALLOWED_INTENT_FLAGS,
                 mDelegate.startActivityIntent.getFlags());
@@ -1329,14 +1331,14 @@
     @SmallTest
     public void testIntentWithFileSchemeFiltered() {
         checkUrl("intent://#Intent;package=com.test.package;scheme=file;end;")
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
     @SmallTest
     public void testIntentWithNoSchemeLaunched() {
         checkUrl("intent://#Intent;package=com.test.package;end;")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -1344,7 +1346,7 @@
     @SmallTest
     public void testIntentWithEmptySchemeLaunched() {
         checkUrl("intent://#Intent;package=com.test.package;scheme=;end;")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -1352,7 +1354,7 @@
     @SmallTest
     public void testIntentWithWeirdSchemeLaunched() {
         checkUrl("intent://#Intent;package=com.test.package;scheme=w3irD;end;")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -1367,11 +1369,12 @@
         // WebContents.lastCommittedUrl.
 
         checkUrl("http://refertest.com")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         mUrlHandler.mLastCommittedUrl = "https://refertest.com";
-        checkUrl("http://refertest.com").expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+        checkUrl("http://refertest.com")
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1385,7 +1388,7 @@
                 .withPageTransition(PageTransition.FORM_SUBMIT)
                 .withIsRedirect(true)
                 .withHasUserGesture(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertEquals(Uri.parse(referrer),
                 mDelegate.startActivityIntent.getParcelableExtra(Intent.EXTRA_REFERRER));
@@ -1401,18 +1404,18 @@
         redirectHandler.updateNewUrlLoading(PageTransition.RELOAD, false, false, 1, 0);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, true, false, 1, 0);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, false, 1, 1);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1426,18 +1429,18 @@
                 PageTransition.FORM_SUBMIT | PageTransition.FORWARD_BACK, false, false, 1, 0);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, true, false, 1, 0);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withIsRedirect(true)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         redirectHandler.updateNewUrlLoading(PageTransition.LINK, false, false, 1, 1);
         checkUrl(YOUTUBE_MOBILE_URL)
                 .withRedirectHandler(redirectHandler)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
     }
 
     @Test
@@ -1448,19 +1451,19 @@
 
         mUrlHandler.mShouldRequestFileAccess = false;
         // Verify no overrides if file access is allowed (under different load conditions).
-        checkUrl(fileUrl).expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+        checkUrl(fileUrl).expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
         checkUrl(fileUrl)
                 .withPageTransition(PageTransition.RELOAD)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
         checkUrl(fileUrl)
                 .withPageTransition(PageTransition.AUTO_TOPLEVEL)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         mUrlHandler.mShouldRequestFileAccess = true;
         // Verify that the file intent action is triggered if file access is not allowed.
         checkUrl(fileUrl)
                 .withPageTransition(PageTransition.AUTO_TOPLEVEL)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION, START_FILE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION, START_FILE);
     }
 
     @Test
@@ -1473,7 +1476,7 @@
 
         checkUrl("sms:+012345678?body=hello%20there")
                 .withReferrer(referer)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertNotNull(mDelegate.startActivityIntent);
@@ -1491,7 +1494,7 @@
 
         checkUrl("sms:+012345678?body=hello%20there")
                 .withReferrer(referer)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertNotNull(mDelegate.startActivityIntent);
@@ -1508,7 +1511,7 @@
 
         checkUrl("intent://012345678?body=hello%20there/#Intent;scheme=sms;end")
                 .withReferrer(referer)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertNotNull(mDelegate.startActivityIntent);
@@ -1525,7 +1528,8 @@
         mDelegate.add(new IntentActivity(WEBAPK_SCOPE, WEBAPK_PACKAGE_NAME));
 
         checkUrl(WEBAPK_SCOPE)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_WEBAPK);
+                .expecting(
+                        OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_WEBAPK);
     }
 
     /**
@@ -1540,7 +1544,7 @@
         mDelegate.add(new IntentActivity(scope, "com.webapk.with.native.android"));
 
         checkUrl(scope).expecting(
-                OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
+                OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
     }
 
     /**
@@ -1560,7 +1564,7 @@
         mDelegate.setReferrerWebappPackageName(scope1WebApkPackageName);
 
         checkUrl(scope2).withReferrer(scope1).expecting(
-                OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_WEBAPK);
+                OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_WEBAPK);
     }
 
     /**
@@ -1573,7 +1577,7 @@
     public void testLaunchWebApk_ShowIntentPickerInvalidWebApk() {
         mDelegate.add(new IntentActivity(WEBAPK_SCOPE, INVALID_WEBAPK_PACKAGE_NAME));
         checkUrl(WEBAPK_SCOPE)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
     }
 
@@ -1581,7 +1585,7 @@
     @SmallTest
     public void testMarketIntent_MarketInstalled() {
         checkUrl("market://1234")
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
 
         Assert.assertNotNull(mDelegate.startActivityIntent);
@@ -1592,7 +1596,7 @@
     @SmallTest
     public void testMarketIntent_MarketNotInstalled() {
         mDelegate.setCanResolveActivityForMarket(false);
-        checkUrl("market://1234").expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+        checkUrl("market://1234").expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
     }
@@ -1602,7 +1606,7 @@
     public void testMarketIntent_ShowDialogIncognitoMarketInstalled() {
         checkUrl("market://1234")
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION,
                         START_INCOGNITO | START_OTHER_ACTIVITY);
 
         Assert.assertTrue(mUrlHandler.mStartIncognitoIntentCalled);
@@ -1614,7 +1618,7 @@
         mDelegate.setCanResolveActivityForMarket(false);
         checkUrl("market://1234")
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         Assert.assertFalse(mUrlHandler.mStartIncognitoIntentCalled);
     }
@@ -1628,7 +1632,7 @@
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
                 .withHasUserGesture(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertTrue(mDelegate.maybeSetRequestMetadataCalled);
         Assert.assertFalse(mUrlHandler.mStartIncognitoIntentCalled);
@@ -1644,7 +1648,7 @@
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
                 .withHasUserGesture(true)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_ASYNC_ACTION,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION,
                         START_INCOGNITO | START_OTHER_ACTIVITY);
         Assert.assertTrue(mDelegate.maybeSetRequestMetadataCalled);
         Assert.assertTrue(mUrlHandler.mStartIncognitoIntentCalled);
@@ -1659,7 +1663,7 @@
         checkUrl(INTENT_URL_WITH_FALLBACK_URL)
                 .withReferrer(SEARCH_RESULT_URL_FOR_TOM_HANKS)
                 .withIsRendererInitiated(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertTrue(mDelegate.maybeSetRequestMetadataCalled);
     }
@@ -1669,7 +1673,7 @@
     public void testAutofillAssistantIntentWithFallback_InRegular() {
         mDelegate.setIsIntentToAutofillAssistant(true);
         checkUrl(AUTOFILL_ASSISTANT_INTENT_URL_WITH_FALLBACK)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
     }
@@ -1680,7 +1684,7 @@
         mDelegate.setIsIntentToAutofillAssistant(true);
         checkUrl(AUTOFILL_ASSISTANT_INTENT_URL_WITH_FALLBACK)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
     }
@@ -1691,7 +1695,7 @@
         mDelegate.setIsIntentToAutofillAssistant(true);
         checkUrl(AUTOFILL_ASSISTANT_INTENT_URL_WITHOUT_FALLBACK)
                 .withIsIncognito(false)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
     }
@@ -1702,7 +1706,7 @@
         mDelegate.setIsIntentToAutofillAssistant(true);
         checkUrl(AUTOFILL_ASSISTANT_INTENT_URL_WITHOUT_FALLBACK)
                 .withIsIncognito(true)
-                .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE);
+                .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE);
 
         Assert.assertNull(mDelegate.startActivityIntent);
     }
@@ -1724,7 +1728,7 @@
                 ExternalNavigationHandler.StandardActions.VIEW);
 
         checkUrl(intentWithAction)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertEquals(pickCount + 1,
                 RecordHistogram.getHistogramValueCountForTesting(
@@ -1736,7 +1740,7 @@
                         ExternalNavigationHandler.StandardActions.VIEW));
 
         checkUrl(intentWithoutAction)
-                .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT,
+                .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT,
                         START_OTHER_ACTIVITY);
         Assert.assertEquals(viewCount + 1,
                 RecordHistogram.getHistogramValueCountForTesting(
@@ -1754,7 +1758,7 @@
                 ExternalNavigationHandler.StandardActions.ANSWER);
 
         checkUrl(appIntent).expecting(
-                OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
+                OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY);
         Assert.assertEquals(count + 1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         ExternalNavigationHandler.INTENT_ACTION_HISTOGRAM,
@@ -2027,10 +2031,11 @@
         }
 
         @Override
-        protected @OverrideUrlLoadingResult int clobberCurrentTab(String url, String referrerUrl) {
+        protected @OverrideUrlLoadingResultType int clobberCurrentTab(
+                String url, String referrerUrl) {
             mNewUrlAfterClobbering = url;
             mReferrerUrlForClobbering = referrerUrl;
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB;
         }
     };
 
@@ -2110,11 +2115,11 @@
         }
 
         @Override
-        public @OverrideUrlLoadingResult int handleIncognitoIntentTargetingSelf(
+        public @OverrideUrlLoadingResultType int handleIncognitoIntentTargetingSelf(
                 Intent intent, String referrerUrl, String fallbackUrl) {
             handleIncognitoIntentTargetingSelfCalled = true;
-            if (mCanLoadUrlInTab) return OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB;
-            return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
+            if (mCanLoadUrlInTab) return OverrideUrlLoadingResultType.OVERRIDE_WITH_CLOBBERING_TAB;
+            return OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT;
         }
 
         @Override
@@ -2383,7 +2388,7 @@
         }
 
         public void expecting(
-                @OverrideUrlLoadingResult int expectedOverrideResult, int otherExpectation) {
+                @OverrideUrlLoadingResultType int expectedOverrideResult, int otherExpectation) {
             boolean expectStartIncognito = (otherExpectation & START_INCOGNITO) != 0;
             boolean expectStartActivity =
                     (otherExpectation & (START_WEBAPK | START_OTHER_ACTIVITY)) != 0;
@@ -2407,7 +2412,7 @@
                             .setHasUserGesture(mHasUserGesture)
                             .setIsRendererInitiated(mIsRendererInitiated)
                             .build();
-            @OverrideUrlLoadingResult
+            @OverrideUrlLoadingResultType
             int result = mUrlHandler.shouldOverrideUrlLoading(params);
             boolean startActivityCalled = false;
             boolean startWebApkCalled = false;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index f0d26f6f..2d9a92c1 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -1760,6 +1760,7 @@
         'chrome_os:14-',
         'android:30-',
       ],
+      'future_on': [ 'ios' ],
       'features': {
         'dynamic_refresh': True,
         'per_profile': True,
diff --git a/components/power_metrics/android_battery_metrics.cc b/components/power_metrics/android_battery_metrics.cc
index 8d9fd5d04..40994ed 100644
--- a/components/power_metrics/android_battery_metrics.cc
+++ b/components/power_metrics/android_battery_metrics.cc
@@ -6,18 +6,23 @@
 
 #include "base/android/radio_utils.h"
 #include "base/bind.h"
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/optional.h"
 #include "base/power_monitor/power_monitor.h"
+#include "base/trace_event/trace_event.h"
 #include "net/android/network_library.h"
 #include "net/android/traffic_stats.h"
 
+const base::Feature kForegroundRadioStateCountWakeups{
+    "ForegroundRadioStateCountWakeups", base::FEATURE_DISABLED_BY_DEFAULT};
+
 namespace power_metrics {
 namespace {
 
-void Report30SecondRadioUsage(int64_t tx_bytes, int64_t rx_bytes) {
+void Report30SecondRadioUsage(int64_t tx_bytes, int64_t rx_bytes, int wakeups) {
   if (!base::android::RadioUtils::IsSupported())
     return;
 
@@ -59,6 +64,21 @@
     UMA_HISTOGRAM_SCALED_ENUMERATION(
         "Power.ForegroundRadio.ReceivedKiB.Cell.30Seconds", cell_level,
         rx_bytes, 1024);
+
+    // Number of radio wakeups during the last 30 seconds.
+    if (base::FeatureList::IsEnabled(kForegroundRadioStateCountWakeups) &&
+        wakeups > 0) {
+      static const int kMaxLevel =
+          static_cast<int>(base::android::RadioSignalLevel::kMaxValue);
+      static const char kWakeupsHistogramName[] =
+          "Power.ForegroundRadio.Wakeups.Cell.30Seconds";
+      STATIC_HISTOGRAM_POINTER_BLOCK(
+          kWakeupsHistogramName,
+          AddCount(static_cast<int>(cell_level), wakeups),
+          base::Histogram::FactoryGet(
+              kWakeupsHistogramName, 0, kMaxLevel, kMaxLevel + 1,
+              base::HistogramBase::kUmaTargetedHistogramFlag));
+    }
   }
 }
 
@@ -115,6 +135,7 @@
 
 // static
 constexpr base::TimeDelta AndroidBatteryMetrics::kMetricsInterval;
+constexpr base::TimeDelta AndroidBatteryMetrics::kRadioStateInterval;
 
 AndroidBatteryMetrics::AndroidBatteryMetrics()
     : app_visible_(false),
@@ -160,13 +181,31 @@
 
     metrics_timer_.Start(FROM_HERE, kMetricsInterval, this,
                          &AndroidBatteryMetrics::CaptureAndReportMetrics);
+    if (base::FeatureList::IsEnabled(kForegroundRadioStateCountWakeups)) {
+      radio_state_timer_.Start(FROM_HERE, kRadioStateInterval, this,
+                               &AndroidBatteryMetrics::MonitorRadioState);
+    }
   } else if (!should_be_enabled && metrics_timer_.IsRunning()) {
     // Capture one last measurement before disabling the timer.
     CaptureAndReportMetrics();
     metrics_timer_.Stop();
+    if (base::FeatureList::IsEnabled(kForegroundRadioStateCountWakeups)) {
+      radio_state_timer_.Stop();
+    }
   }
 }
 
+void AndroidBatteryMetrics::MonitorRadioState() {
+  base::android::RadioDataActivity activity =
+      base::android::RadioUtils::GetCellDataActivity();
+  if (last_activity_ == base::android::RadioDataActivity::kDormant &&
+      activity != base::android::RadioDataActivity::kDormant) {
+    TRACE_EVENT_INSTANT0("power", "RadioWakeup", TRACE_EVENT_SCOPE_GLOBAL);
+    ++radio_wakeups_;
+  }
+  last_activity_ = activity;
+}
+
 void AndroidBatteryMetrics::UpdateAndReportRadio() {
   int64_t tx_bytes;
   int64_t rx_bytes;
@@ -178,10 +217,11 @@
   if (last_tx_bytes_ > 0 && tx_bytes > 0 && last_rx_bytes_ > 0 &&
       rx_bytes > 0) {
     Report30SecondRadioUsage(tx_bytes - last_tx_bytes_,
-                             rx_bytes - last_rx_bytes_);
+                             rx_bytes - last_rx_bytes_, radio_wakeups_);
   }
   last_tx_bytes_ = tx_bytes;
   last_rx_bytes_ = rx_bytes;
+  radio_wakeups_ = 0;
 }
 
 void AndroidBatteryMetrics::CaptureAndReportMetrics() {
diff --git a/components/power_metrics/android_battery_metrics.h b/components/power_metrics/android_battery_metrics.h
index 0f8c91e..2373722 100644
--- a/components/power_metrics/android_battery_metrics.h
+++ b/components/power_metrics/android_battery_metrics.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_POWER_METRICS_ANDROID_BATTERY_METRICS_H_
 #define COMPONENTS_POWER_METRICS_ANDROID_BATTERY_METRICS_H_
 
+#include "base/android/radio_utils.h"
 #include "base/macros.h"
 #include "base/power_monitor/power_observer.h"
 #include "base/sequence_checker.h"
@@ -31,6 +32,7 @@
   void UpdateMetricsEnabled();
   void CaptureAndReportMetrics();
   void UpdateAndReportRadio();
+  void MonitorRadioState();
 
   // Whether or not we've seen at least two consecutive capacity drops while
   // the embedding app was visible. Battery drain reported prior to this could
@@ -42,12 +44,20 @@
   static constexpr base::TimeDelta kMetricsInterval =
       base::TimeDelta::FromSeconds(30);
 
+  // Radio state is polled with this interval to count radio wakeups.
+  static constexpr base::TimeDelta kRadioStateInterval =
+      base::TimeDelta::FromSeconds(1);
+
   bool app_visible_;
   bool on_battery_power_;
   int last_remaining_capacity_uah_ = 0;
   int64_t last_tx_bytes_ = -1;
   int64_t last_rx_bytes_ = -1;
+  base::android::RadioDataActivity last_activity_ =
+      base::android::RadioDataActivity::kNone;
+  int radio_wakeups_ = 0;
   base::RepeatingTimer metrics_timer_;
+  base::RepeatingTimer radio_state_timer_;
   int skipped_timers_ = 0;
 
   // Number of consecutive charge drops seen while the app has been visible.
diff --git a/components/safety_check/safety_check.h b/components/safety_check/safety_check.h
index 7ca202d..3aab1c1 100644
--- a/components/safety_check/safety_check.h
+++ b/components/safety_check/safety_check.h
@@ -24,6 +24,8 @@
   enum class PasswordsStatus {
     kChecking = 0,
     kSafe = 1,
+    // Indicates that at least one compromised password exists. Weak passwords
+    // may exist as well.
     kCompromisedExist = 2,
     kOffline = 3,
     kNoPasswords = 4,
@@ -31,8 +33,11 @@
     kQuotaLimit = 6,
     kError = 7,
     kFeatureUnavailable = 8,
+    // Indicates that no compromised passwords exist, but at least one weak
+    // password.
+    kWeakPasswordsExist = 9,
     // New enum values must go above here.
-    kMaxValue = kFeatureUnavailable,
+    kMaxValue = kWeakPasswordsExist,
   };
 
   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.safety_check
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java
index db98331..a8a81015 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/ProfileDataSource.java
@@ -86,11 +86,11 @@
     /**
      * Gets ProfileData for single account. There must be at least one active observer when this
      * method is invoked (see {@link #addObserver}).
-     * @param accountId account name to get ProfileData for.
+     * @param accountEmail account email to get ProfileData for.
      * @return ProfileData if there's any profile data for this account name, null otherwise.
      */
     @Nullable
-    ProfileData getProfileDataForAccount(String accountId);
+    ProfileData getProfileDataForAccount(String accountEmail);
 
     /**
      * Adds an observer to get notified about changes to profile data.
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java
index d1d0b1f7..ea5560f 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java
+++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java
@@ -31,9 +31,9 @@
     }
 
     @Override
-    public @Nullable ProfileData getProfileDataForAccount(String accountId) {
+    public @Nullable ProfileData getProfileDataForAccount(String accountEmail) {
         ThreadUtils.assertOnUiThread();
-        return mProfileDataMap.get(accountId);
+        return mProfileDataMap.get(accountEmail);
     }
 
     @Override
diff --git a/content/OWNERS b/content/OWNERS
index 8077f7a..0a780ba 100644
--- a/content/OWNERS
+++ b/content/OWNERS
@@ -13,6 +13,7 @@
 # to content-owners@chromium.org.
 
 alexmos@chromium.org
+arthursonzogni@chromium.org
 avi@chromium.org
 clamy@chromium.org
 creis@chromium.org
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 71c6590..568e124 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -194,8 +194,8 @@
   return false;
 }
 
-bool BrowserAccessibility::IsDocument() const {
-  return ui::IsDocument(GetRole());
+bool BrowserAccessibility::IsPlatformDocument() const {
+  return ui::IsPlatformDocument(GetRole());
 }
 
 bool BrowserAccessibility::IsIgnored() const {
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index 8f1b696..3004fa7d 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -107,7 +107,10 @@
   // Return true if this object is equal to or a descendant of |ancestor|.
   bool IsDescendantOf(const BrowserAccessibility* ancestor) const;
 
-  bool IsDocument() const;
+  // Returns true if this object is at the root of what most accessibility APIs
+  // consider to be a document, such as the root of a webpage, an iframe, or a
+  // PDF.
+  bool IsPlatformDocument() const;
 
   bool IsIgnored() const;
 
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index 530488305..aa9495d 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -895,7 +895,7 @@
   *num_children = owner()->PlatformChildCount();
   *unique_id = -AXPlatformNodeWin::GetUniqueId();
 
-  if (owner()->IsDocument()) {
+  if (owner()->IsPlatformDocument()) {
     *node_type = NODETYPE_DOCUMENT;
   } else if (owner()->IsText()) {
     *node_type = NODETYPE_TEXT;
@@ -1378,7 +1378,7 @@
       return E_NOINTERFACE;
     }
   } else if (iid == IID_ISimpleDOMDocument) {
-    if (!accessibility->IsDocument()) {
+    if (!accessibility->IsPlatformDocument()) {
       *object = nullptr;
       return E_NOINTERFACE;
     }
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index cc20e04..fd3eb2fa 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -247,7 +247,7 @@
           // Fire the event on the root object, which in the absence of a text
           // field ancestor is the closest UIA text provider (other than the
           // focused object) in which the selection has changed.
-          DCHECK(node->IsDocument());
+          DCHECK(node->IsPlatformDocument());
           EnqueueSelectionChangedEvent(*node);
         }
       }
@@ -911,7 +911,8 @@
     // IA2_EVENT_TEXT_CARET_MOVED events should not be fired on the document
     // object, just because a selection has been made within it, because they
     // would be both unnecessary and noisy.
-    if (!event_node->IsDocument() && event_node->HasVisibleCaretOrSelection()) {
+    if (!event_node->IsPlatformDocument() &&
+        event_node->HasVisibleCaretOrSelection()) {
       FireWinAccessibilityEvent(IA2_EVENT_TEXT_CARET_MOVED, event_node);
     }
     if (ToBrowserAccessibilityWin(event_node)
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index eef7298..4c1ef76 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -670,13 +670,13 @@
     const std::string& devtools_request_id,
     const net::CookieAccessResultList& request_cookie_list,
     const std::vector<network::mojom::HttpRawHeaderPairPtr>& request_headers,
-    network::mojom::ClientSecurityStatePtr security_state) {
+    const network::mojom::ClientSecurityStatePtr security_state) {
   FrameTreeNode* ftn = GetFtnForNetworkRequest(process_id, routing_id);
   if (ftn) {
     DispatchToAgents(ftn,
                      &protocol::NetworkHandler::OnRequestWillBeSentExtraInfo,
                      devtools_request_id, request_cookie_list, request_headers,
-                     std::move(security_state));
+                     security_state);
     return;
   }
 
@@ -689,7 +689,7 @@
       process_id, routing_id,
       &protocol::NetworkHandler::OnRequestWillBeSentExtraInfo,
       devtools_request_id, request_cookie_list, request_headers,
-      std::move(security_state));
+      security_state);
 }
 
 void OnResponseReceivedExtraInfo(
diff --git a/content/browser/devtools/devtools_instrumentation.h b/content/browser/devtools/devtools_instrumentation.h
index ec90cbb..5636489 100644
--- a/content/browser/devtools/devtools_instrumentation.h
+++ b/content/browser/devtools/devtools_instrumentation.h
@@ -148,7 +148,7 @@
     const std::string& devtools_request_id,
     const net::CookieAccessResultList& request_cookie_list,
     const std::vector<network::mojom::HttpRawHeaderPairPtr>& request_headers,
-    network::mojom::ClientSecurityStatePtr security_state);
+    const network::mojom::ClientSecurityStatePtr security_state);
 void OnResponseReceivedExtraInfo(
     int process_id,
     int routing_id,
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index a7a0b11..7085282 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -2476,7 +2476,7 @@
     const std::string& devtools_request_id,
     const net::CookieAccessResultList& request_cookie_list,
     const std::vector<network::mojom::HttpRawHeaderPairPtr>& request_headers,
-    network::mojom::ClientSecurityStatePtr security_state) {
+    const network::mojom::ClientSecurityStatePtr& security_state) {
   if (!enabled_)
     return;
 
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h
index 5931330..d03370b 100644
--- a/content/browser/devtools/protocol/network_handler.h
+++ b/content/browser/devtools/protocol/network_handler.h
@@ -207,7 +207,7 @@
       const std::string& devtools_request_id,
       const net::CookieAccessResultList& request_cookie_list,
       const std::vector<network::mojom::HttpRawHeaderPairPtr>& request_headers,
-      network::mojom::ClientSecurityStatePtr security_state);
+      const network::mojom::ClientSecurityStatePtr& security_state);
   void OnResponseReceivedExtraInfo(
       const std::string& devtools_request_id,
       const net::CookieAndLineAccessResultList& response_cookie_list,
diff --git a/content/browser/network_service_client.cc b/content/browser/network_service_client.cc
index aea430f1..44e8b72 100644
--- a/content/browser/network_service_client.cc
+++ b/content/browser/network_service_client.cc
@@ -260,4 +260,13 @@
       process_id, render_frame_id, devtools_request_id, status);
 }
 
+void NetworkServiceClient::OnTrustTokenOperationDone(
+    int32_t process_id,
+    int32_t routing_id,
+    const std::string& devtools_request_id,
+    network::mojom::TrustTokenOperationResultPtr result) {
+  // TODO(crbug.com/1126824): Implement by forwarding to a
+  //                          devtools_instrumentation method.
+}
+
 }  // namespace content
diff --git a/content/browser/network_service_client.h b/content/browser/network_service_client.h
index 1913533..6849c44 100644
--- a/content/browser/network_service_client.h
+++ b/content/browser/network_service_client.h
@@ -81,6 +81,12 @@
       const base::UnguessableToken& devtool_request_id,
       const network::URLLoaderCompletionStatus& status) override;
 
+  void OnTrustTokenOperationDone(
+      int32_t process_id,
+      int32_t routing_id,
+      const std::string& devtool_request_id,
+      network::mojom::TrustTokenOperationResultPtr result) override;
+
   // net::CertDatabase::Observer implementation:
   void OnCertDBChanged() override;
 
diff --git a/content/browser/renderer_host/media/peer_connection_tracker_host.cc b/content/browser/renderer_host/media/peer_connection_tracker_host.cc
index a1d323a..a95ae978 100644
--- a/content/browser/renderer_host/media/peer_connection_tracker_host.cc
+++ b/content/browser/renderer_host/media/peer_connection_tracker_host.cc
@@ -153,7 +153,8 @@
 void PeerConnectionTrackerHost::OnThermalStateChange(
     base::PowerObserver::DeviceThermalState new_state) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  tracker_->OnThermalStateChange(new_state);
+  tracker_->OnThermalStateChange(
+      static_cast<blink::mojom::DeviceThermalState>(new_state));
 }
 
 void PeerConnectionTrackerHost::StartEventLog(int lid, int output_period_ms) {
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 572e75a..5dbc564 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -81,6 +81,7 @@
     "$google_play_services_package:google_play_services_tasks_java",
     "//base:base_java",
     "//base:jni_java",
+    "//build:chromeos_buildflags",
     "//components/download/public/common:public_java",
     "//components/payments/mojom:mojom_java",
     "//content/public/common:trust_tokens_mojo_bindings_java",
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index c72a6f4..14c05b5ac 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/ui.gni")
 import("//device/vr/buildflags/buildflags.gni")
 import("//ppapi/buildflags/buildflags.gni")
@@ -474,7 +475,7 @@
     "//content/browser",
   ]
 
-  if (is_chromeos || is_android || is_chromecast || is_fuchsia) {
+  if (is_chromeos_ash || is_android || is_chromecast || is_fuchsia) {
     defines = [ "ENABLE_PROTECTED_MEDIA_IDENTIFIER_PERMISSION" ]
   }
 
@@ -529,7 +530,7 @@
     ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     sources += [
       "chromeos/delegate_to_browser_gpu_service_accelerator_factory.h",
       "tts_controller_delegate.cc",
diff --git a/content/public/browser/authenticator_request_client_delegate.cc b/content/public/browser/authenticator_request_client_delegate.cc
index 6024e64..bba28ef 100644
--- a/content/public/browser/authenticator_request_client_delegate.cc
+++ b/content/public/browser/authenticator_request_client_delegate.cc
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/strings/string_piece.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "device/fido/features.h"
 #include "device/fido/fido_discovery_factory.h"
 
@@ -88,7 +89,7 @@
 }
 #endif  // defined(OS_MAC)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 AuthenticatorRequestClientDelegate::ChromeOSGenerateRequestIdCallback
 AuthenticatorRequestClientDelegate::GetGenerateRequestIdCallback(
     RenderFrameHost* render_frame_host) {
diff --git a/content/public/browser/authenticator_request_client_delegate.h b/content/public/browser/authenticator_request_client_delegate.h
index 6f8417b0..8e91def 100644
--- a/content/public/browser/authenticator_request_client_delegate.h
+++ b/content/public/browser/authenticator_request_client_delegate.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/optional.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "content/common/content_export.h"
 #include "device/fido/authenticator_get_assertion_response.h"
 #include "device/fido/cable/cable_discovery_data.h"
@@ -33,7 +34,7 @@
 
 namespace content {
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 class RenderFrameHost;
 #endif
 
@@ -190,7 +191,7 @@
   GetTouchIdAuthenticatorConfig();
 #endif  // defined(OS_MAC)
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Callback that should generate and return a unique request id.
   using ChromeOSGenerateRequestIdCallback = base::RepeatingCallback<uint32_t()>;
 
@@ -201,7 +202,7 @@
   // request.
   virtual ChromeOSGenerateRequestIdCallback GetGenerateRequestIdCallback(
       RenderFrameHost* render_frame_host);
-#endif  // defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   // Returns a bool if the result of the isUserVerifyingPlatformAuthenticator
   // API call should be overridden with that value, or base::nullopt otherwise.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 2496f7c3..d108726 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -21,6 +21,7 @@
 #include "base/notreached.h"
 #include "base/sequenced_task_runner.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "content/public/browser/authenticator_request_client_delegate.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/browser_main_parts.h"
@@ -554,7 +555,7 @@
   return nullptr;
 }
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 TtsControllerDelegate* ContentBrowserClient::GetTtsControllerDelegate() {
   return nullptr;
 }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 13787b2..ea9b1324 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -24,6 +24,7 @@
 #include "base/time/time.h"
 #include "base/types/strong_alias.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "components/download/public/common/quarantine_connection.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/allow_service_worker_result.h"
@@ -227,7 +228,7 @@
 class TtsEnvironmentAndroid;
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 class TtsControllerDelegate;
 #endif
 
@@ -745,7 +746,7 @@
   virtual bool AllowConversionMeasurement(
       content::BrowserContext* browser_context);
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Notification that a trust anchor was used by the given user.
   virtual void OnTrustAnchorUsed(BrowserContext* browser_context) {}
 #endif
@@ -880,7 +881,7 @@
   virtual SpeechRecognitionManagerDelegate*
   CreateSpeechRecognitionManagerDelegate();
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Allows the embedder to return a delegate for the TtsController.
   virtual TtsControllerDelegate* GetTtsControllerDelegate();
 #endif
diff --git a/content/public/browser/desktop_capture.cc b/content/public/browser/desktop_capture.cc
index c57821ec..60065d1 100644
--- a/content/public/browser/desktop_capture.cc
+++ b/content/public/browser/desktop_capture.cc
@@ -9,7 +9,7 @@
 #include "build/chromeos_buildflags.h"
 #include "content/public/common/content_features.h"
 
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "content/browser/media/capture/desktop_capturer_lacros.h"
 #endif
 
@@ -44,7 +44,7 @@
 }
 
 std::unique_ptr<webrtc::DesktopCapturer> CreateScreenCapturer() {
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
   return std::make_unique<DesktopCapturerLacros>(
       DesktopCapturerLacros::CaptureType::kScreen,
       webrtc::DesktopCaptureOptions());
@@ -55,7 +55,7 @@
 }
 
 std::unique_ptr<webrtc::DesktopCapturer> CreateWindowCapturer() {
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
   return std::make_unique<DesktopCapturerLacros>(
       DesktopCapturerLacros::CaptureType::kWindow,
       webrtc::DesktopCaptureOptions());
diff --git a/content/public/browser/gpu_utils.cc b/content/public/browser/gpu_utils.cc
index 240407a..f8d9923 100644
--- a/content/public/browser/gpu_utils.cc
+++ b/content/public/browser/gpu_utils.cc
@@ -10,6 +10,7 @@
 #include "base/command_line.h"
 #include "base/single_thread_task_runner.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "cc/base/switches.h"
 #include "components/viz/common/features.h"
 #include "components/viz/common/switches.h"
@@ -120,7 +121,7 @@
   gpu_preferences.enable_native_gpu_memory_buffers =
       command_line->HasSwitch(switches::kEnableNativeGpuMemoryBuffers);
 
-#if BUILDFLAG(IS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
   // The direct VideoDecoder is disallowed on some particular SoC/platforms.
   const bool should_use_direct_video_decoder =
@@ -141,7 +142,7 @@
 #else   // !BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
   gpu_preferences.enable_chromeos_direct_video_decoder = false;
 #endif  // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
-#endif  // BUILDFLAG(IS_ASH)
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if defined(OS_ANDROID)
   gpu_preferences.disable_oopr_debug_crash_dump =
diff --git a/content/public/browser/is_uvpaa.h b/content/public/browser/is_uvpaa.h
index 6224427d..f7587f6 100644
--- a/content/public/browser/is_uvpaa.h
+++ b/content/public/browser/is_uvpaa.h
@@ -6,6 +6,7 @@
 #define CONTENT_PUBLIC_BROWSER_IS_UVPAA_H_
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/authenticator_request_client_delegate.h"
 
@@ -30,7 +31,7 @@
 #elif defined(OS_WIN)
 CONTENT_EXPORT bool IsUVPlatformAuthenticatorAvailable(device::WinWebAuthnApi*);
 
-#elif defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
 CONTENT_EXPORT bool IsUVPlatformAuthenticatorAvailable();
 
 #else
diff --git a/content/public/browser/media_keys_listener_manager.cc b/content/public/browser/media_keys_listener_manager.cc
index dbd922a8..0537a44 100644
--- a/content/public/browser/media_keys_listener_manager.cc
+++ b/content/public/browser/media_keys_listener_manager.cc
@@ -5,7 +5,7 @@
 #include "content/public/browser/media_keys_listener_manager.h"
 #include "build/chromeos_buildflags.h"
 
-#if !defined(OS_CHROMEOS)
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/feature_list.h"
 #include "media/base/media_switches.h"
 #endif
@@ -14,7 +14,7 @@
 
 // static
 bool MediaKeysListenerManager::IsMediaKeysListenerManagerEnabled() {
-#if defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
   return false;
 #else
   return base::FeatureList::IsEnabled(media::kHardwareMediaKeyHandling);
diff --git a/content/public/browser/network_context_client_base.h b/content/public/browser/network_context_client_base.h
index e03d0fc..b320398 100644
--- a/content/public/browser/network_context_client_base.h
+++ b/content/public/browser/network_context_client_base.h
@@ -6,6 +6,7 @@
 #define CONTENT_PUBLIC_BROWSER_NETWORK_CONTEXT_CLIENT_BASE_H_
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "content/common/content_export.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "services/network/public/mojom/network_context.mojom.h"
@@ -72,7 +73,7 @@
       const std::string& spn,
       OnGenerateHttpNegotiateAuthTokenCallback callback) override;
 #endif
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void OnTrustAnchorUsed() override;
 #endif
   void OnTrustTokenIssuanceDivertedToSystem(
diff --git a/content/public/browser/network_service_instance.h b/content/public/browser/network_service_instance.h
index 3ca5329af..a8c62a96 100644
--- a/content/public/browser/network_service_instance.h
+++ b/content/public/browser/network_service_instance.h
@@ -10,6 +10,7 @@
 #include "base/callback.h"
 #include "base/callback_list.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "content/common/content_export.h"
 #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom-forward.h"
 #include "services/network/public/cpp/network_connection_tracker.h"
@@ -41,7 +42,7 @@
 CONTENT_EXPORT network::mojom::NetworkService* GetNetworkService();
 
 // Only on ChromeOS since it's only used there.
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 // Returns the global NetworkChangeNotifier instance.
 CONTENT_EXPORT net::NetworkChangeNotifier* GetNetworkChangeNotifier();
 #endif
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index a95188e..626093b 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/buildflag_header.gni")
 import("//build/config/chromecast_build.gni")
+import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/features.gni")
 import("//build/config/ui.gni")
 import("//content/public/common/zygote/features.gni")
@@ -61,7 +62,10 @@
   public_configs = [ ":static_switches_defines" ]
 
   # Deps required by the above headers.
-  deps = [ "//media:media_buildflags" ]
+  deps = [
+    "//build:chromeos_buildflags",
+    "//media:media_buildflags",
+  ]
 }
 
 # This target allows you to use the content_features constants and statically
@@ -75,9 +79,11 @@
   ]
   public_deps = [ "//base" ]
 
+  deps = [ "//build:chromeos_buildflags" ]
+
   public_configs = [ ":static_switches_defines" ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     public_deps += [ "//media/capture/video/chromeos/public" ]
   }
 }
@@ -217,6 +223,7 @@
   deps = [
     ":content_descriptor_keys",
     "//build:branding_buildflags",
+    "//build:chromeos_buildflags",
 
     # This looks needless as we have //content/common in public_deps, but it's
     # needed because of allow_circular_includes_from.
@@ -250,7 +257,7 @@
     deps += [ "//content/public/android:jni" ]
   }
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     public_deps += [ "//media/capture/video/chromeos/public" ]
   }
 
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 6eb6475c..0115bd7 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -5,6 +5,7 @@
 #include "content/public/common/content_features.h"
 #include "base/feature_list.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
@@ -48,8 +49,10 @@
 // Runs the audio service in a separate process.
 const base::Feature kAudioServiceOutOfProcess {
   "AudioServiceOutOfProcess",
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
 #if defined(OS_WIN) || defined(OS_MAC) || \
-    (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+    (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
@@ -99,7 +102,7 @@
     "BlockInsecurePrivateNetworkRequests", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Use ThreadPriority::DISPLAY for browser UI and IO threads.
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#if defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
 const base::Feature kBrowserUseDisplayThreadPriority{
     "BrowserUseDisplayThreadPriority", base::FEATURE_ENABLED_BY_DEFAULT};
 #else
@@ -691,7 +694,7 @@
 // only enabled by default on CrOS.
 const base::Feature kTouchpadOverscrollHistoryNavigation {
   "TouchpadOverscrollHistoryNavigation",
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_WIN)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
@@ -780,7 +783,7 @@
 // disabled, an occluded WebContents behaves exactly like a VISIBLE WebContents.
 const base::Feature kWebContentsOcclusion {
   "WebContentsOcclusion",
-#if defined(OS_MAC) || defined(OS_CHROMEOS) || defined(OS_WIN)
+#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_WIN)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
@@ -797,7 +800,9 @@
 // https://w3c.github.io/webauthn
 const base::Feature kWebAuthCable {
   "WebAuthenticationCable",
-#if !defined(OS_CHROMEOS) && defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || defined(OS_LINUX)
       base::FEATURE_DISABLED_BY_DEFAULT
 #else
       base::FEATURE_ENABLED_BY_DEFAULT
@@ -969,7 +974,7 @@
 // On ChromeOS the service must run in the browser process, because parts of the
 // code depend on global objects that are only available in the Browser process.
 // See https://crbug.com/891961.
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#if defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
   return VideoCaptureServiceConfiguration::kEnabledForBrowserProcess;
 #else
 #if defined(OS_WIN)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 633ce423..9817ff08 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -5,6 +5,7 @@
 #include "content/public/common/content_switches.h"
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "media/media_buildflags.h"
 
 namespace switches {
@@ -890,7 +891,7 @@
 const char kDisableAcceleratedVideoDecode[] =
     "disable-accelerated-video-decode";
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
+#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(OS_ANDROID)
 // Enables hardware acceleration of video decoding on linux. (defaults to off)
 const char kEnableAcceleratedVideoDecode[] = "enable-accelerated-video-decode";
 #endif
@@ -954,7 +955,9 @@
 // Enable indication that browser is controlled by automation.
 const char kEnableAutomation[] = "enable-automation";
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 // Allows sending text-to-speech requests to speech-dispatcher, a common
 // Linux speech service. Because it's buggy, the user must explicitly
 // enable it so that visiting a random webpage can't cause instability.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index dbededb..d3ab2e9 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -8,6 +8,7 @@
 #define CONTENT_PUBLIC_COMMON_CONTENT_SWITCHES_H_
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "content/common/content_export.h"
 #include "media/media_buildflags.h"
 
@@ -244,7 +245,7 @@
 CONTENT_EXPORT extern const char kWebXrRuntimeOpenXr[];
 CONTENT_EXPORT extern const char kWebXrRuntimeWMR[];
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
+#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(OS_ANDROID)
 CONTENT_EXPORT extern const char kEnableAcceleratedVideoDecode[];
 #endif
 CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[];
@@ -265,7 +266,9 @@
 CONTENT_EXPORT extern const char kRendererWaitForJavaDebugger[];
 #endif
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 CONTENT_EXPORT extern const char kEnableSpeechDispatcher[];
 #endif
 
diff --git a/content/public/common/url_constants.cc b/content/public/common/url_constants.cc
index db7ce218..c95a381 100644
--- a/content/public/common/url_constants.cc
+++ b/content/public/common/url_constants.cc
@@ -5,6 +5,7 @@
 #include "content/public/common/url_constants.h"
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 
 namespace content {
 
@@ -16,7 +17,7 @@
 const char kChromeUIUntrustedScheme[] = "chrome-untrusted";
 const char kGuestScheme[] = "chrome-guest";
 const char kViewSourceScheme[] = "view-source";
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 const char kExternalFileScheme[] = "externalfile";
 #endif
 const char kGoogleChromeScheme[] = "googlechrome";
diff --git a/content/public/common/url_constants.h b/content/public/common/url_constants.h
index e554270..9083578 100644
--- a/content/public/common/url_constants.h
+++ b/content/public/common/url_constants.h
@@ -10,6 +10,8 @@
 #include "content/common/content_export.h"
 #include "url/url_constants.h"
 
+#include "build/chromeos_buildflags.h"
+
 // Contains constants for known URLs and portions thereof.
 
 namespace content {
@@ -23,7 +25,7 @@
 CONTENT_EXPORT extern const char kChromeUIUntrustedScheme[];
 CONTENT_EXPORT extern const char kGuestScheme[];
 CONTENT_EXPORT extern const char kViewSourceScheme[];
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 CONTENT_EXPORT extern const char kExternalFileScheme[];
 #endif
 
diff --git a/content/public/renderer/BUILD.gn b/content/public/renderer/BUILD.gn
index c7cda44..f9a92f1f 100644
--- a/content/public/renderer/BUILD.gn
+++ b/content/public/renderer/BUILD.gn
@@ -50,7 +50,6 @@
     "render_view_observer.h",
     "render_view_visitor.h",
     "renderer_ppapi_host.h",
-    "request_peer.h",
     "resource_dispatcher_delegate.h",
     "url_loader_throttle_provider.h",
     "v8_value_converter.h",
diff --git a/content/public/renderer/resource_dispatcher_delegate.h b/content/public/renderer/resource_dispatcher_delegate.h
index c255239..a033107 100644
--- a/content/public/renderer/resource_dispatcher_delegate.h
+++ b/content/public/renderer/resource_dispatcher_delegate.h
@@ -11,9 +11,11 @@
 
 class GURL;
 
-namespace content {
+namespace blink {
+class WebRequestPeer;
+}  // namespace blink
 
-class RequestPeer;
+namespace content {
 
 // Interface that allows observing request events and optionally replacing
 // the peer. Note that if it doesn't replace the peer it must return the
@@ -27,8 +29,8 @@
 
   // Note that |url|, |referrer| and |method| are the final values (e.g. after
   // any redirects).
-  virtual std::unique_ptr<RequestPeer> OnReceivedResponse(
-      std::unique_ptr<RequestPeer> current_peer,
+  virtual std::unique_ptr<blink::WebRequestPeer> OnReceivedResponse(
+      std::unique_ptr<blink::WebRequestPeer> current_peer,
       const std::string& mime_type,
       const GURL& url) = 0;
 };
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index 53b5d60..0002e7d 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -115,7 +115,7 @@
 #include "ui/aura/test/event_generator_delegate_aura.h"  // nogncheck
 #endif
 
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "base/files/file_path.h"
 #include "base/files/scoped_file.h"
 #include "chromeos/lacros/lacros_chrome_service_impl.h"
@@ -346,14 +346,14 @@
   use_software_gl = false;
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // If the test is running on the chromeos envrionment (such as
   // device or vm bots), we use hardware GL.
   if (base::SysInfo::IsRunningOnChromeOS())
     use_software_gl = false;
 #endif
 
-#if BUILDFLAG(IS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
   // If the test is running on the lacros environment, a file descriptor needs
   // to be obtained and used to launch lacros-chrome so that a mojo connection
   // between lacros-chrome and ash-chrome can be established.
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc
index 89441a39..92ccf32 100644
--- a/content/public/test/content_browser_test.cc
+++ b/content/public/test/content_browser_test.cc
@@ -10,6 +10,7 @@
 #include "base/run_loop.h"
 #include "base/task/current_thread.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_paths.h"
@@ -26,11 +27,13 @@
 #include "base/mac/foundation_util.h"
 #endif
 
-#if !defined(OS_CHROMEOS) && defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || defined(OS_LINUX)
 #include "ui/base/ime/init/input_method_initializer.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "content/public/test/network_connection_change_simulator.h"
 #endif
 
@@ -87,7 +90,9 @@
 #endif
 
   // LinuxInputMethodContextFactory has to be initialized.
-#if !defined(OS_CHROMEOS) && defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || defined(OS_LINUX)
   ui::InitializeInputMethodForTesting();
 #endif
 
@@ -100,13 +105,15 @@
   BrowserTestBase::TearDown();
 
   // LinuxInputMethodContextFactory has to be shutdown.
-#if !defined(OS_CHROMEOS) && defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
+// of lacros-chrome is complete.
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || defined(OS_LINUX)
   ui::ShutdownInputMethodForTesting();
 #endif
 }
 
 void ContentBrowserTest::PreRunTestOnMainThread() {
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   NetworkConnectionChangeSimulator network_change_simulator;
   network_change_simulator.InitializeChromeosConnectionType();
 #endif
diff --git a/content/public/test/network_connection_change_simulator.cc b/content/public/test/network_connection_change_simulator.cc
index 162b810..d22d290 100644
--- a/content/public/test/network_connection_change_simulator.cc
+++ b/content/public/test/network_connection_change_simulator.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/run_loop.h"
+#include "build/chromeos_buildflags.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/common/network_service_util.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -15,7 +16,7 @@
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "services/network/public/mojom/network_service_test.mojom.h"
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "net/base/network_change_notifier_posix.h"
 #include "services/network/public/mojom/network_service.mojom.h"
 #endif
@@ -34,7 +35,7 @@
 NetworkConnectionChangeSimulator::NetworkConnectionChangeSimulator() = default;
 NetworkConnectionChangeSimulator::~NetworkConnectionChangeSimulator() = default;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void NetworkConnectionChangeSimulator::InitializeChromeosConnectionType() {
   // Manually set the connection type since ChromeOS's NetworkChangeNotifier
   // implementation relies on some other class controlling it (normally
diff --git a/content/public/test/network_connection_change_simulator.h b/content/public/test/network_connection_change_simulator.h
index 32228854..717f177 100644
--- a/content/public/test/network_connection_change_simulator.h
+++ b/content/public/test/network_connection_change_simulator.h
@@ -6,6 +6,7 @@
 #define CONTENT_PUBLIC_TEST_NETWORK_CONNECTION_CHANGE_SIMULATOR_H_
 
 #include "base/macros.h"
+#include "build/chromeos_buildflags.h"
 #include "services/network/public/cpp/network_connection_tracker.h"
 
 namespace base {
@@ -21,7 +22,7 @@
   NetworkConnectionChangeSimulator();
   ~NetworkConnectionChangeSimulator() override;
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Initializes the ChromeOS network connection type.
   // This should be used in tests that don't have a DBus set up.
   void InitializeChromeosConnectionType();
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index dc9caa2..f177cae6 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -163,7 +163,7 @@
                        0));
   }
 
-  void SetDefersLoading(bool) override {}
+  void SetDefersLoading(DeferType) override {}
   void DidChangePriority(WebURLRequest::Priority, int) override {}
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForBodyLoader()
       override {
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index 4716112..c993d17 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -166,7 +166,7 @@
     *inner_image = obj;
   } else {
     // If we found something else with a name, fail.
-    if (!ui::IsDocument(obj.Role()) && !ui::IsLink(obj.Role())) {
+    if (!ui::IsPlatformDocument(obj.Role()) && !ui::IsLink(obj.Role())) {
       blink::WebString web_name = obj.GetName();
       if (!base::ContainsOnlyChars(web_name.Utf8(), base::kWhitespaceASCII)) {
         return false;
@@ -972,7 +972,7 @@
   // image (searching only to a max depth of 2), and the link doesn't have
   // accessible text from an attribute like aria-label, then annotate the
   // link/web area with the image's annotation, too.
-  if ((ui::IsLink(dst->role) || ui::IsDocument(dst->role)) &&
+  if ((ui::IsLink(dst->role) || ui::IsPlatformDocument(dst->role)) &&
       dst->GetNameFrom() != ax::mojom::NameFrom::kAttribute) {
     WebAXObject inner_image;
     if (FindExactlyOneInnerImageInMaxDepthThree(src, &inner_image))
diff --git a/content/renderer/loader/navigation_body_loader.cc b/content/renderer/loader/navigation_body_loader.cc
index 5a80a90..8422c31 100644
--- a/content/renderer/loader/navigation_body_loader.cc
+++ b/content/renderer/loader/navigation_body_loader.cc
@@ -183,10 +183,11 @@
   NotifyCompletionIfAppropriate();
 }
 
-void NavigationBodyLoader::SetDefersLoading(bool defers) {
-  if (is_deferred_ == defers)
+void NavigationBodyLoader::SetDefersLoading(
+    blink::WebURLLoader::DeferType defers) {
+  if (defer_type_ == defers)
     return;
-  is_deferred_ = defers;
+  defer_type_ = defers;
   if (handle_.is_valid())
     OnReadable(MOJO_RESULT_OK);
 }
@@ -251,7 +252,9 @@
 void NavigationBodyLoader::OnReadable(MojoResult unused) {
   TRACE_EVENT1("loading", "NavigationBodyLoader::OnReadable", "url",
                original_url_.possibly_invalid_spec());
-  if (has_seen_end_of_data_ || is_deferred_ || is_in_on_readable_)
+  if (has_seen_end_of_data_ ||
+      defer_type_ != blink::WebURLLoader::DeferType::kNotDeferred ||
+      is_in_on_readable_)
     return;
   // Protect against reentrancy:
   // - when the client calls SetDefersLoading;
@@ -271,7 +274,7 @@
   TRACE_EVENT1("loading", "NavigationBodyLoader::ReadFromDataPipe", "url",
                original_url_.possibly_invalid_spec());
   uint32_t num_bytes_consumed = 0;
-  while (!is_deferred_) {
+  while (defer_type_ == blink::WebURLLoader::DeferType::kNotDeferred) {
     const void* buffer = nullptr;
     uint32_t available = 0;
     MojoResult result =
diff --git a/content/renderer/loader/navigation_body_loader.h b/content/renderer/loader/navigation_body_loader.h
index 30e29c9b..f487cb7 100644
--- a/content/renderer/loader/navigation_body_loader.h
+++ b/content/renderer/loader/navigation_body_loader.h
@@ -106,7 +106,7 @@
           resource_load_info_notifier_wrapper);
 
   // blink::WebNavigationBodyLoader
-  void SetDefersLoading(bool defers) override;
+  void SetDefersLoading(blink::WebURLLoader::DeferType defers) override;
   void StartLoadingBody(WebNavigationBodyLoader::Client* client,
                         bool use_isolated_code_cache) override;
 
@@ -172,7 +172,8 @@
 
   // Deferred body loader does not send any notifications to the client
   // and tries not to read from the body pipe.
-  bool is_deferred_ = false;
+  blink::WebURLLoader::DeferType defer_type_ =
+      blink::WebURLLoader::DeferType::kNotDeferred;
 
   // This protects against reentrancy into OnReadable,
   // which can happen due to nested message loop triggered
diff --git a/content/renderer/loader/navigation_body_loader_unittest.cc b/content/renderer/loader/navigation_body_loader_unittest.cc
index 7624d3f..d751ec5 100644
--- a/content/renderer/loader/navigation_body_loader_unittest.cc
+++ b/content/renderer/loader/navigation_body_loader_unittest.cc
@@ -110,8 +110,8 @@
     }
     if (toggle_defers_loading_) {
       toggle_defers_loading_ = false;
-      loader_->SetDefersLoading(false);
-      loader_->SetDefersLoading(true);
+      loader_->SetDefersLoading(blink::WebURLLoader::DeferType::kNotDeferred);
+      loader_->SetDefersLoading(blink::WebURLLoader::DeferType::kDeferred);
     }
     if (destroy_loader_) {
       destroy_loader_ = false;
@@ -171,8 +171,8 @@
 
 TEST_F(NavigationBodyLoaderTest, SetDefersBeforeStart) {
   CreateBodyLoader();
-  loader_->SetDefersLoading(true);
-  loader_->SetDefersLoading(false);
+  loader_->SetDefersLoading(blink::WebURLLoader::DeferType::kDeferred);
+  loader_->SetDefersLoading(blink::WebURLLoader::DeferType::kNotDeferred);
   // Should not crash.
 }
 
@@ -217,11 +217,23 @@
 
 TEST_F(NavigationBodyLoaderTest, StartDeferred) {
   CreateBodyLoader();
-  loader_->SetDefersLoading(true);
+  loader_->SetDefersLoading(blink::WebURLLoader::DeferType::kDeferred);
   StartLoading();
   Write("hello");
   ExpectDataReceived();
-  loader_->SetDefersLoading(false);
+  loader_->SetDefersLoading(blink::WebURLLoader::DeferType::kNotDeferred);
+  Wait();
+  EXPECT_EQ("hello", TakeDataReceived());
+}
+
+TEST_F(NavigationBodyLoaderTest, StartDeferredWithBackForwardCache) {
+  CreateBodyLoader();
+  loader_->SetDefersLoading(
+      blink::WebURLLoader::DeferType::kDeferredWithBackForwardCache);
+  StartLoading();
+  Write("hello");
+  ExpectDataReceived();
+  loader_->SetDefersLoading(blink::WebURLLoader::DeferType::kNotDeferred);
   Wait();
   EXPECT_EQ("hello", TakeDataReceived());
 }
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc
index c11c0a99..d4b52b1 100644
--- a/content/renderer/loader/resource_dispatcher.cc
+++ b/content/renderer/loader/resource_dispatcher.cc
@@ -23,7 +23,6 @@
 #include "build/build_config.h"
 #include "content/common/inter_process_time_ticks_converter.h"
 #include "content/common/navigation_params.h"
-#include "content/public/renderer/request_peer.h"
 #include "content/public/renderer/resource_dispatcher_delegate.h"
 #include "content/renderer/loader/sync_load_context.h"
 #include "content/renderer/loader/url_loader_client_impl.h"
@@ -47,6 +46,7 @@
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
 #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
 #include "third_party/blink/public/platform/sync_load_response.h"
+#include "third_party/blink/public/platform/web_request_peer.h"
 
 namespace content {
 
@@ -155,9 +155,10 @@
   ToLocalURLResponseHead(*request_info, *response_head);
   request_info->load_timing_info = response_head->load_timing;
   if (delegate_) {
-    std::unique_ptr<RequestPeer> new_peer = delegate_->OnReceivedResponse(
-        std::move(request_info->peer), response_head->mime_type,
-        request_info->url);
+    std::unique_ptr<blink::WebRequestPeer> new_peer =
+        delegate_->OnReceivedResponse(std::move(request_info->peer),
+                                      response_head->mime_type,
+                                      request_info->url);
     DCHECK(new_peer);
     request_info->peer = std::move(new_peer);
   }
@@ -239,7 +240,8 @@
         ->NotifyResourceRedirectReceived(redirect_info,
                                          std::move(response_head));
 
-    if (!request_info->is_deferred)
+    if (request_info->is_deferred ==
+        blink::WebURLLoader::DeferType::kNotDeferred)
       FollowPendingRedirect(request_info);
   } else {
     Cancel(request_id, std::move(task_runner));
@@ -278,7 +280,7 @@
   request_info->resource_load_info_notifier_wrapper
       ->NotifyResourceLoadCompleted(status);
 
-  RequestPeer* peer = request_info->peer.get();
+  blink::WebRequestPeer* peer = request_info->peer.get();
 
   if (delegate_) {
     delegate_->OnRequestComplete();
@@ -358,18 +360,22 @@
   RemovePendingRequest(request_id, std::move(task_runner));
 }
 
-void ResourceDispatcher::SetDefersLoading(int request_id, bool value) {
+void ResourceDispatcher::SetDefersLoading(
+    int request_id,
+    blink::WebURLLoader::DeferType value) {
   PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
   if (!request_info) {
     DLOG(ERROR) << "unknown request";
     return;
   }
-  if (value) {
+  if (value != blink::WebURLLoader::DeferType::kNotDeferred) {
     request_info->is_deferred = value;
-    request_info->url_loader_client->SetDefersLoading();
-  } else if (request_info->is_deferred) {
-    request_info->is_deferred = false;
-    request_info->url_loader_client->UnsetDefersLoading();
+    request_info->url_loader_client->SetDefersLoading(value);
+  } else if (request_info->is_deferred !=
+             blink::WebURLLoader::DeferType::kNotDeferred) {
+    request_info->is_deferred = blink::WebURLLoader::DeferType::kNotDeferred;
+    request_info->url_loader_client->SetDefersLoading(
+        blink::WebURLLoader::DeferType::kNotDeferred);
 
     FollowPendingRedirect(request_info);
   }
@@ -395,7 +401,7 @@
     return;
 
   // TODO(yhirano): Consider using int64_t in
-  // RequestPeer::OnTransferSizeUpdated.
+  // blink::WebRequestPeer::OnTransferSizeUpdated.
   request_info->peer->OnTransferSizeUpdated(transfer_size_diff);
   if (!GetPendingRequestInfo(request_id))
     return;
@@ -409,7 +415,7 @@
 }
 
 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
-    std::unique_ptr<RequestPeer> peer,
+    std::unique_ptr<blink::WebRequestPeer> peer,
     network::mojom::RequestDestination request_destination,
     int render_frame_id,
     const GURL& request_url,
@@ -437,7 +443,7 @@
     std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
     base::TimeDelta timeout,
     mojo::PendingRemote<blink::mojom::BlobRegistry> download_to_blob_registry,
-    std::unique_ptr<RequestPeer> peer,
+    std::unique_ptr<blink::WebRequestPeer> peer,
     std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
         resource_load_info_notifier_wrapper) {
   CheckSchemeForReferrerPolicy(*request);
@@ -503,7 +509,7 @@
     scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
     const net::NetworkTrafficAnnotationTag& traffic_annotation,
     uint32_t loader_options,
-    std::unique_ptr<RequestPeer> peer,
+    std::unique_ptr<blink::WebRequestPeer> peer,
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
     std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
     std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
diff --git a/content/renderer/loader/resource_dispatcher.h b/content/renderer/loader/resource_dispatcher.h
index 592d8f4..1eaf54d 100644
--- a/content/renderer/loader/resource_dispatcher.h
+++ b/content/renderer/loader/resource_dispatcher.h
@@ -33,6 +33,7 @@
 #include "third_party/blink/public/mojom/blob/blob_registry.mojom-forward.h"
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "url/gurl.h"
 
@@ -41,6 +42,7 @@
 }
 
 namespace blink {
+class WebRequestPeer;
 class ResourceLoadInfoNotifierWrapper;
 class ThrottlingURLLoader;
 struct SyncLoadResponse;
@@ -59,7 +61,6 @@
 }
 
 namespace content {
-class RequestPeer;
 class ResourceDispatcherDelegate;
 class URLLoaderClientImpl;
 
@@ -104,7 +105,7 @@
       std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
       base::TimeDelta timeout,
       mojo::PendingRemote<blink::mojom::BlobRegistry> download_to_blob_registry,
-      std::unique_ptr<RequestPeer> peer,
+      std::unique_ptr<blink::WebRequestPeer> peer,
       std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
           resource_load_info_notifier_wrapper);
 
@@ -123,7 +124,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
       const net::NetworkTrafficAnnotationTag& traffic_annotation,
       uint32_t loader_options,
-      std::unique_ptr<RequestPeer> peer,
+      std::unique_ptr<blink::WebRequestPeer> peer,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
       std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
       std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
@@ -141,7 +142,8 @@
                       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   // Toggles the is_deferred attribute for the specified request.
-  virtual void SetDefersLoading(int request_id, bool value);
+  virtual void SetDefersLoading(int request_id,
+                                blink::WebURLLoader::DeferType value);
 
   // Indicates the priority of the specified request changed.
   void DidChangePriority(int request_id,
@@ -182,7 +184,7 @@
   friend class ResourceDispatcherTest;
 
   struct PendingRequestInfo {
-    PendingRequestInfo(std::unique_ptr<RequestPeer> peer,
+    PendingRequestInfo(std::unique_ptr<blink::WebRequestPeer> peer,
                        network::mojom::RequestDestination request_destination,
                        int render_frame_id,
                        const GURL& request_url,
@@ -191,10 +193,11 @@
 
     ~PendingRequestInfo();
 
-    std::unique_ptr<RequestPeer> peer;
+    std::unique_ptr<blink::WebRequestPeer> peer;
     network::mojom::RequestDestination request_destination;
     int render_frame_id;
-    bool is_deferred = false;
+    blink::WebURLLoader::DeferType is_deferred =
+        blink::WebURLLoader::DeferType::kNotDeferred;
     // Original requested url.
     GURL url;
     // The url, method and referrer of the latest response even in case of
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc
index e101ed1..6cff3509 100644
--- a/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -21,7 +21,6 @@
 #include "content/common/appcache_interfaces.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/referrer.h"
-#include "content/public/renderer/request_peer.h"
 #include "content/public/renderer/resource_dispatcher_delegate.h"
 #include "content/renderer/loader/test_request_peer.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -40,6 +39,7 @@
 #include "third_party/blink/public/common/loader/referrer_utils.h"
 #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/platform/web_request_peer.h"
 #include "third_party/blink/public/platform/web_url_request_extra_data.h"
 #include "url/gurl.h"
 
@@ -189,16 +189,16 @@
 
   void OnRequestComplete() override {}
 
-  std::unique_ptr<RequestPeer> OnReceivedResponse(
-      std::unique_ptr<RequestPeer> current_peer,
+  std::unique_ptr<blink::WebRequestPeer> OnReceivedResponse(
+      std::unique_ptr<blink::WebRequestPeer> current_peer,
       const std::string& mime_type,
       const GURL& url) override {
     return std::make_unique<WrapperPeer>(std::move(current_peer));
   }
 
-  class WrapperPeer : public RequestPeer {
+  class WrapperPeer : public blink::WebRequestPeer {
    public:
-    explicit WrapperPeer(std::unique_ptr<RequestPeer> original_peer)
+    explicit WrapperPeer(std::unique_ptr<blink::WebRequestPeer> original_peer)
         : original_peer_(std::move(original_peer)) {}
 
     void OnUploadProgress(uint64_t position, uint64_t size) override {}
@@ -228,7 +228,7 @@
     }
 
    private:
-    std::unique_ptr<RequestPeer> original_peer_;
+    std::unique_ptr<blink::WebRequestPeer> original_peer_;
     network::mojom::URLResponseHeadPtr response_head_;
     mojo::ScopedDataPipeConsumerHandle body_handle_;
 
diff --git a/content/renderer/loader/sync_load_context.cc b/content/renderer/loader/sync_load_context.cc
index e104af1..5fe479b 100644
--- a/content/renderer/loader/sync_load_context.cc
+++ b/content/renderer/loader/sync_load_context.cc
@@ -173,7 +173,8 @@
   response_->head = std::move(head);
   response_->redirect_info = redirect_info;
   *context_for_redirect_ = this;
-  resource_dispatcher_->SetDefersLoading(request_id_, true);
+  resource_dispatcher_->SetDefersLoading(
+      request_id_, blink::WebURLLoader::DeferType::kDeferred);
   signals_->SignalRedirectOrResponseComplete();
   return true;
 }
@@ -187,7 +188,8 @@
   response_->redirect_info = net::RedirectInfo();
   *context_for_redirect_ = nullptr;
 
-  resource_dispatcher_->SetDefersLoading(request_id_, false);
+  resource_dispatcher_->SetDefersLoading(
+      request_id_, blink::WebURLLoader::DeferType::kNotDeferred);
 }
 
 void SyncLoadContext::CancelRedirect() {
diff --git a/content/renderer/loader/sync_load_context.h b/content/renderer/loader/sync_load_context.h
index d68a156..6bb9f19 100644
--- a/content/renderer/loader/sync_load_context.h
+++ b/content/renderer/loader/sync_load_context.h
@@ -11,7 +11,6 @@
 #include "base/synchronization/waitable_event_watcher.h"
 #include "base/timer/timer.h"
 #include "content/common/content_export.h"
-#include "content/public/renderer/request_peer.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/data_pipe.h"
@@ -19,6 +18,7 @@
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
+#include "third_party/blink/public/platform/web_request_peer.h"
 
 namespace base {
 class WaitableEvent;
@@ -44,7 +44,7 @@
 //   2) kBlob: body is received on a data pipe passed on
 //      OnStartLoadingResponseBody(), and wraps the data pipe with a
 //      SerializedBlobPtr.
-class CONTENT_EXPORT SyncLoadContext : public RequestPeer {
+class CONTENT_EXPORT SyncLoadContext : public blink::WebRequestPeer {
  public:
   // Begins a new asynchronous request on whatever sequence this method is
   // called on. |completed_event| will be signalled when the request is complete
@@ -97,7 +97,7 @@
       mojo::PendingRemote<blink::mojom::BlobRegistry> download_to_blob_registry,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       const std::vector<std::string>& cors_exempt_header_list);
-  // RequestPeer implementation:
+  // blink::WebRequestPeer implementation:
   void OnUploadProgress(uint64_t position, uint64_t size) override;
   bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
                           network::mojom::URLResponseHeadPtr head,
diff --git a/content/renderer/loader/sync_load_context_unittest.cc b/content/renderer/loader/sync_load_context_unittest.cc
index 5c89221a..a1d23fea 100644
--- a/content/renderer/loader/sync_load_context_unittest.cc
+++ b/content/renderer/loader/sync_load_context_unittest.cc
@@ -71,7 +71,7 @@
 
 class MockResourceDispatcher : public ResourceDispatcher {
  public:
-  int CreatePendingRequest(std::unique_ptr<RequestPeer> peer) {
+  int CreatePendingRequest(std::unique_ptr<blink::WebRequestPeer> peer) {
     peers_.push_back(std::move(peer));
     return peers_.size() - 1;
   }
@@ -86,7 +86,7 @@
   }
 
  private:
-  std::vector<std::unique_ptr<RequestPeer>> peers_;
+  std::vector<std::unique_ptr<blink::WebRequestPeer>> peers_;
 };
 
 }  // namespace
diff --git a/content/renderer/loader/test_request_peer.cc b/content/renderer/loader/test_request_peer.cc
index 35fc75f..c45406f 100644
--- a/content/renderer/loader/test_request_peer.cc
+++ b/content/renderer/loader/test_request_peer.cc
@@ -31,7 +31,8 @@
   ++context_->seen_redirects;
   context_->last_load_timing = head->load_timing;
   if (context_->defer_on_redirect)
-    dispatcher_->SetDefersLoading(context_->request_id, true);
+    dispatcher_->SetDefersLoading(context_->request_id,
+                                  blink::WebURLLoader::DeferType::kDeferred);
   return context_->follow_redirects;
 }
 
@@ -66,7 +67,8 @@
     return;
   context_->total_encoded_data_length += transfer_size_diff;
   if (context_->defer_on_transfer_size_updated)
-    dispatcher_->SetDefersLoading(context_->request_id, true);
+    dispatcher_->SetDefersLoading(context_->request_id,
+                                  blink::WebURLLoader::DeferType::kDeferred);
 }
 
 void TestRequestPeer::OnReceivedCachedMetadata(mojo_base::BigBuffer data) {
diff --git a/content/renderer/loader/test_request_peer.h b/content/renderer/loader/test_request_peer.h
index 4543e84..5e0a68b 100644
--- a/content/renderer/loader/test_request_peer.h
+++ b/content/renderer/loader/test_request_peer.h
@@ -10,10 +10,10 @@
 #include <string>
 #include <vector>
 #include "base/time/time.h"
-#include "content/public/renderer/request_peer.h"
 #include "net/base/load_timing_info.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/url_response_head.mojom-forward.h"
+#include "third_party/blink/public/platform/web_request_peer.h"
 
 namespace net {
 struct RedirectInfo;
@@ -25,7 +25,7 @@
 
 // Listens for request response data and stores it so that it can be compared
 // to the reference data.
-class TestRequestPeer : public RequestPeer {
+class TestRequestPeer : public blink::WebRequestPeer {
  public:
   struct Context;
   TestRequestPeer(ResourceDispatcher* dispatcher, Context* context);
diff --git a/content/renderer/loader/url_loader_client_impl.cc b/content/renderer/loader/url_loader_client_impl.cc
index d7d47c7f..4185c3b 100644
--- a/content/renderer/loader/url_loader_client_impl.cc
+++ b/content/renderer/loader/url_loader_client_impl.cc
@@ -267,20 +267,18 @@
 
 URLLoaderClientImpl::~URLLoaderClientImpl() = default;
 
-void URLLoaderClientImpl::SetDefersLoading() {
-  is_deferred_ = true;
-}
-
-void URLLoaderClientImpl::UnsetDefersLoading() {
-  is_deferred_ = false;
-
-  task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&URLLoaderClientImpl::FlushDeferredMessages,
-                                weak_factory_.GetWeakPtr()));
+void URLLoaderClientImpl::SetDefersLoading(
+    blink::WebURLLoader::DeferType value) {
+  deferred_state_ = value;
+  if (value == blink::WebURLLoader::DeferType::kNotDeferred) {
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&URLLoaderClientImpl::FlushDeferredMessages,
+                                  weak_factory_.GetWeakPtr()));
+  }
 }
 
 void URLLoaderClientImpl::FlushDeferredMessages() {
-  if (is_deferred_)
+  if (deferred_state_ != blink::WebURLLoader::DeferType::kNotDeferred)
     return;
   std::vector<std::unique_ptr<DeferredMessage>> messages;
   messages.swap(deferred_messages_);
@@ -302,7 +300,7 @@
     messages[index]->HandleMessage(resource_dispatcher_, request_id_);
     if (!weak_this)
       return;
-    if (is_deferred_) {
+    if (deferred_state_ != blink::WebURLLoader::DeferType::kNotDeferred) {
       deferred_messages_.insert(
           deferred_messages_.begin(),
           std::make_move_iterator(messages.begin()) + index + 1,
@@ -319,7 +317,7 @@
                                                 transfer_size_diff);
     if (!weak_this)
       return;
-    if (is_deferred_) {
+    if (deferred_state_ != blink::WebURLLoader::DeferType::kNotDeferred) {
       if (has_completion_message) {
         DCHECK_GT(messages.size(), 0u);
         DCHECK(messages.back()->IsCompletionMessage());
@@ -376,6 +374,15 @@
     const net::RedirectInfo& redirect_info,
     network::mojom::URLResponseHeadPtr response_head) {
   DCHECK(!has_received_response_head_);
+  if (deferred_state_ ==
+      blink::WebURLLoader::DeferType::kDeferredWithBackForwardCache) {
+    // TODO(yuzus): Evict here.
+    // Close the connections and disptach and OnComplete message.
+    url_loader_.reset();
+    url_loader_client_receiver_.reset();
+    OnComplete(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+    return;
+  }
   if (!bypass_redirect_checks_ &&
       !IsRedirectSafe(last_loaded_url_, redirect_info.new_url)) {
     OnComplete(network::URLLoaderCompletionStatus(net::ERR_UNSAFE_REDIRECT));
@@ -492,14 +499,15 @@
 }
 
 bool URLLoaderClientImpl::NeedsStoringMessage() const {
-  return is_deferred_ || deferred_messages_.size() > 0 ||
+  return deferred_state_ != blink::WebURLLoader::DeferType::kNotDeferred ||
+         deferred_messages_.size() > 0 ||
          accumulated_transfer_size_diff_during_deferred_ > 0;
 }
 
 void URLLoaderClientImpl::StoreAndDispatch(
     std::unique_ptr<DeferredMessage> message) {
   DCHECK(NeedsStoringMessage());
-  if (is_deferred_) {
+  if (deferred_state_ != blink::WebURLLoader::DeferType::kNotDeferred) {
     deferred_messages_.push_back(std::move(message));
   } else if (deferred_messages_.size() > 0 ||
              accumulated_transfer_size_diff_during_deferred_ > 0) {
diff --git a/content/renderer/loader/url_loader_client_impl.h b/content/renderer/loader/url_loader_client_impl.h
index 5fb24d0..aa2af3b7 100644
--- a/content/renderer/loader/url_loader_client_impl.h
+++ b/content/renderer/loader/url_loader_client_impl.h
@@ -17,6 +17,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -43,12 +44,9 @@
                       const GURL& request_url);
   ~URLLoaderClientImpl() override;
 
-  // Sets |is_deferred_|. From now, the received messages are not dispatched
-  // to clients until UnsetDefersLoading is called.
-  void SetDefersLoading();
-
-  // Unsets |is_deferred_|.
-  void UnsetDefersLoading();
+  // Set the defer status. If loading is deferred, received messages are not
+  // dispatched to clients until it is set not deferred.
+  void SetDefersLoading(blink::WebURLLoader::DeferType value);
 
   // Dispatches the messages received after SetDefersLoading is called.
   void FlushDeferredMessages();
@@ -98,7 +96,8 @@
   bool has_received_response_head_ = false;
   bool has_received_response_body_ = false;
   bool has_received_complete_ = false;
-  bool is_deferred_ = false;
+  blink::WebURLLoader::DeferType deferred_state_ =
+      blink::WebURLLoader::DeferType::kNotDeferred;
   int32_t accumulated_transfer_size_diff_during_deferred_ = 0;
   ResourceDispatcher* const resource_dispatcher_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/content/renderer/loader/url_loader_client_impl_unittest.cc b/content/renderer/loader/url_loader_client_impl_unittest.cc
index fa40bba..4c50081 100644
--- a/content/renderer/loader/url_loader_client_impl_unittest.cc
+++ b/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -270,13 +270,15 @@
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
 
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
 
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
 
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
 
@@ -305,14 +307,16 @@
   EXPECT_FALSE(request_peer_context_.complete);
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
 
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
 
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
 
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
@@ -326,7 +330,8 @@
 TEST_P(URLLoaderClientImplTest, StoppedDeferringBeforeClosing) {
   // Call OnReceiveResponse, OnStartLoadingResponseBody, OnComplete while
   // deferred.
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New());
   mojo::ScopedDataPipeProducerHandle producer_handle;
   mojo::ScopedDataPipeConsumerHandle consumer_handle;
@@ -353,7 +358,8 @@
 
   // Stop deferring. OnComplete message shouldn't be dispatched yet because
   // we're still waiting for the response body pipe to be closed.
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(request_peer_context_.received_response);
   // When the body is buffered, we'll wait until the pipe is closed before
@@ -383,7 +389,8 @@
 TEST_P(URLLoaderClientImplTest, DeferBodyWithoutOnComplete) {
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New());
   // Call OnStartLoadingResponseBody while deferred.
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
   mojo::ScopedDataPipeProducerHandle producer_handle;
   mojo::ScopedDataPipeConsumerHandle consumer_handle;
   ASSERT_EQ(MOJO_RESULT_OK,
@@ -406,7 +413,8 @@
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
 
   // Stop deferring.
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
@@ -423,7 +431,8 @@
 TEST_P(URLLoaderClientImplTest, DeferredWithLongResponseBody) {
   // Call OnReceiveResponse, OnStartLoadingResponseBody, OnComplete while
   // deferred.
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
   url_loader_client_->OnReceiveResponse(network::mojom::URLResponseHead::New());
   mojo::ScopedDataPipeProducerHandle producer_handle;
   mojo::ScopedDataPipeConsumerHandle consumer_handle;
@@ -468,7 +477,8 @@
   producer_handle.reset();
 
   // Stop deferring.
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(request_peer_context_.received_response);
   // When the body is buffered, BodyBuffer shouldn't be finished writing to the
@@ -513,7 +523,8 @@
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
 
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
 
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(request_peer_context_.received_response);
@@ -521,7 +532,8 @@
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
 
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
@@ -562,7 +574,8 @@
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
 
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
 
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, request_peer_context_.seen_redirects);
@@ -571,7 +584,8 @@
   EXPECT_EQ("", GetRequestPeerContextBody(&request_peer_context_));
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
 
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   EXPECT_EQ(0, request_peer_context_.seen_redirects);
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
@@ -586,7 +600,8 @@
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
   EXPECT_FALSE(request_peer_context_.cancelled);
 
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, request_peer_context_.seen_redirects);
   EXPECT_TRUE(request_peer_context_.received_response);
@@ -615,14 +630,16 @@
   EXPECT_FALSE(request_peer_context_.complete);
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
 
-  dispatcher_->SetDefersLoading(request_id_, true);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kDeferred);
 
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
 
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   EXPECT_FALSE(request_peer_context_.received_response);
   EXPECT_FALSE(request_peer_context_.complete);
   EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
@@ -633,7 +650,8 @@
   EXPECT_EQ(4, request_peer_context_.total_encoded_data_length);
   EXPECT_FALSE(request_peer_context_.cancelled);
 
-  dispatcher_->SetDefersLoading(request_id_, false);
+  dispatcher_->SetDefersLoading(request_id_,
+                                blink::WebURLLoader::DeferType::kNotDeferred);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(request_peer_context_.received_response);
   EXPECT_TRUE(request_peer_context_.complete);
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index e1b671e..a3a0c20 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -35,7 +35,6 @@
 #include "content/public/common/content_constants.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/navigation_policy.h"
-#include "content/public/renderer/request_peer.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "content/renderer/variations_render_thread_observer.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -79,6 +78,7 @@
 #include "third_party/blink/public/platform/sync_load_response.h"
 #include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/platform/web_http_load_info.h"
+#include "third_party/blink/public/platform/web_request_peer.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
 #include "third_party/blink/public/platform/web_url.h"
 #include "third_party/blink/public/platform/web_url_error.h"
@@ -387,7 +387,7 @@
   }
 
   void Cancel();
-  void SetDefersLoading(bool value);
+  void SetDefersLoading(WebURLLoader::DeferType value);
   void DidChangePriority(WebURLRequest::Priority new_priority,
                          int intra_priority_value);
   void Start(
@@ -455,8 +455,7 @@
   scoped_refptr<base::SingleThreadTaskRunner> freezable_task_runner_;
   scoped_refptr<base::SingleThreadTaskRunner> unfreezable_task_runner_;
   mojo::PendingRemote<blink::mojom::KeepAliveHandle> keep_alive_handle_;
-  enum DeferState { NOT_DEFERRING, SHOULD_DEFER };
-  DeferState defers_loading_;
+  blink::WebURLLoader::DeferType defers_loading_;
   int request_id_;
   bool in_two_phase_read_ = false;
   bool is_in_on_body_available_ = false;
@@ -469,11 +468,11 @@
 // A thin wrapper class for Context to ensure its lifetime while it is
 // handling IPC messages coming from ResourceDispatcher. Owns one ref to
 // Context and held by ResourceDispatcher.
-class WebURLLoaderImpl::RequestPeerImpl : public RequestPeer {
+class WebURLLoaderImpl::RequestPeerImpl : public blink::WebRequestPeer {
  public:
   explicit RequestPeerImpl(Context* context);
 
-  // RequestPeer methods:
+  // blink::WebRequestPeer methods:
   void OnUploadProgress(uint64_t position, uint64_t size) override;
   bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
                           network::mojom::URLResponseHeadPtr head,
@@ -516,7 +515,7 @@
       unfreezable_task_runner_(
           unfreezable_task_runner_handle_->GetTaskRunner()),
       keep_alive_handle_(std::move(keep_alive_handle)),
-      defers_loading_(NOT_DEFERRING),
+      defers_loading_(blink::WebURLLoader::DeferType::kNotDeferred),
       request_id_(-1),
       url_loader_factory_(std::move(url_loader_factory)) {
   DCHECK(resource_dispatcher_);
@@ -536,14 +535,11 @@
   loader_ = nullptr;
 }
 
-void WebURLLoaderImpl::Context::SetDefersLoading(bool value) {
+void WebURLLoaderImpl::Context::SetDefersLoading(
+    WebURLLoader::DeferType value) {
   if (request_id_ != -1)
     resource_dispatcher_->SetDefersLoading(request_id_, value);
-  if (value && defers_loading_ == NOT_DEFERRING) {
-    defers_loading_ = SHOULD_DEFER;
-  } else if (!value && defers_loading_ != NOT_DEFERRING) {
-    defers_loading_ = NOT_DEFERRING;
-  }
+  defers_loading_ = value;
 }
 
 void WebURLLoaderImpl::Context::DidChangePriority(
@@ -640,7 +636,7 @@
   }
 
   if (sync_load_response) {
-    DCHECK(defers_loading_ == NOT_DEFERRING);
+    DCHECK(defers_loading_ == blink::WebURLLoader::DeferType::kNotDeferred);
 
     loader_options |= network::mojom::kURLLoadOptionSynchronous;
     request->load_flags |= net::LOAD_IGNORE_LIMITS;
@@ -667,8 +663,9 @@
       url_loader_factory_, std::move(throttles),
       std::move(resource_load_info_notifier_wrapper));
 
-  if (defers_loading_ != NOT_DEFERRING)
-    resource_dispatcher_->SetDefersLoading(request_id_, true);
+  if (defers_loading_ != blink::WebURLLoader::DeferType::kNotDeferred)
+    resource_dispatcher_->SetDefersLoading(
+        request_id_, blink::WebURLLoader::DeferType::kDeferred);
 }
 
 void WebURLLoaderImpl::Context::OnUploadProgress(uint64_t position,
@@ -1118,7 +1115,7 @@
   context_->Cancel();
 }
 
-void WebURLLoaderImpl::SetDefersLoading(bool value) {
+void WebURLLoaderImpl::SetDefersLoading(DeferType value) {
   context_->SetDefersLoading(value);
 }
 
diff --git a/content/renderer/loader/web_url_loader_impl.h b/content/renderer/loader/web_url_loader_impl.h
index 3b9131e..883a088 100644
--- a/content/renderer/loader/web_url_loader_impl.h
+++ b/content/renderer/loader/web_url_loader_impl.h
@@ -102,7 +102,7 @@
       std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
           resource_load_info_notifier_wrapper,
       blink::WebURLLoaderClient* client) override;
-  void SetDefersLoading(bool value) override;
+  void SetDefersLoading(DeferType value) override;
   void DidChangePriority(blink::WebURLRequest::Priority new_priority,
                          int intra_priority_value) override;
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForBodyLoader()
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc
index b9eb785..c0f17895 100644
--- a/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -19,7 +19,6 @@
 #include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/renderer/request_peer.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
@@ -40,9 +39,11 @@
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/sync_load_response.h"
 #include "third_party/blink/public/platform/web_data.h"
+#include "third_party/blink/public/platform/web_request_peer.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_url.h"
 #include "third_party/blink/public/platform/web_url_error.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/public/platform/web_url_loader_client.h"
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/public/platform/web_url_request_extra_data.h"
@@ -76,7 +77,7 @@
       std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
       base::TimeDelta timeout,
       mojo::PendingRemote<blink::mojom::BlobRegistry> download_to_blob_registry,
-      std::unique_ptr<RequestPeer> peer,
+      std::unique_ptr<blink::WebRequestPeer> peer,
       std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
           resource_load_info_notifier_wrapper) override {
     *response = std::move(sync_load_response_);
@@ -88,7 +89,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
       const net::NetworkTrafficAnnotationTag& traffic_annotation,
       uint32_t loader_options,
-      std::unique_ptr<RequestPeer> peer,
+      std::unique_ptr<blink::WebRequestPeer> peer,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
       std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
       std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
@@ -108,15 +109,16 @@
     canceled_ = true;
   }
 
-  RequestPeer* peer() { return peer_.get(); }
+  blink::WebRequestPeer* peer() { return peer_.get(); }
 
   bool canceled() { return canceled_; }
 
   const GURL& url() { return url_; }
   const GURL& stream_url() { return stream_url_; }
 
-  void SetDefersLoading(int request_id, bool value) override {
-    defers_loading_ = value;
+  void SetDefersLoading(int request_id,
+                        blink::WebURLLoader::DeferType value) override {
+    defers_loading_ = (value != blink::WebURLLoader::DeferType::kNotDeferred);
   }
   bool defers_loading() const { return defers_loading_; }
 
@@ -125,7 +127,7 @@
   }
 
  private:
-  std::unique_ptr<RequestPeer> peer_;
+  std::unique_ptr<blink::WebRequestPeer> peer_;
   bool canceled_;
   bool defers_loading_;
   GURL url_;
@@ -393,7 +395,7 @@
 
   TestWebURLLoaderClient* client() { return client_.get(); }
   TestResourceDispatcher* dispatcher() { return &dispatcher_; }
-  RequestPeer* peer() { return dispatcher()->peer(); }
+  blink::WebRequestPeer* peer() { return dispatcher()->peer(); }
 
  private:
   base::test::SingleThreadTaskEnvironment task_environment_;
@@ -460,7 +462,8 @@
 }
 
 TEST_F(WebURLLoaderImplTest, DefersLoadingBeforeStart) {
-  client()->loader()->SetDefersLoading(true);
+  client()->loader()->SetDefersLoading(
+      blink::WebURLLoader::DeferType::kDeferred);
   EXPECT_FALSE(dispatcher()->defers_loading());
   DoStartAsyncRequest();
   EXPECT_TRUE(dispatcher()->defers_loading());
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 3598250..8d69eb3 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -749,6 +749,7 @@
     "//base:i18n",
     "//base/test:test_config",
     "//base/test:test_support",
+    "//build:chromeos_buildflags",
     "//components/network_session_configurator/common:common",
     "//content/app:for_content_tests",
     "//content/browser:for_content_tests",
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 882e94c..1850c83 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -118,6 +118,12 @@
 crbug.com/1082533 [ win angle-vulkan passthrough ] conformance/textures/misc/texture-copying-and-deletion.html [ Failure ]
 crbug.com/1018028 [ win angle-vulkan ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
 crbug.com/angleproject/5038 conformance/extensions/ext-color-buffer-half-float.html [ Skip ]
+# TODO(crbug.com/1136231): Uncomment suppression for s3tc-and-rgtc.html below
+# under crbug.com/963205 once these two failures are fixed.
+crbug.com/1136231 [ win ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
+crbug.com/1136231 [ linux ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
+crbug.com/1152259 [ win ] conformance/reading/read-pixels-test.html [ Failure ]
+crbug.com/1152259 [ linux ] conformance/reading/read-pixels-test.html [ Failure ]
 
 crbug.com/953120 conformance/programs/program-handling.html [ Failure ]
 
@@ -256,7 +262,7 @@
 crbug.com/1073613 [ angle-d3d11 win nvidia-0x2184 ] deqp/functional/gles3/shadertexturefunction/texturesize.html [ Failure ]
 
 # WIN / OpenGL / NVIDIA failures
-crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/webgl-compressed-texture-s3tc.html [ RetryOnFailure ]
+# crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/s3tc-and-rgtc.html [ RetryOnFailure ]
 crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/webgl-compressed-texture-s3tc-srgb.html [ RetryOnFailure ]
 crbug.com/715001 [ angle-opengl win nvidia                    ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
 crbug.com/703779 [ angle-opengl win nvidia                    ] conformance/textures/misc/texture-size.html [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 7a66957..01c413b 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -201,6 +201,12 @@
 crbug.com/1082533 [ mac intel ] conformance/textures/misc/texture-copying-and-deletion.html [ Failure ]
 crbug.com/1018028 [ win angle-vulkan nvidia ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
 crbug.com/1110111 [ win nvidia ] conformance/rendering/point-no-attributes.html [ RetryOnFailure ]
+# TODO(crbug.com/1136231): Uncomment suppressions for s3tc-and-rgtc.html below
+# under crbug.com/963205 and crbug.com/964321 once these two failures are fixed.
+crbug.com/1136231 [ win ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
+crbug.com/1136231 [ linux ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
+crbug.com/1152259 [ win ] conformance/reading/read-pixels-test.html [ Failure ]
+crbug.com/1152259 [ linux ] conformance/reading/read-pixels-test.html [ Failure ]
 
 # Skipping new tests
 crbug.com/angleproject/5038 conformance/extensions/ext-color-buffer-half-float.html [ Skip ]
@@ -376,7 +382,7 @@
 # WIN / OpenGL / NVIDIA failures
 crbug.com/715001 [ win nvidia angle-opengl passthrough ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
 crbug.com/703779 [ win nvidia angle-opengl ] conformance/textures/misc/texture-size.html [ Failure ]
-crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/webgl-compressed-texture-s3tc.html [ RetryOnFailure ]
+# crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/s3tc-and-rgtc.html [ RetryOnFailure ]
 crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/webgl-compressed-texture-s3tc-srgb.html [ RetryOnFailure ]
 
 # Mark ANGLE's OpenGL as flaky on Windows Nvidia
@@ -404,7 +410,7 @@
 
 # Vulkan / Win / NVIDIA / Passthrough command decoder
 crbug.com/963205 [ win nvidia angle-vulkan passthrough ] conformance/extensions/webgl-compressed-texture-s3tc-srgb.html [ Failure ]
-crbug.com/964321 [ win nvidia angle-vulkan passthrough ] conformance/extensions/webgl-compressed-texture-s3tc.html [ RetryOnFailure ]
+# crbug.com/964321 [ win nvidia angle-vulkan passthrough ] conformance/extensions/s3tc-and-rgtc.html [ RetryOnFailure ]
 crbug.com/1051576 [ win nvidia angle-vulkan passthrough ] conformance/extensions/webgl-compressed-texture-size-limit.html [ Failure ]
 crbug.com/963217 [ win nvidia angle-vulkan passthrough ] conformance/glsl/samplers/glsl-function-texture2dprojlod.html [ Failure ]
 crbug.com/angleproject/3883 [ win nvidia angle-vulkan passthrough ] conformance/misc/uninitialized-test.html [ Failure ]
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_revision.txt b/content/test/gpu/gpu_tests/webgl_conformance_revision.txt
index 1a992b1..a4bc397 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_revision.txt
+++ b/content/test/gpu/gpu_tests/webgl_conformance_revision.txt
@@ -1,3 +1,3 @@
 # AUTOGENERATED FILE - DO NOT EDIT
 # SEE roll_webgl_conformance.py
-Current webgl revision 1a111c2adcb4898655aacaca018d6e275172760b
+Current webgl revision 3e3f152617996e4a175fd0b597a1936824b371f3
diff --git a/docs/clang_sheriffing.md b/docs/clang_sheriffing.md
index 4cf52f3..3cfccbd 100644
--- a/docs/clang_sheriffing.md
+++ b/docs/clang_sheriffing.md
@@ -14,19 +14,19 @@
 change, filing bugs upstream, and often reverting bad changes in LLVM. This
 document describes some of the processes and techniques for doing that.
 
-Some may find the [sheriff-o-matic]
-(https://sheriff-o-matic.appspot.com/chromium.clang) view of the waterfall
-easier to work with.
+Some may find the
+[sheriff-o-matic](https://sheriff-o-matic.appspot.com/chromium.clang)
+view of the waterfall easier to work with.
 
-To keep others informed, [file a bug]
-(https://bugs.chromium.org/p/chromium/issues/entry) .
+To keep others informed, [file a
+bug](https://bugs.chromium.org/p/chromium/issues/entry).
 earlier rather than later for build breaks likely caused by changes in
 clang or the rest fo the toolchain. Make sure to set the component field to
 `Tools > LLVM`, which will include the entire Chrome toolchain (Lexan) team.
 
 At the beginning of your sheriff rotation, it may be
-useful to [search for recent bot breaks]
-(https://bugs.chromium.org/p/chromium/issues/list?q=component%3ATools%3ELLVM&can=2&sort=-modified).
+useful to [search for recent bot
+breaks](https://bugs.chromium.org/p/chromium/issues/list?q=component%3ATools%3ELLVM&can=2&sort=-modified).
 We prefer searching like this to having sheriffs compose status email at the
 end of their week.
 
diff --git a/docs/speed/perf_regression_sheriffing.md b/docs/speed/perf_regression_sheriffing.md
index 33375a0..a4cdf79 100644
--- a/docs/speed/perf_regression_sheriffing.md
+++ b/docs/speed/perf_regression_sheriffing.md
@@ -62,9 +62,10 @@
 ## Follow up on Performance Regressions
 
 Please spend any spare time driving down bugs from the [regression
-backlog](http://go/triage-backlog). Treat these bugs as you would your own --
-investigate the regressions, find out what the next step should be, and then
-move the bug along. Some possible next steps and questions to answer are:
+backlog](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=Performance%3DSheriff+Type%3ABug+modified-before%3Atoday-6&sort=-modified).
+Treat these bugs as you would your own -- investigate the regressions, find out
+what the next step should be, and then move the bug along. Some possible next steps
+and questions to answer are:
 
 * Should the bug be closed?
 * Are there questions that need to be answered?
diff --git a/extensions/renderer/api/automation/automation_position.cc b/extensions/renderer/api/automation/automation_position.cc
index abfb5f5..8399625 100644
--- a/extensions/renderer/api/automation/automation_position.cc
+++ b/extensions/renderer/api/automation/automation_position.cc
@@ -48,8 +48,8 @@
       .SetMethod("atEndOfPage", &AutomationPosition::AtEndOfPage)
       .SetMethod("atStartOfFormat", &AutomationPosition::AtStartOfFormat)
       .SetMethod("atEndOfFormat", &AutomationPosition::AtEndOfFormat)
-      .SetMethod("atStartOfDocument", &AutomationPosition::AtStartOfDocument)
-      .SetMethod("atEndOfDocument", &AutomationPosition::AtEndOfDocument)
+      .SetMethod("atStartOfContent", &AutomationPosition::AtStartOfContent)
+      .SetMethod("atEndOfContent", &AutomationPosition::AtEndOfContent)
       .SetMethod("asTreePosition", &AutomationPosition::AsTreePosition)
       .SetMethod("asTextPosition", &AutomationPosition::AsTextPosition)
       .SetMethod("asLeafTextPosition", &AutomationPosition::AsLeafTextPosition)
@@ -57,10 +57,10 @@
                  &AutomationPosition::MoveToPositionAtStartOfAnchor)
       .SetMethod("moveToPositionAtEndOfAnchor",
                  &AutomationPosition::MoveToPositionAtEndOfAnchor)
-      .SetMethod("moveToPositionAtStartOfDocument",
-                 &AutomationPosition::MoveToPositionAtStartOfDocument)
-      .SetMethod("moveToPositionAtEndOfDocument",
-                 &AutomationPosition::MoveToPositionAtEndOfDocument)
+      .SetMethod("moveToPositionAtStartOfContent",
+                 &AutomationPosition::MoveToPositionAtStartOfContent)
+      .SetMethod("moveToPositionAtEndOfContent",
+                 &AutomationPosition::MoveToPositionAtEndOfContent)
       .SetMethod("moveToParentPosition",
                  &AutomationPosition::MoveToParentPosition)
       .SetMethod("moveToNextLeafTreePosition",
@@ -207,12 +207,12 @@
   return position_->AtEndOfFormat();
 }
 
-bool AutomationPosition::AtStartOfDocument(gin::Arguments* arguments) {
-  return position_->AtStartOfDocument();
+bool AutomationPosition::AtStartOfContent(gin::Arguments* arguments) {
+  return position_->AtStartOfContent();
 }
 
-bool AutomationPosition::AtEndOfDocument(gin::Arguments* arguments) {
-  return position_->AtEndOfDocument();
+bool AutomationPosition::AtEndOfContent(gin::Arguments* arguments) {
+  return position_->AtEndOfContent();
 }
 
 void AutomationPosition::AsTreePosition(gin::Arguments* arguments) {
@@ -237,14 +237,14 @@
   position_ = position_->CreatePositionAtEndOfAnchor();
 }
 
-void AutomationPosition::MoveToPositionAtStartOfDocument(
+void AutomationPosition::MoveToPositionAtStartOfContent(
     gin::Arguments* arguments) {
-  position_ = position_->CreatePositionAtStartOfDocument();
+  position_ = position_->CreatePositionAtStartOfContent();
 }
 
-void AutomationPosition::MoveToPositionAtEndOfDocument(
+void AutomationPosition::MoveToPositionAtEndOfContent(
     gin::Arguments* arguments) {
-  position_ = position_->CreatePositionAtEndOfDocument();
+  position_ = position_->CreatePositionAtEndOfContent();
 }
 
 void AutomationPosition::MoveToParentPosition(gin::Arguments* arguments) {
diff --git a/extensions/renderer/api/automation/automation_position.h b/extensions/renderer/api/automation/automation_position.h
index 3e4c870e..972e0f3 100644
--- a/extensions/renderer/api/automation/automation_position.h
+++ b/extensions/renderer/api/automation/automation_position.h
@@ -53,15 +53,15 @@
   bool AtEndOfPage(gin::Arguments* arguments);
   bool AtStartOfFormat(gin::Arguments* arguments);
   bool AtEndOfFormat(gin::Arguments* arguments);
-  bool AtStartOfDocument(gin::Arguments* arguments);
-  bool AtEndOfDocument(gin::Arguments* arguments);
+  bool AtStartOfContent(gin::Arguments* arguments);
+  bool AtEndOfContent(gin::Arguments* arguments);
   void AsTreePosition(gin::Arguments* arguments);
   void AsTextPosition(gin::Arguments* arguments);
   void AsLeafTextPosition(gin::Arguments* arguments);
   void MoveToPositionAtStartOfAnchor(gin::Arguments* arguments);
   void MoveToPositionAtEndOfAnchor(gin::Arguments* arguments);
-  void MoveToPositionAtStartOfDocument(gin::Arguments* arguments);
-  void MoveToPositionAtEndOfDocument(gin::Arguments* arguments);
+  void MoveToPositionAtStartOfContent(gin::Arguments* arguments);
+  void MoveToPositionAtEndOfContent(gin::Arguments* arguments);
   void MoveToParentPosition(gin::Arguments* arguments);
   void MoveToNextLeafTreePosition(gin::Arguments* arguments);
   void MoveToPreviousLeafTreePosition(gin::Arguments* arguments);
diff --git a/ios/chrome/browser/browsing_data/cache_counter_unittest.cc b/ios/chrome/browser/browsing_data/cache_counter_unittest.cc
index 096f2e7..bc2c535 100644
--- a/ios/chrome/browser/browsing_data/cache_counter_unittest.cc
+++ b/ios/chrome/browser/browsing_data/cache_counter_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/run_loop.h"
 #include "base/task/post_task.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/pref_names.h"
 #include "components/prefs/testing_pref_service.h"
@@ -239,7 +240,14 @@
 };
 
 // Tests that for the empty cache, the result is zero.
-TEST_F(CacheCounterTest, Empty) {
+// Disabled on Windows because this test randomly crashes on Win 7 Tests x64
+// (1). See: https://crbug.com/1152289
+#if defined(OS_WIN)
+#define MAYBE_Empty DISABLED_Empty
+#else
+#define MAYBE_Empty Empty
+#endif
+TEST_F(CacheCounterTest, MAYBE_Empty) {
   CacheCounter counter(browser_state());
   counter.Init(prefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&CacheCounterTest::CountingCallback,
diff --git a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
index 1870ef7..12702ae 100644
--- a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
+++ b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
@@ -60,6 +60,9 @@
   { policy::key::kDefaultPopupsSetting,
     prefs::kManagedDefaultPopupsSetting,
     base::Value::Type::INTEGER },
+  { policy::key::kIncognitoModeAvailability,
+    prefs::kIncognitoModeAvailability,
+    base::Value::Type::INTEGER },
   { policy::key::kMetricsReportingEnabled,
     metrics::prefs::kMetricsReportingEnabled,
     base::Value::Type::BOOLEAN },
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc
index d7c16e0..e792e701 100644
--- a/ios/chrome/browser/pref_names.cc
+++ b/ios/chrome/browser/pref_names.cc
@@ -56,6 +56,12 @@
 // Prefs for persisting HttpServerProperties.
 const char kHttpServerProperties[] = "net.http_server_properties";
 
+// Integer that specifies whether Incognito mode is:
+// 0 - Enabled. Default behaviour. Default mode is available on demand.
+// 1 - Disabled. User cannot browse pages in Incognito mode.
+// 2 - Forced. All pages/sessions are forced into Incognito.
+const char kIncognitoModeAvailability[] = "incognito.mode_availability";
+
 // Caches the folder id of user's position in the bookmark hierarchy navigator.
 const char kIosBookmarkCachedFolderId[] = "ios.bookmark.cached_folder_id";
 
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h
index 335ac71..ab11585 100644
--- a/ios/chrome/browser/pref_names.h
+++ b/ios/chrome/browser/pref_names.h
@@ -20,6 +20,7 @@
 extern const char kDefaultCharset[];
 extern const char kEnableDoNotTrack[];
 extern const char kHttpServerProperties[];
+extern const char kIncognitoModeAvailability[];
 extern const char kIosBookmarkCachedFolderId[];
 extern const char kIosBookmarkCachedTopMostRow[];
 extern const char kIosBookmarkFolderDefault[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm
index cfdf1bd..fc7b9ac 100644
--- a/ios/chrome/browser/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -231,6 +231,9 @@
   registry->RegisterIntegerPref(kGCMChannelPollIntervalSeconds, 0);
   registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0);
 
+  // Register kIncognitoModeAvailability to available.
+  registry->RegisterIntegerPref(prefs::kIncognitoModeAvailability, 0);
+
   registry->RegisterListPref(kInvalidatorSavedInvalidations);
   registry->RegisterStringPref(kInvalidatorInvalidationState, std::string());
   registry->RegisterStringPref(kInvalidatorClientId, std::string());
diff --git a/ios/chrome/browser/ui/open_in/BUILD.gn b/ios/chrome/browser/ui/open_in/BUILD.gn
index 7c2225a7..0748cd9 100644
--- a/ios/chrome/browser/ui/open_in/BUILD.gn
+++ b/ios/chrome/browser/ui/open_in/BUILD.gn
@@ -72,6 +72,8 @@
   deps = [
     "//base",
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser/open_in:features",
+    "//ios/chrome/test:eg_test_support+eg2",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/testing/earl_grey:eg_test_support+eg2",
     "//ios/third_party/earl_grey2:test_lib",
diff --git a/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm b/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm
index b46bfef..2f15238 100644
--- a/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm
+++ b/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm
@@ -6,12 +6,16 @@
 
 #include "base/ios/ios_util.h"
 #include "base/strings/sys_string_conversions.h"
+#import "base/test/ios/wait_util.h"
+#import "ios/chrome/browser/open_in/features.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/earl_grey/chrome_actions.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/chrome/test/scoped_eg_synchronization_disabler.h"
+#import "ios/testing/earl_grey/app_launch_configuration.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "ui/base/l10n/l10n_util_mac.h"
@@ -25,6 +29,10 @@
 // Path which leads to a PDF file.
 const char kPDFPath[] = "/testpage.pdf";
 
+// Path wich leads to a PNG file.
+const char KPNGPath[] = "/chromium_logo.png";
+
+// Matcher for the Cancel button.
 id<GREYMatcher> ShareMenuDismissButton() {
   if (@available(iOS 13, *)) {
     return chrome_test_util::CloseButton();
@@ -35,12 +43,18 @@
 
 }  // namespace
 
-// Tests Open in Feature for PDF files.
+// Tests Open in Feature.
 @interface OpenInManagerTestCase : ChromeTestCase
 @end
 
 @implementation OpenInManagerTestCase
 
+- (AppLaunchConfiguration)appConfigurationForTestCase {
+  AppLaunchConfiguration config;
+  config.features_enabled.push_back(kExtendOpenInFilesSupport);
+  return config;
+}
+
 - (void)setUp {
   [super setUp];
   GREYAssertTrue(self.testServer->Start(), @"Server did not start.");
@@ -48,40 +62,103 @@
 
 // Tests that open in button appears when opening a PDF, and that tapping on it
 // will open the activity view.
-//
-// Disabled due to flakiness: http://crbug.com/1146303
-- (void)DISABLED_testOpenIn {
-  // TODO(crbug.com/1135805): The share menu displays in a popover on iPad,
-  // which causes this test to fail.
-  if ([ChromeEarlGrey isIPadIdiom]) {
-    EARL_GREY_TEST_DISABLED(@"Disabled on iPad");
-  }
+- (void)testOpenInPDF {
+  // Apple is hiding UIActivityViewController's content from the host app on
+  // iPad.
+  if ([ChromeEarlGrey isIPadIdiom])
+    EARL_GREY_TEST_SKIPPED(@"Test skipped on iPad.");
 
-  // TODO(crbug.com/982845): A bug is causing the "Open in" toolbar to disappear
-  // after any VC is presented fullscreen over the BVC.  The iOS 13 share menu
-  // is presented fullscreen, but only when compiling with the iOS 12 SDK.
-  // Disable this test in this configuration until the underlying bug is fixed.
-#if !defined(__IPHONE_13_0) || (__IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_13_0)
-  if (base::ios::IsRunningOnIOS13OrLater()) {
-    EARL_GREY_TEST_DISABLED(
-        @"Disabled on iOS 13 when compiled with the iOS 12 SDK.");
-  }
-#endif
-
+  // Open the activity menu.
   [ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)];
   [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()]
       performAction:grey_tap()];
-  // Check and tap on the Cancel button that appears below the activity menu.
-  // Other actions buttons can't be checked from EarlGrey.
-  [[[EarlGrey selectElementWithMatcher:ShareMenuDismissButton()]
-      assertWithMatcher:grey_interactable()] performAction:grey_tap()];
 
-  // Check that after dismissing the activity view, tapping on the web view will
-  // bring the open in bar again.
+  // UIActivityViewController doesn't display the filename on iOS 12.
+  if (@available(iOS 13, *)) {
+    // Test filename label.
+    [[EarlGrey
+        selectElementWithMatcher:grey_allOf(grey_text(@"testpage"),
+                                            grey_sufficientlyVisible(), nil)]
+        assertWithMatcher:grey_notNil()];
+  }
+
+  // Check that tapping on the Cancel button closes the activity menu and hides
+  // the open in toolbar.
+  [[EarlGrey selectElementWithMatcher:ShareMenuDismissButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:ShareMenuDismissButton()]
+      assertWithMatcher:grey_notVisible()];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()]
+      assertWithMatcher:grey_notVisible()];
+}
+
+// Tests that open in button appears when opening a PNG, and that tapping on it
+// will open the activity view.
+- (void)testOpenInPNG {
+  // Apple is hiding UIActivityViewController's content from the host app on
+  // iPad.
+  if ([ChromeEarlGrey isIPadIdiom])
+    EARL_GREY_TEST_SKIPPED(@"Test skipped on iPad.");
+
+  // Open the activity menu.
+  [ChromeEarlGrey loadURL:self.testServer->GetURL(KPNGPath)];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()]
+      performAction:grey_tap()];
+
+  // UIActivityViewController doesn't display the filename on iOS 12.
+  if (@available(iOS 13, *)) {
+    // Test filename label.
+    [[EarlGrey
+        selectElementWithMatcher:grey_allOf(grey_text(@"chromium_logo"),
+                                            grey_sufficientlyVisible(), nil)]
+        assertWithMatcher:grey_notNil()];
+  }
+
+  // Check that tapping on the Cancel button closes the activity menu and hides
+  // the open in toolbar.
+  [[EarlGrey selectElementWithMatcher:ShareMenuDismissButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:ShareMenuDismissButton()]
+      assertWithMatcher:grey_notVisible()];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()]
+      assertWithMatcher:grey_notVisible()];
+}
+
+// Tests that the open in bar is correctly displayed when a compatible URL is
+// loaded and tapping on the web view makes it appear or disappear.
+- (void)testOpenInDisplay {
+  // Check that the open in bar is correctly displayed when a compatible URL is
+  // loaded.
+  [ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Check that tapping on the web view makes the open in toolbar disappear.
   [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
       performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()]
-      assertWithMatcher:grey_interactable()];
+      assertWithMatcher:grey_notVisible()];
+
+  // Check that tapping on the web view makes the open in toolbar appear.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:grey_tap()];
+  // Turn off synchronization of GREYAssert to test the appearance of open in
+  // toolbar. If synchronization is on, the open in toolbar exists but it's not
+  // considered visible.
+  ScopedSynchronizationDisabler disabler;
+  GREYCondition* openInVisibleCondition = [GREYCondition
+      conditionWithName:@"Check that the open in toolbar is visible"
+                  block:^BOOL {
+                    NSError* error = nil;
+                    [[EarlGrey selectElementWithMatcher:chrome_test_util::
+                                                            OpenInButton()]
+                        assertWithMatcher:grey_sufficientlyVisible()
+                                    error:&error];
+                    return error == nil;
+                  }];
+  BOOL openInVisible = [openInVisibleCondition
+      waitWithTimeout:base::test::ios::kWaitForUIElementTimeout];
+  GREYAssertTrue(openInVisible, @"The open in toolbar never became visible.");
 }
 
 @end
diff --git a/ios/chrome/test/data/policy/policy_test_cases.json b/ios/chrome/test/data/policy/policy_test_cases.json
index 55d6d54..280205e 100644
--- a/ios/chrome/test/data/policy/policy_test_cases.json
+++ b/ios/chrome/test/data/policy/policy_test_cases.json
@@ -308,6 +308,20 @@
     ]
   },
 
+  "IncognitoModeAvailability": {
+    "os": [ "ios" ],
+    "policy_pref_mapping_test": [
+      {
+        "policies": { "IncognitoModeAvailability": 1 },
+        "prefs": { "incognito.mode_availability": {} }
+      },
+      {
+        "policies": { "IncognitoModeAvailability": 2 },
+        "prefs": { "incognito.mode_availability": {} }
+      }
+    ]
+  },
+
   "MetricsReportingEnabled": {
     "os": [ "ios" ],
     "policy_pref_mapping_tests": [
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
index 8798143..8e80c8a8 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-5f401a2d7f24069036a13d2c31b8e5fddde3d5a7
\ No newline at end of file
+fef4e744106d685338b21081095dc3a82bb5bec2
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
index 0142622..14603a6e 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-f71c498d92a9035f1c9db31094ce300d8be4e6f1
\ No newline at end of file
+e4cf1ddb027a9f71a688ee4bd57c0e84ae589841
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
index 538826c6..1659b1b9 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-030efabe9b40c94b70b7d2744929fb98cd1299c0
\ No newline at end of file
+1084adddcc5ae44f0eea37397cbdab3d4ea91121
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
index c5b275b..43465b9 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-8fb34dcb825f96c215ac32dc3993342f8fbb5423
\ No newline at end of file
+5dc2ea35fba12ab068ccc05c69dce2377e1065b7
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
index 02bc5a5..36337e81 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-c3083629c1b1cbec5a3dca37df09e0803e72e76a
\ No newline at end of file
+3e9f556c3a8b4b07688661dde402748feb692060
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
index 059ce07..fe2bda2 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-e1a98658a4bb87db8e01fb16b37e8e2207d303c0
\ No newline at end of file
+7223c72049f4804c971876bdab5d93beed34a842
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
index 997f546..2754f98 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-a21e29ea67c207149ae38649dd5d1f58715ff0d6
\ No newline at end of file
+f271c80ba5d329123699dd34186b4445632d5880
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
index f78adc3..63fd2d84 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-567fa443c2274d441e0d0955fdabb51fc6e1a25f
\ No newline at end of file
+d7e1f48514c0cdcdaf7addacc2e315e1286cdad4
\ No newline at end of file
diff --git a/pdf/accessibility.cc b/pdf/accessibility.cc
index cea8028..fc767a6 100644
--- a/pdf/accessibility.cc
+++ b/pdf/accessibility.cc
@@ -186,7 +186,7 @@
     int32_t page_index,
     AccessibilityPageInfo& page_info,
     std::vector<pp::PDF::PrivateAccessibilityTextRunInfo>* text_runs,
-    std::vector<PP_PrivateAccessibilityCharInfo>* chars,
+    std::vector<AccessibilityCharInfo>& chars,
     pp::PDF::PrivateAccessibilityPageObjects* page_objects) {
   int page_count = engine->GetNumberOfPages();
   if (page_index < 0 || page_index >= page_count)
@@ -203,9 +203,9 @@
   page_info.bounds = engine->GetPageBoundsRect(page_index);
   page_info.char_count = char_count;
 
-  chars->resize(page_info.char_count);
+  chars.resize(page_info.char_count);
   for (uint32_t i = 0; i < page_info.char_count; ++i) {
-    (*chars)[i].unicode_character = engine->GetCharUnicode(page_index, i);
+    chars[i].unicode_character = engine->GetCharUnicode(page_index, i);
   }
 
   int char_index = 0;
@@ -231,7 +231,7 @@
     for (uint32_t i = char_index; i < text_run_end - 1; i++) {
       DCHECK_LT(i + 1, static_cast<uint32_t>(char_count));
       gfx::RectF next_char_bounds = engine->GetCharBounds(page_index, i + 1);
-      double& char_width = (*chars)[i].char_width;
+      double& char_width = chars[i].char_width;
       switch (text_run_info.direction) {
         case PP_PRIVATEDIRECTION_NONE:
         case PP_PRIVATEDIRECTION_LTR:
@@ -249,7 +249,7 @@
       }
       char_bounds = next_char_bounds;
     }
-    double& char_width = (*chars)[text_run_end - 1].char_width;
+    double& char_width = chars[text_run_end - 1].char_width;
     if (text_run_info.direction == PP_PRIVATEDIRECTION_BTT ||
         text_run_info.direction == PP_PRIVATEDIRECTION_TTB) {
       char_width = char_bounds.height();
diff --git a/pdf/accessibility.h b/pdf/accessibility.h
index 6e0394b..ca6a4b8c 100644
--- a/pdf/accessibility.h
+++ b/pdf/accessibility.h
@@ -13,6 +13,7 @@
 
 namespace chrome_pdf {
 
+struct AccessibilityCharInfo;
 struct AccessibilityPageInfo;
 class PDFEngine;
 
@@ -25,7 +26,7 @@
     int32_t page_index,
     AccessibilityPageInfo& page_info,
     std::vector<pp::PDF::PrivateAccessibilityTextRunInfo>* text_runs,
-    std::vector<PP_PrivateAccessibilityCharInfo>* chars,
+    std::vector<AccessibilityCharInfo>& chars,
     pp::PDF::PrivateAccessibilityPageObjects* page_objects);
 
 }  // namespace chrome_pdf
diff --git a/pdf/accessibility_structs.h b/pdf/accessibility_structs.h
index 0816db9..72c936a 100644
--- a/pdf/accessibility_structs.h
+++ b/pdf/accessibility_structs.h
@@ -18,6 +18,11 @@
   uint32_t char_count = 0;
 };
 
+struct AccessibilityCharInfo {
+  uint32_t unicode_character = 0;
+  double char_width = 0.0;
+};
+
 }  // namespace chrome_pdf
 
 #endif  // PDF_ACCESSIBILITY_STRUCTS_H_
\ No newline at end of file
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc
index 4bfc6c1..3a682ba 100644
--- a/pdf/out_of_process_instance.cc
+++ b/pdf/out_of_process_instance.cc
@@ -488,6 +488,16 @@
   return pp_page_info;
 }
 
+std::vector<PP_PrivateAccessibilityCharInfo>
+PrivateAccessibilityCharInfoFromAccessibilityCharInfo(
+    const std::vector<AccessibilityCharInfo>& chars) {
+  std::vector<PP_PrivateAccessibilityCharInfo> pp_chars;
+  pp_chars.reserve(chars.size());
+  for (const auto& char_object : chars)
+    pp_chars.push_back({char_object.unicode_character, char_object.char_width});
+  return pp_chars;
+}
+
 }  // namespace
 
 OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
@@ -828,18 +838,20 @@
 void OutOfProcessInstance::SendNextAccessibilityPage(int32_t page_index) {
   AccessibilityPageInfo page_info;
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> text_runs;
-  std::vector<PP_PrivateAccessibilityCharInfo> chars;
+  std::vector<AccessibilityCharInfo> chars;
   pp::PDF::PrivateAccessibilityPageObjects page_objects;
 
-  if (!GetAccessibilityInfo(engine(), page_index, page_info, &text_runs, &chars,
+  if (!GetAccessibilityInfo(engine(), page_index, page_info, &text_runs, chars,
                             &page_objects)) {
     return;
   }
 
   PP_PrivateAccessibilityPageInfo pp_page_info =
       PrivateAccessibilityPageInfoFromAccessibilityPageInfo(page_info);
+  std::vector<PP_PrivateAccessibilityCharInfo> pp_chars =
+      PrivateAccessibilityCharInfoFromAccessibilityCharInfo(chars);
   pp::PDF::SetAccessibilityPageInfo(GetPluginInstance(), &pp_page_info,
-                                    text_runs, chars, page_objects);
+                                    text_runs, pp_chars, page_objects);
 
   // Schedule loading the next page.
   pp::Module::Get()->core()->CallOnMainThread(
diff --git a/pdf/pdfium/accessibility_unittest.cc b/pdf/pdfium/accessibility_unittest.cc
index 861dc378..19a0e3f 100644
--- a/pdf/pdfium/accessibility_unittest.cc
+++ b/pdf/pdfium/accessibility_unittest.cc
@@ -57,7 +57,7 @@
                 "Bad test expectation count");
 
   static constexpr size_t kExpectedCharCount = 30;
-  static constexpr PP_PrivateAccessibilityCharInfo kExpectedChars[] = {
+  static constexpr AccessibilityCharInfo kExpectedChars[] = {
       {'H', 12}, {'e', 6.6666}, {'l', 5.3333}, {'l', 4},      {'o', 8},
       {',', 4},  {' ', 4},      {'w', 12},     {'o', 6.6666}, {'r', 6.6666},
       {'l', 4},  {'d', 9.3333}, {'!', 4},      {'\r', 0},     {'\n', 0},
@@ -76,10 +76,10 @@
   ASSERT_EQ(2, engine->GetNumberOfPages());
   AccessibilityPageInfo page_info;
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> text_runs;
-  std::vector<PP_PrivateAccessibilityCharInfo> chars;
+  std::vector<AccessibilityCharInfo> chars;
   pp::PDF::PrivateAccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, &text_runs,
-                                   &chars, &page_objects));
+                                   chars, &page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 266, 266), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -129,10 +129,10 @@
 
   AccessibilityPageInfo page_info;
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> text_runs;
-  std::vector<PP_PrivateAccessibilityCharInfo> chars;
+  std::vector<AccessibilityCharInfo> chars;
   pp::PDF::PrivateAccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, &text_runs,
-                                   &chars, &page_objects));
+                                   chars, &page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 816, 1056), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -472,10 +472,10 @@
 
   AccessibilityPageInfo page_info;
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> text_runs;
-  std::vector<PP_PrivateAccessibilityCharInfo> chars;
+  std::vector<AccessibilityCharInfo> chars;
   pp::PDF::PrivateAccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, &text_runs,
-                                   &chars, &page_objects));
+                                   chars, &page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 533, 266), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -519,10 +519,10 @@
 
   AccessibilityPageInfo page_info;
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> text_runs;
-  std::vector<PP_PrivateAccessibilityCharInfo> chars;
+  std::vector<AccessibilityCharInfo> chars;
   pp::PDF::PrivateAccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, &text_runs,
-                                   &chars, &page_objects));
+                                   chars, &page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 533, 266), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -577,10 +577,10 @@
 
   AccessibilityPageInfo page_info;
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> text_runs;
-  std::vector<PP_PrivateAccessibilityCharInfo> chars;
+  std::vector<AccessibilityCharInfo> chars;
   pp::PDF::PrivateAccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, &text_runs,
-                                   &chars, &page_objects));
+                                   chars, &page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 400, 400), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom
index 88912c9..3d2a5703 100644
--- a/services/network/public/mojom/network_service.mojom
+++ b/services/network/public/mojom/network_service.mojom
@@ -106,6 +106,15 @@
     int32 render_frame_id,
     mojo_base.mojom.UnguessableToken devtool_request_id,
     URLLoaderCompletionStatus status);
+
+  // Called to send the result of a successful or failed Trust Token
+  // operation. Only called when |devtools_request_id| is available on the
+  // original request.
+  OnTrustTokenOperationDone(
+    int32 process_id,
+    int32 routing_id,
+    string devtool_request_id,
+    TrustTokenOperationResult result);
 };
 
 // Values for configuring HTTP authentication that can only be set once.
diff --git a/services/network/public/mojom/trust_tokens.mojom b/services/network/public/mojom/trust_tokens.mojom
index c9df1b0..4debf76 100644
--- a/services/network/public/mojom/trust_tokens.mojom
+++ b/services/network/public/mojom/trust_tokens.mojom
@@ -262,3 +262,18 @@
   // response header. Otherwise, its value is indeterminate.
   string response;
 };
+
+// TrustTokenOperationResult contains all the information required by
+// DevTools. Which fields are set depend on |type| and |status|.
+struct TrustTokenOperationResult {
+  // Required.
+  TrustTokenOperationType type;
+  TrustTokenOperationStatus status;
+
+  // Shared among the different operation types.
+  url.mojom.Origin? issuer;
+  url.mojom.Origin? top_level_origin;
+
+  // In case of TrustTokenOperationType::kIssuance.
+  int32 issued_token_count = 0;
+};
diff --git a/services/network/test/test_network_service_client.cc b/services/network/test/test_network_service_client.cc
index cb6389e..db13adc 100644
--- a/services/network/test/test_network_service_client.cc
+++ b/services/network/test/test_network_service_client.cc
@@ -65,4 +65,10 @@
     const base::UnguessableToken& devtool_request_id,
     const network::URLLoaderCompletionStatus& status) {}
 
+void TestNetworkServiceClient::OnTrustTokenOperationDone(
+    int32_t process_id,
+    int32_t routing_id,
+    const std::string& devtool_request_id,
+    network::mojom::TrustTokenOperationResultPtr result) {}
+
 }  // namespace network
diff --git a/services/network/test/test_network_service_client.h b/services/network/test/test_network_service_client.h
index 5c5818b..1b7b8d0 100644
--- a/services/network/test/test_network_service_client.h
+++ b/services/network/test/test_network_service_client.h
@@ -62,6 +62,11 @@
       int32_t routing_id,
       const base::UnguessableToken& devtool_request_id,
       const network::URLLoaderCompletionStatus& status) override;
+  void OnTrustTokenOperationDone(
+      int32_t process_id,
+      int32_t routing_id,
+      const std::string& devtool_request_id,
+      network::mojom::TrustTokenOperationResultPtr result) override;
 
  private:
   mojo::Receiver<mojom::NetworkServiceClient> receiver_;
diff --git a/services/network/trust_tokens/operation_timing_request_helper_wrapper.cc b/services/network/trust_tokens/operation_timing_request_helper_wrapper.cc
index 9d5a9135..8037935 100644
--- a/services/network/trust_tokens/operation_timing_request_helper_wrapper.cc
+++ b/services/network/trust_tokens/operation_timing_request_helper_wrapper.cc
@@ -47,4 +47,10 @@
   std::move(done).Run(status);
 }
 
+mojom::TrustTokenOperationResultPtr
+OperationTimingRequestHelperWrapper::CollectOperationResultWithStatus(
+    mojom::TrustTokenOperationStatus status) {
+  return helper_->CollectOperationResultWithStatus(status);
+}
+
 }  // namespace network
diff --git a/services/network/trust_tokens/operation_timing_request_helper_wrapper.h b/services/network/trust_tokens/operation_timing_request_helper_wrapper.h
index 08ce803..bb8e846 100644
--- a/services/network/trust_tokens/operation_timing_request_helper_wrapper.h
+++ b/services/network/trust_tokens/operation_timing_request_helper_wrapper.h
@@ -32,6 +32,9 @@
       mojom::URLResponseHead* response,
       base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override;
 
+  mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
+      mojom::TrustTokenOperationStatus status) override;
+
  private:
   // Records timing metrics, then calls the callback.
   void FinishBegin(
diff --git a/services/network/trust_tokens/trust_token_request_helper.h b/services/network/trust_tokens/trust_token_request_helper.h
index d4781c3..e2b4d89 100644
--- a/services/network/trust_tokens/trust_token_request_helper.h
+++ b/services/network/trust_tokens/trust_token_request_helper.h
@@ -6,7 +6,7 @@
 #define SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_REQUEST_HELPER_H_
 
 #include "base/callback_forward.h"
-#include "services/network/public/mojom/trust_tokens.mojom-shared.h"
+#include "services/network/public/mojom/trust_tokens.mojom.h"
 #include "services/network/public/mojom/url_response_head.mojom-forward.h"
 
 namespace net {
@@ -41,6 +41,12 @@
   virtual void Finalize(
       mojom::URLResponseHead* response,
       base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) = 0;
+
+  // Provides operation specific information to DevTools. The |status| of an
+  // operation is passed inline to the "done" callback and not stored on the
+  // helper. Thus, it always needs to be provided explicitly.
+  virtual mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
+      mojom::TrustTokenOperationStatus status) = 0;
 };
 
 }  // namespace network
diff --git a/services/network/trust_tokens/trust_token_request_issuance_helper.cc b/services/network/trust_tokens/trust_token_request_issuance_helper.cc
index 1f12d25c..94b5370f 100644
--- a/services/network/trust_tokens/trust_token_request_issuance_helper.cc
+++ b/services/network/trust_tokens/trust_token_request_issuance_helper.cc
@@ -321,9 +321,11 @@
   token_store_->AddTokens(*issuer_, base::make_span(maybe_tokens->tokens),
                           maybe_tokens->body_of_verifying_key);
 
+  num_obtained_tokens_ = maybe_tokens->tokens.size();
+
   net_log_.EndEvent(
       net::NetLogEventType::TRUST_TOKEN_OPERATION_FINALIZE_ISSUANCE,
-      [num_obtained_tokens = maybe_tokens->tokens.size()]() {
+      [num_obtained_tokens = *num_obtained_tokens_]() {
         base::Value ret = CreateLogValue("Success");
         ret.SetIntKey("# tokens obtained", num_obtained_tokens);
         return ret;
@@ -371,4 +373,21 @@
   std::move(done).Run(status);
 }
 
+mojom::TrustTokenOperationResultPtr
+TrustTokenRequestIssuanceHelper::CollectOperationResultWithStatus(
+    mojom::TrustTokenOperationStatus status) {
+  mojom::TrustTokenOperationResultPtr operation_result =
+      mojom::TrustTokenOperationResult::New();
+  operation_result->status = status;
+  operation_result->type = mojom::TrustTokenOperationType::kIssuance;
+  operation_result->top_level_origin = top_level_origin_;
+  if (issuer_) {
+    operation_result->issuer = *issuer_;
+  }
+  if (num_obtained_tokens_) {
+    operation_result->issued_token_count = *num_obtained_tokens_;
+  }
+  return operation_result;
+}
+
 }  // namespace network
diff --git a/services/network/trust_tokens/trust_token_request_issuance_helper.h b/services/network/trust_tokens/trust_token_request_issuance_helper.h
index 44f06f6..4e9b8902 100644
--- a/services/network/trust_tokens/trust_token_request_issuance_helper.h
+++ b/services/network/trust_tokens/trust_token_request_issuance_helper.h
@@ -187,6 +187,9 @@
   struct CryptographerAndBlindedTokens;
   struct CryptographerAndUnblindedTokens;
 
+  mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
+      mojom::TrustTokenOperationStatus status) override;
+
  private:
   // Continuation of |Begin| after asynchronous key commitment fetching
   // concludes.
@@ -275,6 +278,7 @@
       is_current_os_callback_;
 
   net::NetLogWithSource net_log_;
+  base::Optional<size_t> num_obtained_tokens_;
   base::WeakPtrFactory<TrustTokenRequestIssuanceHelper> weak_ptr_factory_{this};
 };
 
diff --git a/services/network/trust_tokens/trust_token_request_redemption_helper.cc b/services/network/trust_tokens/trust_token_request_redemption_helper.cc
index b479fdc..1c0a6669 100644
--- a/services/network/trust_tokens/trust_token_request_redemption_helper.cc
+++ b/services/network/trust_tokens/trust_token_request_redemption_helper.cc
@@ -261,4 +261,18 @@
   return matching_tokens.front();
 }
 
+mojom::TrustTokenOperationResultPtr
+TrustTokenRequestRedemptionHelper::CollectOperationResultWithStatus(
+    mojom::TrustTokenOperationStatus status) {
+  mojom::TrustTokenOperationResultPtr operation_result =
+      mojom::TrustTokenOperationResult::New();
+  operation_result->status = status;
+  operation_result->type = mojom::TrustTokenOperationType::kRedemption;
+  operation_result->top_level_origin = top_level_origin_;
+  if (issuer_) {
+    operation_result->issuer = *issuer_;
+  }
+  return operation_result;
+}
+
 }  // namespace network
diff --git a/services/network/trust_tokens/trust_token_request_redemption_helper.h b/services/network/trust_tokens/trust_token_request_redemption_helper.h
index c37e2e08..9518c8f 100644
--- a/services/network/trust_tokens/trust_token_request_redemption_helper.h
+++ b/services/network/trust_tokens/trust_token_request_redemption_helper.h
@@ -175,6 +175,9 @@
       mojom::URLResponseHead* response,
       base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override;
 
+  mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
+      mojom::TrustTokenOperationStatus status) override;
+
  private:
   // Continuation of |Begin| after asynchronous key commitment fetching
   // concludes.
diff --git a/services/network/trust_tokens/trust_token_request_signing_helper.cc b/services/network/trust_tokens/trust_token_request_signing_helper.cc
index d63cf40..92ac164 100644
--- a/services/network/trust_tokens/trust_token_request_signing_helper.cc
+++ b/services/network/trust_tokens/trust_token_request_signing_helper.cc
@@ -604,4 +604,15 @@
   return signer_->Sign(key_bytes, base::make_span(signing_data));
 }
 
+mojom::TrustTokenOperationResultPtr
+TrustTokenRequestSigningHelper::CollectOperationResultWithStatus(
+    mojom::TrustTokenOperationStatus status) {
+  mojom::TrustTokenOperationResultPtr operation_result =
+      mojom::TrustTokenOperationResult::New();
+  operation_result->status = status;
+  operation_result->type = mojom::TrustTokenOperationType::kRedemption;
+  operation_result->top_level_origin = params_.toplevel;
+  return operation_result;
+}
+
 }  // namespace network
diff --git a/services/network/trust_tokens/trust_token_request_signing_helper.h b/services/network/trust_tokens/trust_token_request_signing_helper.h
index 9534352..fcf37a2 100644
--- a/services/network/trust_tokens/trust_token_request_signing_helper.h
+++ b/services/network/trust_tokens/trust_token_request_signing_helper.h
@@ -215,6 +215,9 @@
       mojom::URLResponseHead* response,
       base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override;
 
+  mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
+      mojom::TrustTokenOperationStatus status) override;
+
  private:
   // Given issuer-to-redemption-record and issuer-to-signature maps, returns a
   // Trust Tokens signature header, a serialized Structured Headers Draft 15
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 21e9773..4675dfd 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -843,6 +843,16 @@
         FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted,
                                   weak_ptr_factory_.GetWeakPtr(),
                                   net::ERR_TRUST_TOKEN_OPERATION_FAILED));
+
+    if (network_service_client_ && devtools_request_id()) {
+      mojom::TrustTokenOperationResultPtr operation_result =
+          mojom::TrustTokenOperationResult::New();
+      operation_result->status = *trust_token_status_;
+      operation_result->type = type;
+      network_service_client_->OnTrustTokenOperationDone(
+          GetProcessId(), GetRenderFrameId(), devtools_request_id().value(),
+          std::move(operation_result));
+    }
     return;
   }
 
@@ -857,6 +867,14 @@
 void URLLoader::OnDoneBeginningTrustTokenOperation(
     mojom::TrustTokenOperationStatus status) {
   trust_token_status_ = status;
+
+  // In case the operation failed or we hit the cache, the DevTools event is
+  // emitted from here. Otherwise the DevTools event is always emitted from
+  // |OnDoneFinalizeTrustTokenOperation|.
+  if (status != mojom::TrustTokenOperationStatus::kOk) {
+    MaybeSendTrustTokenOperationResultToDevTools();
+  }
+
   if (status == mojom::TrustTokenOperationStatus::kOk) {
     ScheduleStart();
   } else if (status == mojom::TrustTokenOperationStatus::kAlreadyExists) {
@@ -1257,6 +1275,8 @@
     mojom::TrustTokenOperationStatus status) {
   trust_token_status_ = status;
 
+  MaybeSendTrustTokenOperationResultToDevTools();
+
   if (status != mojom::TrustTokenOperationStatus::kOk) {
     NotifyCompleted(net::ERR_TRUST_TOKEN_OPERATION_FAILED);
     // |this| may have been deleted.
@@ -1265,6 +1285,20 @@
   ContinueOnResponseStarted();
 }
 
+void URLLoader::MaybeSendTrustTokenOperationResultToDevTools() {
+  CHECK(trust_token_helper_ && trust_token_status_);
+
+  if (!network_service_client_ || !devtools_request_id())
+    return;
+
+  mojom::TrustTokenOperationResultPtr operation_result =
+      trust_token_helper_->CollectOperationResultWithStatus(
+          *trust_token_status_);
+  network_service_client_->OnTrustTokenOperationDone(
+      GetProcessId(), GetRenderFrameId(), devtools_request_id().value(),
+      std::move(operation_result));
+}
+
 void URLLoader::ContinueOnResponseStarted() {
   MojoCreateDataPipeOptions options;
   options.struct_size = sizeof(MojoCreateDataPipeOptions);
diff --git a/services/network/url_loader.h b/services/network/url_loader.h
index 22515b2..e9728be 100644
--- a/services/network/url_loader.h
+++ b/services/network/url_loader.h
@@ -293,6 +293,7 @@
   // Continuation of |OnResponseStarted| after possibly asynchronously
   // concluding the request's Trust Tokens operation.
   void ContinueOnResponseStarted();
+  void MaybeSendTrustTokenOperationResultToDevTools();
 
   void ScheduleStart();
   void ReadMore();
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 1941c104..0b53332e 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -5531,6 +5531,14 @@
     }
   }
 
+  mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
+      mojom::TrustTokenOperationStatus status) override {
+    mojom::TrustTokenOperationResultPtr operation_result =
+        mojom::TrustTokenOperationResult::New();
+    operation_result->status = status;
+    return operation_result;
+  }
+
  private:
   void OnDoneBeginning(base::OnceClosure done) {
     if (begin_done_flag_) {
@@ -5635,6 +5643,31 @@
   std::unique_ptr<TrustTokenRequestHelper> helper_;
 };
 
+class MockTrustTokenNetworkServiceClient : public TestNetworkServiceClient {
+ public:
+  MockTrustTokenNetworkServiceClient() = default;
+  ~MockTrustTokenNetworkServiceClient() override = default;
+
+  void OnTrustTokenOperationDone(
+      int32_t process_id,
+      int32_t routing_id,
+      const std::string& devtool_request_id,
+      network::mojom::TrustTokenOperationResultPtr result) override {
+    // Event should be only triggered once.
+    EXPECT_FALSE(trust_token_operation_status_.has_value());
+    trust_token_operation_status_ = result->status;
+  }
+
+  const base::Optional<mojom::TrustTokenOperationStatus>
+  trust_token_operation_status() const {
+    return trust_token_operation_status_;
+  }
+
+ private:
+  base::Optional<mojom::TrustTokenOperationStatus>
+      trust_token_operation_status_ = base::nullopt;
+};
+
 }  // namespace
 
 class URLLoaderSyncOrAsyncTrustTokenOperationTest
@@ -5646,6 +5679,16 @@
   }
 
  protected:
+  ResourceRequest CreateTrustTokenResourceRequest() {
+    ResourceRequest request = CreateResourceRequest(
+        "GET", test_server()->GetURL("/simple_page.html"));
+    request.trust_token_params =
+        OptionalTrustTokenParams(mojom::TrustTokenParams::New());
+    // Set the devtools id to trigger the OnTrustTokenOperationDone call.
+    request.devtools_request_id = "TEST";
+    return request;
+  }
+
   // Maintain a flag, set by the mock trust token request helper, denoting
   // whether we've successfully executed the outbound Trust Tokens operation.
   // This is used to make URLLoader does not send its main request before it
@@ -5664,20 +5707,17 @@
 // whose Begin and Finalize steps are both successful should succeed overall.
 TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
        HandlesTrustTokenOperationSuccess) {
-  ResourceRequest request =
-      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
-  request.trust_token_params =
-      OptionalTrustTokenParams(mojom::TrustTokenParams::New());
+  ResourceRequest request = CreateTrustTokenResourceRequest();
 
   base::RunLoop delete_run_loop;
   mojo::PendingRemote<mojom::URLLoader> loader_remote;
   std::unique_ptr<URLLoader> url_loader;
   mojom::URLLoaderFactoryParams params;
   params.process_id = mojom::kBrowserProcessId;
+  MockTrustTokenNetworkServiceClient network_service_client;
 
   url_loader = std::make_unique<URLLoader>(
-      context(), nullptr /* network_service_client */,
-      nullptr /* network_context_client */,
+      context(), &network_service_client, nullptr /* network_context_client */,
       DeleteLoaderCallback(&delete_run_loop, &url_loader),
       loader_remote.InitWithNewPipeAndPassReceiver(), 0, request,
       client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt,
@@ -5698,6 +5738,9 @@
   EXPECT_EQ(client()->completion_status().error_code, net::OK);
   EXPECT_EQ(client()->completion_status().trust_token_operation_status,
             mojom::TrustTokenOperationStatus::kOk);
+  // Verify the DevTools event was fired and it has the right status.
+  EXPECT_EQ(network_service_client.trust_token_operation_status(),
+            mojom::TrustTokenOperationStatus::kOk);
   // The page should still have loaded.
   base::FilePath file = GetTestFilePath("simple_page.html");
   std::string expected;
@@ -5720,20 +5763,17 @@
 // operation.)
 TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
        HandlesTrustTokenRedemptionRecordCacheHit) {
-  ResourceRequest request =
-      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
-  request.trust_token_params =
-      OptionalTrustTokenParams(mojom::TrustTokenParams::New());
+  ResourceRequest request = CreateTrustTokenResourceRequest();
 
   base::RunLoop delete_run_loop;
   mojo::PendingRemote<mojom::URLLoader> loader_remote;
   std::unique_ptr<URLLoader> url_loader;
   mojom::URLLoaderFactoryParams params;
   params.process_id = mojom::kBrowserProcessId;
+  MockTrustTokenNetworkServiceClient network_service_client;
 
   url_loader = std::make_unique<URLLoader>(
-      context(), nullptr /* network_service_client */,
-      nullptr /* network_context_client */,
+      context(), &network_service_client, nullptr /* network_context_client */,
       DeleteLoaderCallback(&delete_run_loop, &url_loader),
       loader_remote.InitWithNewPipeAndPassReceiver(), 0, request,
       client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt,
@@ -5756,6 +5796,9 @@
             net::ERR_TRUST_TOKEN_OPERATION_CACHE_HIT);
   EXPECT_EQ(client()->completion_status().trust_token_operation_status,
             mojom::TrustTokenOperationStatus::kAlreadyExists);
+  // Verify the DevTools event was fired and it has the right status.
+  EXPECT_EQ(network_service_client.trust_token_operation_status(),
+            mojom::TrustTokenOperationStatus::kAlreadyExists);
 
   EXPECT_FALSE(client()->response_head());
   EXPECT_FALSE(client()->response_body().is_valid());
@@ -5765,20 +5808,17 @@
 // request itself should fail immediately.
 TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
        HandlesTrustTokenBeginFailure) {
-  ResourceRequest request =
-      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
-  request.trust_token_params =
-      OptionalTrustTokenParams(mojom::TrustTokenParams::New());
+  ResourceRequest request = CreateTrustTokenResourceRequest();
 
   base::RunLoop delete_run_loop;
   mojo::PendingRemote<mojom::URLLoader> loader_remote;
   std::unique_ptr<URLLoader> url_loader;
   mojom::URLLoaderFactoryParams params;
   params.process_id = mojom::kBrowserProcessId;
+  MockTrustTokenNetworkServiceClient network_service_client;
 
   url_loader = std::make_unique<URLLoader>(
-      context(), nullptr /* network_service_client */,
-      nullptr /* network_context_client */,
+      context(), &network_service_client, nullptr /* network_context_client */,
       DeleteLoaderCallback(&delete_run_loop, &url_loader),
       loader_remote.InitWithNewPipeAndPassReceiver(), 0, request,
       client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt,
@@ -5800,6 +5840,9 @@
             net::ERR_TRUST_TOKEN_OPERATION_FAILED);
   EXPECT_EQ(client()->completion_status().trust_token_operation_status,
             mojom::TrustTokenOperationStatus::kFailedPrecondition);
+  // Verify the DevTools event was fired and it has the right status.
+  EXPECT_EQ(network_service_client.trust_token_operation_status(),
+            mojom::TrustTokenOperationStatus::kFailedPrecondition);
 
   EXPECT_FALSE(client()->response_head());
   EXPECT_FALSE(client()->response_body().is_valid());
@@ -5809,20 +5852,17 @@
 // its Finalize step fails, the request itself should fail.
 TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
        HandlesTrustTokenFinalizeFailure) {
-  ResourceRequest request =
-      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
-  request.trust_token_params =
-      OptionalTrustTokenParams(mojom::TrustTokenParams::New());
+  ResourceRequest request = CreateTrustTokenResourceRequest();
 
   base::RunLoop delete_run_loop;
   mojo::PendingRemote<mojom::URLLoader> loader_remote;
   std::unique_ptr<URLLoader> url_loader;
   mojom::URLLoaderFactoryParams params;
   params.process_id = mojom::kBrowserProcessId;
+  MockTrustTokenNetworkServiceClient network_service_client;
 
   url_loader = std::make_unique<URLLoader>(
-      context(), nullptr /* network_service_client */,
-      nullptr /* network_context_client */,
+      context(), &network_service_client, nullptr /* network_context_client */,
       DeleteLoaderCallback(&delete_run_loop, &url_loader),
       loader_remote.InitWithNewPipeAndPassReceiver(), 0, request,
       client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt,
@@ -5844,6 +5884,9 @@
             net::ERR_TRUST_TOKEN_OPERATION_FAILED);
   EXPECT_EQ(client()->completion_status().trust_token_operation_status,
             mojom::TrustTokenOperationStatus::kBadResponse);
+  // Verify the DevTools event was fired and it has the right status.
+  EXPECT_EQ(network_service_client.trust_token_operation_status(),
+            mojom::TrustTokenOperationStatus::kBadResponse);
 }
 
 // When URLLoader receives a  request parameterized to perform a Trust Tokens
@@ -5852,20 +5895,17 @@
 // should fail entirely.
 TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
        HandlesTrustTokenRequestHelperCreationFailure) {
-  ResourceRequest request =
-      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
-  request.trust_token_params =
-      OptionalTrustTokenParams(mojom::TrustTokenParams::New());
+  ResourceRequest request = CreateTrustTokenResourceRequest();
 
   base::RunLoop delete_run_loop;
   mojo::PendingRemote<mojom::URLLoader> loader_remote;
   std::unique_ptr<URLLoader> url_loader;
   mojom::URLLoaderFactoryParams params;
   params.process_id = mojom::kBrowserProcessId;
+  MockTrustTokenNetworkServiceClient network_service_client;
 
   url_loader = std::make_unique<URLLoader>(
-      context(), nullptr /* network_service_client */,
-      nullptr /* network_context_client */,
+      context(), &network_service_client, nullptr /* network_context_client */,
       DeleteLoaderCallback(&delete_run_loop, &url_loader),
       loader_remote.InitWithNewPipeAndPassReceiver(), 0, request,
       client()->CreateRemote(), /*reponse_body_use_tracker=*/base::nullopt,
@@ -5887,6 +5927,9 @@
             net::ERR_TRUST_TOKEN_OPERATION_FAILED);
   EXPECT_EQ(client()->completion_status().trust_token_operation_status,
             mojom::TrustTokenOperationStatus::kInternalError);
+  // Verify the DevTools event was fired and it has the right status.
+  EXPECT_EQ(network_service_client.trust_token_operation_status(),
+            mojom::TrustTokenOperationStatus::kInternalError);
 }
 
 TEST_F(URLLoaderTest, OnRawRequestClientSecurityStateFactory) {
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn
index 7bdd25267..9259bde 100644
--- a/third_party/blink/common/BUILD.gn
+++ b/third_party/blink/common/BUILD.gn
@@ -150,7 +150,6 @@
     "page/page_zoom.cc",
     "page_state/page_state.cc",
     "page_state/page_state_serialization.cc",
-    "peerconnection/peer_connection_tracker_mojom_traits.cc",
     "peerconnection/webrtc_ip_handling_policy.cc",
     "permissions/permission_utils.cc",
     "renderer_preferences/renderer_preferences.cc",
diff --git a/third_party/blink/common/peerconnection/peer_connection_tracker_mojom_traits.cc b/third_party/blink/common/peerconnection/peer_connection_tracker_mojom_traits.cc
deleted file mode 100644
index 030a61e..0000000
--- a/third_party/blink/common/peerconnection/peer_connection_tracker_mojom_traits.cc
+++ /dev/null
@@ -1,58 +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 "third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h"
-
-#include "base/notreached.h"
-
-namespace mojo {
-
-// static
-blink::mojom::DeviceThermalState
-EnumTraits<blink::mojom::DeviceThermalState,
-           base::PowerObserver::DeviceThermalState>::
-    ToMojom(base::PowerObserver::DeviceThermalState type) {
-  switch (type) {
-    case base::PowerObserver::DeviceThermalState::kUnknown:
-      return blink::mojom::DeviceThermalState::kUnknown;
-    case base::PowerObserver::DeviceThermalState::kNominal:
-      return blink::mojom::DeviceThermalState::kNominal;
-    case base::PowerObserver::DeviceThermalState::kFair:
-      return blink::mojom::DeviceThermalState::kFair;
-    case base::PowerObserver::DeviceThermalState::kSerious:
-      return blink::mojom::DeviceThermalState::kSerious;
-    case base::PowerObserver::DeviceThermalState::kCritical:
-      return blink::mojom::DeviceThermalState::kCritical;
-  }
-  NOTREACHED();
-  return blink::mojom::DeviceThermalState::kUnknown;
-}
-
-// static
-bool EnumTraits<blink::mojom::DeviceThermalState,
-                base::PowerObserver::DeviceThermalState>::
-    FromMojom(blink::mojom::DeviceThermalState input,
-              base::PowerObserver::DeviceThermalState* out) {
-  switch (input) {
-    case blink::mojom::DeviceThermalState::kUnknown:
-      *out = base::PowerObserver::DeviceThermalState::kUnknown;
-      return true;
-    case blink::mojom::DeviceThermalState::kNominal:
-      *out = base::PowerObserver::DeviceThermalState::kNominal;
-      return true;
-    case blink::mojom::DeviceThermalState::kFair:
-      *out = base::PowerObserver::DeviceThermalState::kFair;
-      return true;
-    case blink::mojom::DeviceThermalState::kSerious:
-      *out = base::PowerObserver::DeviceThermalState::kSerious;
-      return true;
-    case blink::mojom::DeviceThermalState::kCritical:
-      *out = base::PowerObserver::DeviceThermalState::kCritical;
-      return true;
-  }
-  NOTREACHED();
-  return false;
-}
-
-}  // namespace mojo
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index 97f098d..ec52e07 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -235,6 +235,7 @@
     "platform/web_prescient_networking.h",
     "platform/web_private_ptr.h",
     "platform/web_rect.h",
+    "platform/web_request_peer.h",
     "platform/web_runtime_features.h",
     "platform/web_scoped_page_pauser.h",
     "platform/web_scroll_anchor_data.h",
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn
index ccb2c396..f4ce21f 100644
--- a/third_party/blink/public/common/BUILD.gn
+++ b/third_party/blink/public/common/BUILD.gn
@@ -172,7 +172,6 @@
     "page/page_zoom.h",
     "page_state/page_state.h",
     "page_state/page_state_serialization.h",
-    "peerconnection/peer_connection_tracker_mojom_traits.h",
     "peerconnection/webrtc_ip_handling_policy.h",
     "permissions/permission_utils.h",
     "renderer_preferences/renderer_preferences.h",
diff --git a/third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h b/third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h
deleted file mode 100644
index 6e237be..0000000
--- a/third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h
+++ /dev/null
@@ -1,26 +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 THIRD_PARTY_BLINK_PUBLIC_COMMON_PEERCONNECTION_PEER_CONNECTION_TRACKER_MOJOM_TRAITS_H_
-#define THIRD_PARTY_BLINK_PUBLIC_COMMON_PEERCONNECTION_PEER_CONNECTION_TRACKER_MOJOM_TRAITS_H_
-
-#include "base/power_monitor/power_observer.h"
-#include "third_party/blink/public/common/common_export.h"
-#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-shared.h"
-
-namespace mojo {
-
-template <>
-struct BLINK_COMMON_EXPORT EnumTraits<blink::mojom::DeviceThermalState,
-                                      base::PowerObserver::DeviceThermalState> {
-  static blink::mojom::DeviceThermalState ToMojom(
-      base::PowerObserver::DeviceThermalState type);
-
-  static bool FromMojom(blink::mojom::DeviceThermalState input,
-                        base::PowerObserver::DeviceThermalState* out);
-};
-
-}  // namespace mojo
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_PEERCONNECTION_PEER_CONNECTION_TRACKER_MOJOM_TRAITS_H_
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index d18c187..98e97ad 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -545,15 +545,6 @@
     {
       types = [
         {
-          mojom = "blink.mojom.DeviceThermalState"
-          cpp = "::base::PowerObserver::DeviceThermalState"
-        },
-      ]
-      traits_headers = [ "//third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h" ]
-    },
-    {
-      types = [
-        {
           mojom = "blink.mojom.PolicyValue"
           cpp = "::blink::PolicyValue"
         },
diff --git a/third_party/blink/public/platform/internet_disconnected_web_url_loader.h b/third_party/blink/public/platform/internet_disconnected_web_url_loader.h
index f8900a27..1ba3f12 100644
--- a/third_party/blink/public/platform/internet_disconnected_web_url_loader.h
+++ b/third_party/blink/public/platform/internet_disconnected_web_url_loader.h
@@ -65,7 +65,7 @@
       std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
           resource_load_info_notifier_wrapper,
       WebURLLoaderClient* client) override;
-  void SetDefersLoading(bool defers) override;
+  void SetDefersLoading(DeferType defers) override;
   void DidChangePriority(WebURLRequest::Priority, int) override;
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForBodyLoader()
       override;
diff --git a/third_party/blink/public/platform/web_navigation_body_loader.h b/third_party/blink/public/platform/web_navigation_body_loader.h
index 5ad44c3..8a5b806 100644
--- a/third_party/blink/public/platform/web_navigation_body_loader.h
+++ b/third_party/blink/public/platform/web_navigation_body_loader.h
@@ -12,6 +12,7 @@
 #include "base/time/time.h"
 #include "mojo/public/cpp/base/big_buffer.h"
 #include "third_party/blink/public/platform/web_url_error.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 
 namespace blink {
 
@@ -47,10 +48,10 @@
   // including from inside any client notification.
   virtual ~WebNavigationBodyLoader() {}
 
-  // While deferred, no more data will be read and no notifications
-  // will be called on the client. This method can be called
-  // multiples times, at any moment.
-  virtual void SetDefersLoading(bool defers) = 0;
+  // While deferred, data will be read on the renderer side but will not invoke
+  // any web-exposed behavior such as dispatching messages or handling
+  // redirects. This method can be called multiple times at any moment.
+  virtual void SetDefersLoading(WebURLLoader::DeferType defers) = 0;
 
   // Starts loading the body. Client must be non-null, and will receive
   // the body, code cache and final result.
diff --git a/content/public/renderer/request_peer.h b/third_party/blink/public/platform/web_request_peer.h
similarity index 87%
rename from content/public/renderer/request_peer.h
rename to third_party/blink/public/platform/web_request_peer.h
index 244d3b5ad..3c95ddf1 100644
--- a/content/public/renderer/request_peer.h
+++ b/third_party/blink/public/platform/web_request_peer.h
@@ -2,19 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_PUBLIC_RENDERER_REQUEST_PEER_H_
-#define CONTENT_PUBLIC_RENDERER_REQUEST_PEER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_REQUEST_PEER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_REQUEST_PEER_H_
 
 #include <stdint.h>
 
-#include <memory>
 #include <string>
+#include <vector>
 
-#include "base/task_runner.h"
-#include "content/common/content_export.h"
 #include "mojo/public/cpp/base/big_buffer.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "services/network/public/mojom/url_response_head.mojom-forward.h"
+#include "third_party/blink/public/platform/web_common.h"
 
 namespace net {
 struct RedirectInfo;
@@ -24,7 +23,7 @@
 struct URLLoaderCompletionStatus;
 }
 
-namespace content {
+namespace blink {
 
 // This is implemented by our custom resource loader within content. The Peer
 // and it's bridge should have identical lifetimes as they represent each end of
@@ -33,7 +32,7 @@
 // These callbacks mirror net::URLRequest::Delegate and the order and
 // conditions in which they will be called are identical. See url_request.h
 // for more information.
-class CONTENT_EXPORT RequestPeer {
+class BLINK_PLATFORM_EXPORT WebRequestPeer {
  public:
   // Called as upload progress is made.
   // note: only for requests with upload progress enabled.
@@ -73,9 +72,9 @@
   virtual void OnCompletedRequest(
       const network::URLLoaderCompletionStatus& status) = 0;
 
-  virtual ~RequestPeer() {}
+  virtual ~WebRequestPeer() {}
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_PUBLIC_RENDERER_REQUEST_PEER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_REQUEST_PEER_H_
diff --git a/third_party/blink/public/platform/web_url_loader.h b/third_party/blink/public/platform/web_url_loader.h
index 18f605f..2db7b64 100644
--- a/third_party/blink/public/platform/web_url_loader.h
+++ b/third_party/blink/public/platform/web_url_loader.h
@@ -94,8 +94,19 @@
       std::unique_ptr<ResourceLoadInfoNotifierWrapper>,
       WebURLLoaderClient*) = 0;
 
+  // |kDeferred| is when an asynchronous load is suspended.
+  // |kDeferredWithBackForwardCache| is when an asynchronous load is suspended
+  // with BackForwardCache, and BackForwardCache entry can be evicted when
+  // redirects etc. happen.
+  // |kNotDeferred| is when an asynchronous load is resumed.
+  // SetDefersLoading can be called with any value at any point.
+  enum class DeferType {
+    kDeferred,
+    kDeferredWithBackForwardCache,
+    kNotDeferred
+  };
   // Suspends/resumes an asynchronous load.
-  virtual void SetDefersLoading(bool) = 0;
+  virtual void SetDefersLoading(DeferType) = 0;
 
   // Notifies the loader that the priority of a WebURLRequest has changed from
   // its previous value. For example, a preload request starts with low
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
index 0b9cd52a..c7cf683 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
@@ -108,7 +108,7 @@
         std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
             resource_load_info_notifier_wrapper,
         WebURLLoaderClient*) override {}
-    void SetDefersLoading(bool) override {}
+    void SetDefersLoading(WebURLLoader::DeferType) override {}
     void DidChangePriority(WebURLRequest::Priority, int) override {
       NOTREACHED();
     }
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index 7c021ad4..0763ae5 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -301,8 +301,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event_init.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_set_inner_html_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_set_inner_html_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni
index 9a546b3..768d466 100644
--- a/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -162,7 +162,6 @@
           "//third_party/blink/renderer/core/dom/pointer_lock_options.idl",
           "//third_party/blink/renderer/core/dom/processing_instruction.idl",
           "//third_party/blink/renderer/core/dom/range.idl",
-          "//third_party/blink/renderer/core/dom/set_inner_html_options.idl",
           "//third_party/blink/renderer/core/dom/shadow_root.idl",
           "//third_party/blink/renderer/core/dom/shadow_root_init.idl",
           "//third_party/blink/renderer/core/dom/static_range.idl",
@@ -611,8 +610,10 @@
           "//third_party/blink/renderer/core/timing/largest_contentful_paint.idl",
           "//third_party/blink/renderer/core/timing/layout_shift.idl",
           "//third_party/blink/renderer/core/timing/layout_shift_attribution.idl",
-          "//third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl",
-          "//third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl",
+          "//third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl",
+          "//third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl",
+          "//third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl",
+          "//third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl",
           "//third_party/blink/renderer/core/timing/memory_info.idl",
           "//third_party/blink/renderer/core/timing/performance.idl",
           "//third_party/blink/renderer/core/timing/performance_element_timing.idl",
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc
index c6b95e1..8ae37d6 100644
--- a/third_party/blink/renderer/controller/blink_initializer.cc
+++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -47,7 +47,6 @@
 #include "third_party/blink/renderer/controller/dev_tools_frontend_impl.h"
 #include "third_party/blink/renderer/controller/performance_manager/renderer_resource_coordinator_impl.h"
 #include "third_party/blink/renderer/controller/performance_manager/v8_detailed_memory_reporter_impl.h"
-#include "third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.h"
 #include "third_party/blink/renderer/core/animation/animation_clock.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/execution_context/agent.h"
@@ -167,7 +166,6 @@
 
   // Initialize performance manager.
   RendererResourceCoordinatorImpl::MaybeInitialize();
-  V8WorkerMemoryReporter::RegisterWebMemoryReporter();
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc b/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc
index c363490..c92a662 100644
--- a/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc
+++ b/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc
@@ -9,7 +9,6 @@
 
 #include "base/check.h"
 #include "base/time/time.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory_breakdown.h"
 #include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
@@ -234,50 +233,4 @@
   state_ = State::kDone;
 }
 
-namespace {
-
-// Used by the performance.measureMemory Web API. It forwards the incoming
-// memory measurement request to V8WorkerMemoryReporter and adapts the result
-// to match the format of the Web API.
-//
-// It will be removed in the future when performance.measureMemory switches
-// to a mojo-based implementation that queries PerformanceManager in the
-// browser process.
-class WebMemoryReporter : public MeasureMemoryController::V8MemoryReporter {
-  void GetMemoryUsage(MeasureMemoryController::ResultCallback callback,
-                      v8::MeasureMemoryExecution execution) override {
-    V8WorkerMemoryReporter::GetMemoryUsage(
-        WTF::Bind(&WebMemoryReporter::ForwardResults, std::move(callback)),
-        execution);
-  }
-
-  // Adapts the result to match the format expected by MeasureMemoryController.
-  static void ForwardResults(MeasureMemoryController::ResultCallback callback,
-                             const V8WorkerMemoryReporter::Result& result) {
-    HeapVector<Member<MeasureMemoryBreakdown>> new_result;
-    const String kDedicatedWorkerGlobalScope("DedicatedWorkerGlobalScope");
-    const String kJS("JS");
-    const Vector<String> kWorkerMemoryTypes = {kDedicatedWorkerGlobalScope,
-                                               kJS};
-    const Vector<String> kEmptyAttribution = {};
-    for (const auto& worker : result.workers) {
-      if (worker.token.Is<DedicatedWorkerToken>()) {
-        MeasureMemoryBreakdown* entry = MeasureMemoryBreakdown::Create();
-        entry->setBytes(worker.bytes);
-        entry->setUserAgentSpecificTypes(kWorkerMemoryTypes);
-        entry->setAttribution(kEmptyAttribution);
-        new_result.push_back(entry);
-      }
-    }
-    std::move(callback).Run(new_result);
-  }
-};
-
-}  // anonymous namespace
-
-void V8WorkerMemoryReporter::RegisterWebMemoryReporter() {
-  MeasureMemoryController::SetDedicatedWorkerMemoryReporter(
-      new WebMemoryReporter());
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.h b/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.h
index e60db41b..38e7ae2 100644
--- a/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.h
+++ b/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.h
@@ -60,9 +60,6 @@
   static void NotifyMeasurementFailure(WorkerThread*,
                                        base::WeakPtr<V8WorkerMemoryReporter>);
 
-  // Injects the implementation for the performance.measureMemory Web API.
-  static void RegisterWebMemoryReporter();
-
  private:
   // The initial state is kWaiting.
   // Transition from kWaiting to kDone happens on two events:
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni
index eec15ef4..3b079d4 100644
--- a/third_party/blink/renderer/core/core_idl_files.gni
+++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -652,7 +652,6 @@
                     "dom/idle_request_options.idl",
                     "dom/mutation_observer_init.idl",
                     "dom/pointer_lock_options.idl",
-                    "dom/set_inner_html_options.idl",
                     "dom/shadow_root_init.idl",
                     "dom/events/add_event_listener_options.idl",
                     "dom/events/custom_event_init.idl",
@@ -746,8 +745,10 @@
                     "streams/readable_writable_pair.idl",
                     "streams/stream_pipe_options.idl",
                     "streams/queuing_strategy_init.idl",
-                    "timing/measure_memory/measure_memory.idl",
-                    "timing/measure_memory/measure_memory_breakdown.idl",
+                    "timing/measure_memory/memory_measurement.idl",
+                    "timing/measure_memory/memory_breakdown_entry.idl",
+                    "timing/measure_memory/memory_attribution.idl",
+                    "timing/measure_memory/memory_attribution_container.idl",
                     "timing/performance_mark_options.idl",
                     "timing/performance_measure_options.idl",
                     "timing/performance_observer_init.idl",
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 94eae66b..16c47ad 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -44,7 +44,6 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_pointer_lock_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_set_inner_html_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
 #include "third_party/blink/renderer/core/accessibility/ax_context.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
@@ -4467,13 +4466,11 @@
 }
 
 void Element::SetInnerHTMLInternal(const String& html,
-                                   const SetInnerHTMLOptions* options,
+                                   bool include_shadow_roots,
                                    ExceptionState& exception_state) {
   if (html.IsEmpty() && !HasNonInBodyInsertionMode()) {
     setTextContent(html);
   } else {
-    bool include_shadow_roots =
-        options->hasIncludeShadowRoots() && options->includeShadowRoots();
     if (DocumentFragment* fragment = CreateFragmentForInnerOuterHTML(
             html, this, kAllowScriptingContent, "innerHTML",
             include_shadow_roots, exception_state)) {
@@ -4493,16 +4490,13 @@
 void Element::setInnerHTML(const String& html,
                            ExceptionState& exception_state) {
   probe::BreakableLocation(GetExecutionContext(), "Element.setInnerHTML");
-  const SetInnerHTMLOptions options;
-  SetInnerHTMLInternal(html, &options, exception_state);
+  SetInnerHTMLInternal(html, /*include_shadow_roots=*/false, exception_state);
 }
 
-void Element::setInnerHTMLWithOptions(const String& html,
-                                      const SetInnerHTMLOptions* options,
-                                      ExceptionState& exception_state) {
-  DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
-      GetExecutionContext()));
-  SetInnerHTMLInternal(html, options, exception_state);
+void Element::setInnerHTMLWithDeclarativeShadowDOMForTesting(
+    const String& html) {
+  SetInnerHTMLInternal(html, /*include_shadow_roots=*/true,
+                       ASSERT_NO_EXCEPTION);
 }
 
 String Element::getInnerHTML(const GetInnerHTMLOptions* options) const {
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index d99e36e..528fcab 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -66,7 +66,6 @@
 class FloatQuad;
 class FloatSize;
 class FocusOptions;
-class SetInnerHTMLOptions;
 class GetInnerHTMLOptions;
 class HTMLTemplateElement;
 class Image;
@@ -698,9 +697,7 @@
   String innerHTML() const;
   String outerHTML() const;
   void setInnerHTML(const String&, ExceptionState& = ASSERT_NO_EXCEPTION);
-  void setInnerHTMLWithOptions(const String&,
-                               const SetInnerHTMLOptions*,
-                               ExceptionState& = ASSERT_NO_EXCEPTION);
+  void setInnerHTMLWithDeclarativeShadowDOMForTesting(const String& html);
   String getInnerHTML(const GetInnerHTMLOptions* options) const;
   void setOuterHTML(const String&, ExceptionState& = ASSERT_NO_EXCEPTION);
 
@@ -1190,7 +1187,7 @@
                                                         const AtomicString&);
 
   void SetInnerHTMLInternal(const String&,
-                            const SetInnerHTMLOptions*,
+                            bool include_shadow_roots,
                             ExceptionState&);
 
   ElementRareData* GetElementRareData() const;
diff --git a/third_party/blink/renderer/core/dom/element.idl b/third_party/blink/renderer/core/dom/element.idl
index 5ddc26a5..cd37b91 100644
--- a/third_party/blink/renderer/core/dom/element.idl
+++ b/third_party/blink/renderer/core/dom/element.idl
@@ -96,8 +96,7 @@
     [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute [TreatNullAs=EmptyString, StringContext=TrustedHTML] DOMString outerHTML;
     [CEReactions, CustomElementCallbacks, RaisesException] void insertAdjacentHTML(DOMString position, HTMLString text);
 
-    // Declarative Shadow DOM setInnerHTML/getInnerHTML() functions.
-    [Affects=Nothing, RuntimeEnabled=DeclarativeShadowDOM, RuntimeCallStatsCounter=ElementSetInnerHTML, RaisesException, ImplementedAs=setInnerHTMLWithOptions] void setInnerHTML(HTMLString html, optional SetInnerHTMLOptions options = {});
+    // Declarative Shadow DOM getInnerHTML() function.
     [Affects=Nothing, RuntimeEnabled=DeclarativeShadowDOM, RuntimeCallStatsCounter=ElementGetInnerHTML] HTMLString getInnerHTML(optional GetInnerHTMLOptions options = {});
 
     // Pointer Lock
diff --git a/third_party/blink/renderer/core/dom/shadow_root.cc b/third_party/blink/renderer/core/dom/shadow_root.cc
index b690005..b3086ac 100644
--- a/third_party/blink/renderer/core/dom/shadow_root.cc
+++ b/third_party/blink/renderer/core/dom/shadow_root.cc
@@ -28,7 +28,6 @@
 
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_get_inner_html_options.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_set_inner_html_options.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
@@ -133,30 +132,13 @@
       include_closed_roots);
 }
 
-void ShadowRoot::SetInnerHTMLInternal(const String& html,
-                                      const SetInnerHTMLOptions* options,
-                                      ExceptionState& exception_state) {
-  bool include_shadow_roots =
-      options->hasIncludeShadowRoots() && options->includeShadowRoots();
-  if (DocumentFragment* fragment = CreateFragmentForInnerOuterHTML(
-          html, &host(), kAllowScriptingContent, "innerHTML",
-          include_shadow_roots, exception_state)) {
-    ReplaceChildrenWithFragment(this, fragment, exception_state);
-  }
-}
-
 void ShadowRoot::setInnerHTML(const String& html,
                               ExceptionState& exception_state) {
-  const SetInnerHTMLOptions options;
-  SetInnerHTMLInternal(html, &options, exception_state);
-}
-
-void ShadowRoot::setInnerHTMLWithOptions(const String& html,
-                                         const SetInnerHTMLOptions* options,
-                                         ExceptionState& exception_state) {
-  DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled(
-      GetExecutionContext()));
-  SetInnerHTMLInternal(html, options, exception_state);
+  if (DocumentFragment* fragment = CreateFragmentForInnerOuterHTML(
+          html, &host(), kAllowScriptingContent, "innerHTML",
+          /*include_shadow_roots=*/false, exception_state)) {
+    ReplaceChildrenWithFragment(this, fragment, exception_state);
+  }
 }
 
 void ShadowRoot::RebuildLayoutTree(WhitespaceAttacher& whitespace_attacher) {
diff --git a/third_party/blink/renderer/core/dom/shadow_root.h b/third_party/blink/renderer/core/dom/shadow_root.h
index e46afe2..7fedf6b 100644
--- a/third_party/blink/renderer/core/dom/shadow_root.h
+++ b/third_party/blink/renderer/core/dom/shadow_root.h
@@ -40,7 +40,6 @@
 
 class Document;
 class ExceptionState;
-class SetInnerHTMLOptions;
 class GetInnerHTMLOptions;
 class ShadowRootV0;
 class SlotAssignment;
@@ -141,9 +140,6 @@
   String innerHTML() const;
   String getInnerHTML(const GetInnerHTMLOptions* options) const;
   void setInnerHTML(const String&, ExceptionState& = ASSERT_NO_EXCEPTION);
-  void setInnerHTMLWithOptions(const String&,
-                               const SetInnerHTMLOptions*,
-                               ExceptionState& = ASSERT_NO_EXCEPTION);
 
   Node* Clone(Document&, CloneChildrenFlag) const override;
 
@@ -194,10 +190,6 @@
 
   SlotAssignment& EnsureSlotAssignment();
 
-  void SetInnerHTMLInternal(const String&,
-                            const SetInnerHTMLOptions*,
-                            ExceptionState&);
-
   void AddChildShadowRoot() { ++child_shadow_root_count_; }
   void RemoveChildShadowRoot() {
     DCHECK_GT(child_shadow_root_count_, 0u);
diff --git a/third_party/blink/renderer/core/dom/shadow_root.idl b/third_party/blink/renderer/core/dom/shadow_root.idl
index 8039552..f0a57be3 100644
--- a/third_party/blink/renderer/core/dom/shadow_root.idl
+++ b/third_party/blink/renderer/core/dom/shadow_root.idl
@@ -36,8 +36,7 @@
     readonly attribute boolean delegatesFocus;
     [RuntimeEnabled=ManualSlotting] readonly attribute SlotAssignmentMode slotAssignment;
 
-    // Declarative Shadow DOM setInnerHTML/getInnerHTML() functions.
-    [Affects=Nothing, RuntimeEnabled=DeclarativeShadowDOM, RuntimeCallStatsCounter=ElementSetInnerHTML, RaisesException, ImplementedAs=setInnerHTMLWithOptions] void setInnerHTML(HTMLString html, optional SetInnerHTMLOptions options = {});
+    // Declarative Shadow DOM getInnerHTML() function.
     [Affects=Nothing, RuntimeEnabled=DeclarativeShadowDOM, RuntimeCallStatsCounter=ElementGetInnerHTML] HTMLString getInnerHTML(optional GetInnerHTMLOptions options = {});
 };
 
diff --git a/third_party/blink/renderer/core/dom/slot_assignment_test.cc b/third_party/blink/renderer/core/dom/slot_assignment_test.cc
index 9e52fd4a..6e60db4 100644
--- a/third_party/blink/renderer/core/dom/slot_assignment_test.cc
+++ b/third_party/blink/renderer/core/dom/slot_assignment_test.cc
@@ -5,7 +5,6 @@
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_set_inner_html_options.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/node.h"
@@ -70,9 +69,7 @@
 
 void SlotAssignmentTest::SetBody(const char* html) {
   Element* body = GetDocument().body();
-  SetInnerHTMLOptions options;
-  options.setIncludeShadowRoots(true);
-  body->setInnerHTMLWithOptions(String::FromUTF8(html), &options);
+  body->setInnerHTMLWithDeclarativeShadowDOMForTesting(String::FromUTF8(html));
   RemoveWhiteSpaceOnlyTextNode(*body);
 }
 
diff --git a/third_party/blink/renderer/core/editing/position.cc b/third_party/blink/renderer/core/editing/position.cc
index b3569b7..83199ae9 100644
--- a/third_party/blink/renderer/core/editing/position.cc
+++ b/third_party/blink/renderer/core/editing/position.cc
@@ -592,6 +592,10 @@
   if (pos.IsOffsetInAnchor()) {
     if (anchor->IsCharacterDataNode())
       return PositionInFlatTree(anchor, pos.ComputeOffsetInContainerNode());
+    if (IsActiveV0InsertionPoint(*anchor)) {
+      return ToPositionInFlatTree(Position(NodeTraversal::Parent(*anchor),
+                                           NodeTraversal::Index(*anchor)));
+    }
     DCHECK(!anchor->IsElementNode() || anchor->CanParticipateInFlatTree());
     int offset = pos.ComputeOffsetInContainerNode();
     Node* child = NodeTraversal::ChildAt(*anchor, offset);
@@ -620,9 +624,11 @@
 
   if (anchor->IsShadowRoot())
     return PositionInFlatTree(anchor->OwnerShadowHost(), pos.AnchorType());
+  if (IsActiveV0InsertionPoint(*anchor))
+    return ToPositionInFlatTree(pos.ToOffsetInAnchor());
+  DCHECK(anchor->CanParticipateInFlatTree());
   if (pos.IsBeforeAnchor() || pos.IsAfterAnchor()) {
-    if (anchor->CanParticipateInFlatTree() &&
-        !FlatTreeTraversal::Parent(*anchor)) {
+    if (!FlatTreeTraversal::Parent(*anchor)) {
       // For Before/AfterAnchor, if |anchor| doesn't have parent in the flat
       // tree, there is no valid corresponding PositionInFlatTree.
       // Since this function is a primitive function, we do not adjust |pos|
diff --git a/third_party/blink/renderer/core/editing/position_test.cc b/third_party/blink/renderer/core/editing/position_test.cc
index c43cbfa..890d06f 100644
--- a/third_party/blink/renderer/core/editing/position_test.cc
+++ b/third_party/blink/renderer/core/editing/position_test.cc
@@ -228,6 +228,62 @@
             ToPositionInFlatTree(Position(shadow_root, 0)));
 }
 
+TEST_F(PositionTest, ToPositionInFlatTreeWithV0InsertionPoint1) {
+  SetBodyContent("<p id=host></p>");
+  ShadowRoot* shadow_root = SetShadowContent("<content></content>", "host");
+  Element* host = GetDocument().getElementById("host");
+  Node* content = shadow_root->QuerySelector("content");
+  EXPECT_FALSE(content->CanParticipateInFlatTree());
+  EXPECT_EQ(PositionInFlatTree(host, 0),
+            ToPositionInFlatTree(Position::BeforeNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 0),
+            ToPositionInFlatTree(Position::FirstPositionInNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 0),
+            ToPositionInFlatTree(Position(content, 0)));
+  EXPECT_EQ(PositionInFlatTree(host, 0),
+            ToPositionInFlatTree(Position::LastPositionInNode(*content)));
+  EXPECT_EQ(PositionInFlatTree::LastPositionInNode(*host),
+            ToPositionInFlatTree(Position::AfterNode(*content)));
+}
+
+TEST_F(PositionTest, ToPositionInFlatTreeWithV0InsertionPoint2) {
+  SetBodyContent("<p id=host></p>");
+  ShadowRoot* shadow_root =
+      SetShadowContent("foo<content></content>bar", "host");
+  Element* host = GetDocument().getElementById("host");
+  Node* content = shadow_root->QuerySelector("content");
+  EXPECT_FALSE(content->CanParticipateInFlatTree());
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position::BeforeNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position::FirstPositionInNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position(content, 0)));
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position::LastPositionInNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position::AfterNode(*content)));
+}
+
+TEST_F(PositionTest, ToPositionInFlatTreeWithV0InsertionPoint3) {
+  SetBodyContent("<p id=host><b>11</b><b>22</b></p>");
+  ShadowRoot* shadow_root =
+      SetShadowContent("foo<content></content>bar", "host");
+  Element* host = GetDocument().getElementById("host");
+  Node* content = shadow_root->QuerySelector("content");
+  EXPECT_FALSE(content->CanParticipateInFlatTree());
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position::BeforeNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position::FirstPositionInNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position(content, 0)));
+  EXPECT_EQ(PositionInFlatTree(host, 1),
+            ToPositionInFlatTree(Position::LastPositionInNode(*content)));
+  EXPECT_EQ(PositionInFlatTree(host, 3),
+            ToPositionInFlatTree(Position::AfterNode(*content)));
+}
+
 TEST_F(PositionTest, NullPositionNotConnected) {
   EXPECT_FALSE(Position().IsConnected());
   EXPECT_FALSE(PositionInFlatTree().IsConnected());
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc
index 48a620da..c7398cb 100644
--- a/third_party/blink/renderer/core/execution_context/execution_context.cc
+++ b/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -233,6 +233,15 @@
   return lifecycle_state_ == mojom::blink::FrameLifecycleState::kPaused;
 }
 
+WebURLLoader::DeferType ExecutionContext::DeferType() const {
+  if (lifecycle_state_ == mojom::blink::FrameLifecycleState::kFrozen) {
+    return WebURLLoader::DeferType::kDeferredWithBackForwardCache;
+  } else if (lifecycle_state_ == mojom::blink::FrameLifecycleState::kPaused) {
+    return WebURLLoader::DeferType::kDeferred;
+  }
+  return WebURLLoader::DeferType::kNotDeferred;
+}
+
 bool ExecutionContext::IsLoadDeferred() const {
   return lifecycle_state_ == mojom::blink::FrameLifecycleState::kPaused ||
          lifecycle_state_ == mojom::blink::FrameLifecycleState::kFrozen;
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h
index e58b0015..c1dcadaf 100644
--- a/third_party/blink/renderer/core/execution_context/execution_context.h
+++ b/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -44,6 +44,7 @@
 #include "third_party/blink/public/mojom/feature_policy/policy_disposition.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/v8_cache_options.mojom-blink.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
@@ -243,6 +244,7 @@
   virtual void AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr) = 0;
 
   bool IsContextPaused() const;
+  WebURLLoader::DeferType DeferType() const;
   bool IsContextDestroyed() const { return is_context_destroyed_; }
   mojom::FrameLifecycleState ContextPauseState() const {
     return lifecycle_state_;
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index e4d24cb..abe3660 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2366,8 +2366,8 @@
     return;
   paused_ = is_paused;
 
-  GetDocument()->Fetcher()->SetDefersLoading(IsLoadDeferred());
-  Loader().SetDefersLoading(IsLoadDeferred());
+  GetDocument()->Fetcher()->SetDefersLoading(GetLoadDeferType());
+  Loader().SetDefersLoading(GetLoadDeferType());
   // TODO(altimin): Move this to PageScheduler level.
   GetFrameScheduler()->SetPaused(is_paused);
 }
@@ -2376,6 +2376,14 @@
   return frozen_ || paused_;
 }
 
+WebURLLoader::DeferType LocalFrame::GetLoadDeferType() {
+  if (GetPage()->GetPageScheduler()->IsInBackForwardCache())
+    return WebURLLoader::DeferType::kDeferredWithBackForwardCache;
+  if (paused_ || frozen_)
+    return WebURLLoader::DeferType::kDeferred;
+  return WebURLLoader::DeferType::kNotDeferred;
+}
+
 void LocalFrame::DidFreeze() {
   DCHECK(IsAttached());
   GetDocument()->DispatchFreezeEvent();
@@ -2390,8 +2398,12 @@
         performance_manager::mojom::LifecycleState::kFrozen);
   }
 
-  GetDocument()->Fetcher()->SetDefersLoading(true);
-  Loader().SetDefersLoading(true);
+  WebURLLoader::DeferType defer =
+      GetPage()->GetPageScheduler()->IsInBackForwardCache()
+          ? WebURLLoader::DeferType::kDeferredWithBackForwardCache
+          : WebURLLoader::DeferType::kDeferred;
+  GetDocument()->Fetcher()->SetDefersLoading(defer);
+  Loader().SetDefersLoading(defer);
 }
 
 void LocalFrame::DidResume() {
@@ -2408,8 +2420,11 @@
     document_resource_coordinator->SetLifecycleState(
         performance_manager::mojom::LifecycleState::kRunning);
   }
-  GetDocument()->Fetcher()->SetDefersLoading(IsLoadDeferred());
-  Loader().SetDefersLoading(IsLoadDeferred());
+
+  // TODO(yuzus): Figure out if we should call GetLoadDeferType().
+  GetDocument()->Fetcher()->SetDefersLoading(
+      WebURLLoader::DeferType::kNotDeferred);
+  Loader().SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
 }
 
 void LocalFrame::MaybeLogAdClickNavigation() {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index 37620fcc..a8c5cee0 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -722,6 +722,7 @@
   PolicyContainer* GetPolicyContainer() { return policy_container_.get(); }
   void SetPolicyContainer(std::unique_ptr<PolicyContainer> container);
 
+  WebURLLoader::DeferType GetLoadDeferType();
   bool IsLoadDeferred();
 
  private:
diff --git a/third_party/blink/renderer/core/frame/navigator_automation_information.idl b/third_party/blink/renderer/core/frame/navigator_automation_information.idl
index 62907d00..3d7ca44 100644
--- a/third_party/blink/renderer/core/frame/navigator_automation_information.idl
+++ b/third_party/blink/renderer/core/frame/navigator_automation_information.idl
@@ -7,5 +7,5 @@
 [
     RuntimeEnabled=AutomationControlled
 ] interface mixin NavigatorAutomationInformation {
-    [LegacyUnforgeable] readonly attribute boolean webdriver;
+    readonly attribute boolean webdriver;
 };
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
index e96d830..1d61e2d 100644
--- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
@@ -433,7 +433,7 @@
         WTF::Bind(&InspectorEmulationAgent::VirtualTimeBudgetExpired,
                   WrapWeakPersistent(this)));
     for (DocumentLoader* loader : pending_document_loaders_)
-      loader->SetDefersLoading(false);
+      loader->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
     pending_document_loaders_.clear();
   }
   if (new_policy.max_virtual_time_task_starvation_count) {
@@ -678,7 +678,7 @@
       protocol::Emulation::VirtualTimePolicyEnum::Pause) {
     return;
   }
-  loader->SetDefersLoading(true);
+  loader->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   pending_document_loaders_.push_back(loader);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index 27877a27..3931d9e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -1050,6 +1050,20 @@
 void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(
     const NGPreviousInflowPosition& previous_inflow_position,
     NGBlockNode child) {
+  if (ConstraintSpace().HasBlockFragmentation()) {
+    // Forced breaks cannot be specified directly on out-of-flow positioned
+    // elements, but if the preceding block has a forced break after, we need to
+    // break before it. Note that we really only need to do this if block-start
+    // offset is auto (but it's harmless to do it also when it's non-auto).
+    EBreakBetween break_between =
+        container_builder_.JoinedBreakBetweenValue(EBreakBetween::kAuto);
+    if (IsForcedBreakValue(ConstraintSpace(), break_between)) {
+      container_builder_.AddBreakBeforeChild(child, kBreakAppealPerfect,
+                                             /* is_forced_break*/ true);
+      return;
+    }
+  }
+
   DCHECK(child.IsOutOfFlowPositioned());
   LogicalOffset static_offset = {BorderScrollbarPadding().inline_start,
                                  previous_inflow_position.logical_block_offset};
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 179477c..a2b2438 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1057,7 +1057,7 @@
     LoadFailed(ResourceError::CancelledError(Url()));
 }
 
-void DocumentLoader::SetDefersLoading(bool defers) {
+void DocumentLoader::SetDefersLoading(WebURLLoader::DeferType defers) {
   defers_loading_ = defers;
   if (body_loader_)
     body_loader_->SetDefersLoading(defers);
@@ -1257,8 +1257,7 @@
 
   InitializePrefetchedSignedExchangeManager();
 
-  if (defers_loading_)
-    body_loader_->SetDefersLoading(true);
+  body_loader_->SetDefersLoading(defers_loading_);
 }
 
 void DocumentLoader::StartLoadingResponse() {
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h
index 3af4329..64b0c81 100644
--- a/third_party/blink/renderer/core/loader/document_loader.h
+++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -205,7 +205,7 @@
       bool has_event,
       std::unique_ptr<WebDocumentLoader::ExtraData>);
 
-  void SetDefersLoading(bool defers);
+  void SetDefersLoading(WebURLLoader::DeferType defers);
 
   DocumentLoadTiming& GetTiming() { return document_load_timing_; }
 
@@ -518,7 +518,8 @@
   scoped_refptr<SharedBuffer> data_buffer_;
   const base::UnguessableToken devtools_navigation_token_;
 
-  bool defers_loading_ = false;
+  WebURLLoader::DeferType defers_loading_ =
+      WebURLLoader::DeferType::kNotDeferred;
 
   // Whether this load request comes with a sitcky user activation.
   const bool had_sticky_activation_ = false;
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 0c4725a..bd91e546 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -278,7 +278,7 @@
   return frame_->Client();
 }
 
-void FrameLoader::SetDefersLoading(bool defers) {
+void FrameLoader::SetDefersLoading(WebURLLoader::DeferType defers) {
   if (frame_->GetDocument())
     frame_->GetDocument()->Fetcher()->SetDefersLoading(defers);
   if (document_loader_)
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h
index 646a6b68..707d79a4 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -42,6 +42,7 @@
 #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/page_state/page_state.mojom-blink.h"
 #include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/public/web/web_document_loader.h"
 #include "third_party/blink/public/web/web_frame_load_type.h"
 #include "third_party/blink/public/web/web_navigation_type.h"
@@ -132,7 +133,7 @@
 
   DocumentLoader* GetDocumentLoader() const { return document_loader_.Get(); }
 
-  void SetDefersLoading(bool);
+  void SetDefersLoading(WebURLLoader::DeferType defer);
 
   void DidExplicitOpen();
 
diff --git a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc
index 29e0c88..17f6344e 100644
--- a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc
+++ b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc
@@ -84,6 +84,12 @@
   return frame->GetPage()->Paused();
 }
 
+WebURLLoader::DeferType FrameResourceFetcherProperties::DeferType() const {
+  LocalFrame* frame = document_->GetFrame();
+  DCHECK(frame);
+  return frame->GetLoadDeferType();
+}
+
 bool FrameResourceFetcherProperties::IsLoadDeferred() const {
   LocalFrame* frame = document_->GetFrame();
   DCHECK(frame);
diff --git a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h
index f9c804f..b16de03 100644
--- a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h
+++ b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h
@@ -35,6 +35,7 @@
   ControllerServiceWorkerMode GetControllerServiceWorkerMode() const override;
   int64_t ServiceWorkerId() const override;
   bool IsPaused() const override;
+  WebURLLoader::DeferType DeferType() const override;
   bool IsDetached() const override { return false; }
   bool IsLoadDeferred() const override;
   bool IsLoadComplete() const override;
diff --git a/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc b/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc
index 9bf06e47..7cb71af5 100644
--- a/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc
+++ b/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc
@@ -108,7 +108,7 @@
         no_mime_sniffing, std::move(resource_load_info_notifier_wrapper),
         WTF::Unretained(client)));
   }
-  void SetDefersLoading(bool value) override {
+  void SetDefersLoading(DeferType value) override {
     if (url_loader_) {
       url_loader_->SetDefersLoading(value);
       return;
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc
index 7efc0ec7..a52641b 100644
--- a/third_party/blink/renderer/core/loader/threadable_loader.cc
+++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -213,8 +213,11 @@
 }
 
 void ThreadableLoader::SetDefersLoading(bool value) {
-  if (GetResource() && GetResource()->Loader())
-    GetResource()->Loader()->SetDefersLoading(value);
+  if (GetResource() && GetResource()->Loader()) {
+    GetResource()->Loader()->SetDefersLoading(
+        value ? WebURLLoader::DeferType::kDeferred
+              : WebURLLoader::DeferType::kNotDeferred);
+  }
 }
 
 void ThreadableLoader::Clear() {
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.h b/third_party/blink/renderer/core/loader/threadable_loader.h
index 445793e4..6963b89 100644
--- a/third_party/blink/renderer/core/loader/threadable_loader.h
+++ b/third_party/blink/renderer/core/loader/threadable_loader.h
@@ -37,6 +37,7 @@
 #include "base/macros.h"
 #include "services/network/public/mojom/fetch_api.mojom-blink.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
diff --git a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc
index c194c617..85ddc39 100644
--- a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc
+++ b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc
@@ -38,6 +38,10 @@
   return global_scope_->IsContextPaused();
 }
 
+WebURLLoader::DeferType WorkerResourceFetcherProperties::DeferType() const {
+  return global_scope_->DeferType();
+}
+
 bool WorkerResourceFetcherProperties::IsLoadDeferred() const {
   return global_scope_->IsLoadDeferred();
 }
diff --git a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h
index 5944709d..bfb7f57 100644
--- a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h
+++ b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h
@@ -42,6 +42,7 @@
     return -1;
   }
   bool IsPaused() const override;
+  WebURLLoader::DeferType DeferType() const override;
   bool IsDetached() const override { return false; }
   bool IsLoadDeferred() const override;
   bool IsLoadComplete() const override { return false; }
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index 3b568ee3..eb7cdb9 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -117,7 +117,7 @@
       WebURLLoaderClient* client) override {
     NOTREACHED();
   }
-  void SetDefersLoading(bool) override {}
+  void SetDefersLoading(DeferType) override {}
   void DidChangePriority(WebURLRequest::Priority, int) override {}
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForBodyLoader()
       override {
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index d1e348f..e1d05f5 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -3005,25 +3005,16 @@
 
 namespace {
 
-class AddOneFunction : public ScriptFunction {
+class AddOneFunction : public NewScriptFunction::Callable {
  public:
-  static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) {
-    AddOneFunction* self = MakeGarbageCollected<AddOneFunction>(script_state);
-    return self->BindToV8Function();
-  }
-
-  explicit AddOneFunction(ScriptState* script_state)
-      : ScriptFunction(script_state) {}
-
- private:
-  ScriptValue Call(ScriptValue value) override {
+  ScriptValue Call(ScriptState* script_state, ScriptValue value) override {
     v8::Local<v8::Value> v8_value = value.V8Value();
     DCHECK(v8_value->IsNumber());
     int32_t int_value =
         static_cast<int32_t>(v8_value.As<v8::Integer>()->Value());
     return ScriptValue(
-        GetScriptState()->GetIsolate(),
-        v8::Integer::New(GetScriptState()->GetIsolate(), int_value + 1));
+        script_state->GetIsolate(),
+        v8::Integer::New(script_state->GetIsolate(), int_value + 1));
   }
 };
 
@@ -3047,7 +3038,8 @@
 
 ScriptPromise Internals::addOneToPromise(ScriptState* script_state,
                                          ScriptPromise promise) {
-  return promise.Then(AddOneFunction::CreateFunction(script_state));
+  return promise.Then(MakeGarbageCollected<NewScriptFunction>(
+      script_state, MakeGarbageCollected<AddOneFunction>()));
 }
 
 ScriptPromise Internals::promiseCheck(ScriptState* script_state,
diff --git a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl
deleted file mode 100644
index e90820e6..0000000
--- a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl
+++ /dev/null
@@ -1,12 +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.
-
-// https://github.com/ulan/performance-measure-memory.
-
-// A single entry of performance.measureMemory() result.
-dictionary MeasureMemoryBreakdown {
-  unsigned long long bytes;
-  sequence<DOMString> attribution;
-  sequence<DOMString> userAgentSpecificTypes;
-};
diff --git a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc
index b689e13f..9c362ef8 100644
--- a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc
+++ b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc
@@ -9,8 +9,8 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory_breakdown.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_breakdown_entry.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_measurement.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -26,14 +26,6 @@
 
 namespace blink {
 
-static MeasureMemoryController::V8MemoryReporter*
-    g_dedicated_worker_memory_reporter_ = nullptr;
-
-void MeasureMemoryController::SetDedicatedWorkerMemoryReporter(
-    V8MemoryReporter* reporter) {
-  g_dedicated_worker_memory_reporter_ = reporter;
-}
-
 MeasureMemoryController::MeasureMemoryController(
     base::PassKey<MeasureMemoryController>,
     v8::Isolate* isolate,
@@ -51,8 +43,6 @@
 
 void MeasureMemoryController::Trace(Visitor* visitor) const {
   visitor->Trace(promise_resolver_);
-  visitor->Trace(main_result_);
-  visitor->Trace(worker_result_);
 }
 
 ScriptPromise MeasureMemoryController::StartMeasurement(
@@ -87,57 +77,24 @@
           WTF::Bind(&MeasureMemoryController::MainMeasurementComplete,
                     WrapPersistent(impl))),
       execution);
-  if (g_dedicated_worker_memory_reporter_) {
-    g_dedicated_worker_memory_reporter_->GetMemoryUsage(
-        WTF::Bind(&MeasureMemoryController::WorkerMeasurementComplete,
-                  WrapPersistent(impl)),
-
-        execution);
-  } else {
-    HeapVector<Member<MeasureMemoryBreakdown>> result;
-    impl->WorkerMeasurementComplete(result);
-  }
   return ScriptPromise(script_state, promise_resolver->GetPromise());
 }
 
 bool MeasureMemoryController::IsMeasureMemoryAvailable(LocalDOMWindow* window) {
-  // TODO(ulan): We should check for window.crossOriginIsolated when it ships.
-  // Until then we enable the API only for processes locked to a site
-  // similar to the precise mode of the legacy performance.memory API.
-  if (!Platform::Current()->IsLockedToSite()) {
+  if (!window || !window->CrossOriginIsolatedCapability()) {
     return false;
   }
-  // The window.crossOriginIsolated will be true only for the top-level frame.
-  // Until the flag is available we check for the top-level condition manually.
-  if (!window) {
-    return false;
-  }
+  // CrossOriginIsolated is also set for same-agent cross-origin iframe.
+  // Allow only iframes that have the same origin as the main frame.
+  // Note that COOP guarantees that all main frames have the same origin.
   LocalFrame* local_frame = window->GetFrame();
-  if (!local_frame || !local_frame->IsMainFrame()) {
+  if (!local_frame || local_frame->IsCrossOriginToMainFrame()) {
     return false;
   }
   return true;
 }
 
-void MeasureMemoryController::MainMeasurementComplete(Result result) {
-  DCHECK(!main_measurement_completed_);
-  main_result_ = result;
-  main_measurement_completed_ = true;
-  MaybeResolvePromise();
-}
-
-void MeasureMemoryController::WorkerMeasurementComplete(Result result) {
-  DCHECK(!worker_measurement_completed_);
-  worker_result_ = result;
-  worker_measurement_completed_ = true;
-  MaybeResolvePromise();
-}
-
-void MeasureMemoryController::MaybeResolvePromise() {
-  if (!main_measurement_completed_ || !worker_measurement_completed_) {
-    // Wait until we have all results.
-    return;
-  }
+void MeasureMemoryController::MainMeasurementComplete(Result breakdown) {
   if (context_.IsEmpty()) {
     // The context was garbage collected in the meantime.
     return;
@@ -145,9 +102,7 @@
   v8::HandleScope handle_scope(isolate_);
   v8::Local<v8::Context> context = context_.NewLocal(isolate_);
   v8::Context::Scope context_scope(context);
-  MeasureMemory* result = MeasureMemory::Create();
-  auto breakdown = main_result_;
-  breakdown.AppendVector(worker_result_);
+  auto* result = MemoryMeasurement::Create();
   size_t total_size = 0;
   for (auto entry : breakdown) {
     total_size += entry->bytes();
diff --git a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h
index 453c0fde..9e1a7f68 100644
--- a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h
+++ b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h
@@ -17,7 +17,7 @@
 namespace blink {
 
 class LocalDOMWindow;
-class MeasureMemoryBreakdown;
+class MemoryBreakdownEntry;
 class ScriptState;
 class ExceptionState;
 
@@ -30,7 +30,7 @@
 class MeasureMemoryController final
     : public GarbageCollected<MeasureMemoryController> {
  public:
-  using Result = HeapVector<Member<MeasureMemoryBreakdown>>;
+  using Result = HeapVector<Member<MemoryBreakdownEntry>>;
   using ResultCallback = base::OnceCallback<void(Result)>;
 
   // PerformanceManager in blink/renderer/controller uses this interface
@@ -65,18 +65,10 @@
   static bool IsMeasureMemoryAvailable(LocalDOMWindow* window);
   // Invoked when the memory of the main V8 isolate is measured.
   void MainMeasurementComplete(Result);
-  // Invoked when the memory of all dedicated workers is measured.
-  void WorkerMeasurementComplete(Result);
-  // Resolves the JS promise if both pending measurements are done.
-  void MaybeResolvePromise();
 
   v8::Isolate* isolate_;
   ScopedPersistent<v8::Context> context_;
   TraceWrapperV8Reference<v8::Promise::Resolver> promise_resolver_;
-  Result main_result_;
-  Result worker_result_;
-  bool main_measurement_completed_ = false;
-  bool worker_measurement_completed_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
index 28f6202..bde7eb2 100644
--- a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
+++ b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
@@ -8,8 +8,9 @@
 #include "third_party/blink/public/platform/web_security_origin.h"
 #include "third_party/blink/public/web/web_frame.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory_breakdown.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_attribution.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_breakdown_entry.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_measurement.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/frame.h"
@@ -63,11 +64,9 @@
   const SecurityOrigin* security_origin =
       execution_context->GetSecurityContext().GetSecurityOrigin();
   if (!original_security_origin->IsSameOriginWith(security_origin)) {
-    // TODO(ulan): Check for COOP/COEP and allow cross-origin contexts that
-    // opted in for memory measurement.
-    // Until then we allow cross-origin measurement only for site-isolated
-    // web pages.
-    return Platform::Current()->IsLockedToSite();
+    // TODO(ulan): Allow only same-origin contexts until the implementation
+    // is switched to PerformanceManager.
+    return false;
   }
   return true;
 }
@@ -84,143 +83,32 @@
   return window->GetFrame();
 }
 
-// Returns true if all frames on the path from the main frame to
-// the given frame (excluding the given frame) have the same origin.
-bool AllAncestorsAndOpenersAreSameOrigin(const WebFrame* main_frame,
-                                         const WebFrame* frame) {
-  while (frame != main_frame) {
-    frame = frame->Parent() ? frame->Parent() : frame->Opener();
-    if (!main_frame->GetSecurityOrigin().CanAccess(frame->GetSecurityOrigin()))
-      return false;
-  }
-  return true;
+String GetUrl(const LocalFrame* requesting_frame, const LocalFrame* frame) {
+  // Only same-origin frames are reported until we switch to PerformanceManager.
+  DCHECK(requesting_frame->GetSecurityContext()->GetSecurityOrigin()->CanAccess(
+      frame->GetSecurityContext()->GetSecurityOrigin()));
+  return frame->GetDocument()->Url().GetString();
 }
 
-// Returns the URL corresponding to the given frame. It is:
-// - document's URL if the frame is a same-origin top frame.
-// - the src attribute of the owner iframe element if the frame is
-//   an iframe.
-// - nullopt, otherwise.
-// Preconditions:
-// - If the frame is cross-origin, then all its ancestors/openers
-//   must be of the same origin as the main frame.
-// - The frame must be attached to the DOM tree and the main frame
-//   must be reachable via child => parent and openee => opener edges.
-String GetUrl(const WebFrame* main_frame, const WebFrame* frame) {
-  DCHECK(AllAncestorsAndOpenersAreSameOrigin(main_frame, frame));
-  if (!frame->Parent()) {
-    // TODO(ulan): Turn this conditional into a DCHECK once the API
-    // is gated behind COOP+COEP. Only same-origin frames can appear here.
-    if (!main_frame->GetSecurityOrigin().CanAccess(frame->GetSecurityOrigin()))
-      return {};
-    // The frame must be local because it is in the same browsing context
-    // group as the main frame and has the same origin.
-    // Check to avoid memory corruption in the case if our invariant is off.
-    CHECK(IsA<LocalFrame>(WebFrame::ToCoreFrame(*frame)));
-    LocalFrame* local = To<LocalFrame>(WebFrame::ToCoreFrame(*frame));
-    return local->GetDocument()->Url().GetString();
-  }
-  FrameOwner* frame_owner = WebFrame::ToCoreFrame(*frame)->Owner();
-  // The frame owner must be local because the parent of the frame has
-  // the same origin as the main frame. Also the frame cannot be provisional
-  // here because it is attached and has a document.
-  // Check to avoid of memory corruption in the case if our invariant is off.
-  CHECK(IsA<HTMLFrameOwnerElement>(frame_owner));
-  HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(frame_owner);
-  switch (owner_element->OwnerType()) {
-    case mojom::blink::FrameOwnerElementType::kIframe:
-      return owner_element->getAttribute(html_names::kSrcAttr);
-    case mojom::blink::FrameOwnerElementType::kObject:
-    case mojom::blink::FrameOwnerElementType::kEmbed:
-    case mojom::blink::FrameOwnerElementType::kFrame:
-    case mojom::blink::FrameOwnerElementType::kPortal:
-      // TODO(ulan): return the data/src attribute after adding tests.
-      return {};
-    case mojom::blink::FrameOwnerElementType::kNone:
-      // The main frame was handled as a local frame above.
-      NOTREACHED();
-      return {};
-  }
-}
-
-// To avoid information leaks cross-origin iframes are considered opaque for
-// the purposes of attribution. This means the memory of all iframes nested
-// in a cross-origin iframe is attributed to the cross-origin iframe.
-// See https://github.com/WICG/performance-measure-memory for more details.
-//
-// Given the main frame and a frame, this function find the first cross-origin
-// frame in the path from the main frame to the given frame. Edges in the path
-// are parent/child and opener/openee edges.
-// If the path doesn't exist then it returns nullptr.
-// If there are no cross-origin frames, then it returns the given frame.
-//
-// Precondition: the frame must be attached to the DOM tree.
-const WebFrame* GetAttributionFrame(const WebFrame* main_frame,
-                                    const WebFrame* frame) {
-  WebSecurityOrigin main_security_origin = main_frame->GetSecurityOrigin();
-  // Walk up the tree and the openers to find the first cross-origin frame
-  // on the path from the main frame to the given frame.
-  const WebFrame* result = frame;
-  while (frame != main_frame) {
-    if (frame->Parent()) {
-      frame = frame->Parent();
-    } else if (frame->Opener()) {
-      frame = frame->Opener();
-    } else {
-      // The opener was reset. We cannot get the attribution.
-      return nullptr;
-    }
-    if (!main_security_origin.CanAccess(frame->GetSecurityOrigin()))
-      result = frame;
-  }
-  // The result frame must be attached because we started from an attached
-  // frame (precondition) and followed the parent and opener references until
-  // the main frame, which is also attached.
-  DCHECK(WebFrame::ToCoreFrame(*result)->IsAttached());
+MemoryAttribution* CreateMemoryAttribution(const String& url) {
+  auto* result = MemoryAttribution::Create();
+  result->setUrl(url);
+  result->setScope("Window");
+  result->setContainer(nullptr);
   return result;
 }
 
-// Return per-frame sizes based on the given per-context size.
-// TODO(ulan): Revisit this after Origin Trial and see if the results
-// are precise enough or if we need to additionally group by JS agent.
-HashMap<const WebFrame*, size_t> GroupByFrame(
-    const WebFrame* main_frame,
-    const std::vector<std::pair<v8::Local<v8::Context>, size_t>>& context_sizes,
-    size_t& detached_size,
-    size_t& unknown_frame_size) {
-  detached_size = 0;
-  unknown_frame_size = 0;
-  HashMap<const WebFrame*, size_t> per_frame;
-  for (const auto& context_size : context_sizes) {
-    const WebFrame* frame =
-        WebFrame::FromFrame(GetLocalFrame(context_size.first));
-    if (!frame) {
-      detached_size += context_size.second;
-      continue;
-    }
-    frame = GetAttributionFrame(main_frame, frame);
-    if (!frame) {
-      unknown_frame_size += context_size.second;
-      continue;
-    }
-    auto it = per_frame.find(frame);
-    if (it == per_frame.end()) {
-      per_frame.insert(frame, context_size.second);
-    } else {
-      it->value += context_size.second;
-    }
-  }
-  return per_frame;
-}
-
-MeasureMemoryBreakdown* CreateMeasureMemoryBreakdown(
-    size_t bytes,
-    const Vector<String>& types,
-    const String& url) {
-  MeasureMemoryBreakdown* result = MeasureMemoryBreakdown::Create();
+MemoryBreakdownEntry* CreateMemoryBreakdownEntry(size_t bytes,
+                                                 const Vector<String>& types,
+                                                 const String& url) {
+  auto* result = MemoryBreakdownEntry::Create();
   result->setBytes(bytes);
   result->setUserAgentSpecificTypes(types);
-  result->setAttribution(url.length() ? Vector<String>{url} : Vector<String>());
+  HeapVector<Member<MemoryAttribution>> attribution;
+  if (url.length()) {
+    attribution.push_back(CreateMemoryAttribution(url));
+  }
+  result->setAttribution(attribution);
   return result;
 }
 
@@ -236,49 +124,38 @@
     return;
   }
   v8::Local<v8::Context> context = context_.NewLocal(isolate_);
-  const WebFrame* main_frame = WebFrame::FromFrame(GetLocalFrame(context));
-  if (!main_frame) {
+  LocalFrame* requesting_frame = GetLocalFrame(context);
+  if (!requesting_frame) {
     // The context was detached in the meantime.
     return;
   }
-  DCHECK(!main_frame->Parent());
   v8::Context::Scope context_scope(context);
   size_t total_size = 0;
   for (const auto& context_size : context_sizes) {
     total_size += context_size.second;
   }
-  HeapVector<Member<MeasureMemoryBreakdown>> breakdown;
-  size_t detached_size;
-  size_t unknown_frame_size;
-  HashMap<const WebFrame*, size_t> per_frame(GroupByFrame(
-      main_frame, context_sizes, detached_size, unknown_frame_size));
-  size_t attributed_size = 0;
-  const String kWindow("Window");
+  HeapVector<Member<MemoryBreakdownEntry>> breakdown;
+  size_t detached_size = 0;
   const String kJS("JS");
-  const Vector<String> js_window_types = {kWindow, kJS};
-  for (const auto& it : per_frame) {
-    String url = GetUrl(main_frame, it.key);
-    if (url.IsNull()) {
-      unknown_frame_size += it.value;
+  const Vector<String> js_types = {kJS};
+  for (const auto& it : context_sizes) {
+    size_t bytes = it.second;
+    LocalFrame* frame = GetLocalFrame(it.first);
+    if (!frame) {
+      detached_size += bytes;
       continue;
     }
-    attributed_size += it.value;
-    breakdown.push_back(
-        CreateMeasureMemoryBreakdown(it.value, js_window_types, url));
+    String url = GetUrl(requesting_frame, frame);
+    breakdown.push_back(CreateMemoryBreakdownEntry(bytes, js_types, url));
   }
   if (detached_size) {
     const String kDetached("Detached");
-    breakdown.push_back(CreateMeasureMemoryBreakdown(
-        detached_size, Vector<String>{kWindow, kJS, kDetached}, ""));
+    breakdown.push_back(CreateMemoryBreakdownEntry(
+        detached_size, Vector<String>{kJS, kDetached}, ""));
   }
   if (unattributed_size) {
-    const String kShared("Shared");
-    breakdown.push_back(CreateMeasureMemoryBreakdown(
-        unattributed_size, Vector<String>{kWindow, kJS, kShared}, ""));
-  }
-  if (unknown_frame_size) {
-    breakdown.push_back(CreateMeasureMemoryBreakdown(
-        unknown_frame_size, Vector<String>{kWindow, kJS}, ""));
+    breakdown.push_back(
+        CreateMemoryBreakdownEntry(unattributed_size, Vector<String>{kJS}, ""));
   }
   std::move(callback_).Run(breakdown);
 }
diff --git a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h
index 23a1100..5bb1f48 100644
--- a/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h
+++ b/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h
@@ -12,14 +12,14 @@
 
 namespace blink {
 
-class MeasureMemoryBreakdown;
+class MemoryBreakdownEntry;
 
 // Specifies V8 contexts to be measured and invokes the given callback once V8
 // completes the memory measurement.
 class MeasureMemoryDelegate : public v8::MeasureMemoryDelegate {
  public:
   using ResultCallback =
-      base::OnceCallback<void(HeapVector<Member<MeasureMemoryBreakdown>>)>;
+      base::OnceCallback<void(HeapVector<Member<MemoryBreakdownEntry>>)>;
 
   MeasureMemoryDelegate(v8::Isolate* isolate,
                         v8::Local<v8::Context> context,
diff --git a/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl b/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl
new file mode 100644
index 0000000..5a8d9c27
--- /dev/null
+++ b/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl
@@ -0,0 +1,12 @@
+// 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.
+
+// https://wicg.github.io/performance-measure-memory/#dictdef-memoryattribution
+
+// Describes a context to which the memory was attributed.
+dictionary MemoryAttribution {
+  required USVString url;
+  MemoryAttributionContainer container;
+  required DOMString scope;
+};
\ No newline at end of file
diff --git a/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl b/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl
new file mode 100644
index 0000000..90c476f
--- /dev/null
+++ b/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl
@@ -0,0 +1,11 @@
+// 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.
+
+// https://wicg.github.io/performance-measure-memory/#dictdef-memoryattribution
+
+// The attributes of the container iframe element.
+dictionary MemoryAttributionContainer {
+  required DOMString id;
+  required USVString src;
+};
\ No newline at end of file
diff --git a/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl b/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl
new file mode 100644
index 0000000..4b8d9dd1
--- /dev/null
+++ b/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl
@@ -0,0 +1,12 @@
+// 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.
+
+// https://wicg.github.io/performance-measure-memory/#dictdef-memorybreakdownentry
+
+// A single entry of performance.measureMemory() result.
+dictionary MemoryBreakdownEntry {
+  required unsigned long long bytes;
+  required sequence<MemoryAttribution> attribution;
+  required sequence<DOMString> userAgentSpecificTypes;
+};
\ No newline at end of file
diff --git a/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl b/third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl
similarity index 60%
rename from third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl
rename to third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl
index d319cef..e3eba07 100644
--- a/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl
+++ b/third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// https://github.com/WICG/performance-measure-memory
+// https://wicg.github.io/performance-measure-memory/#dictdef-memorymeasurement
 
 // The result of performance.measureMemory().
-dictionary MeasureMemory {
+dictionary MemoryMeasurement {
   required unsigned long long bytes;
-  required sequence<MeasureMemoryBreakdown> breakdown;
+  required sequence<MemoryBreakdownEntry> breakdown;
 };
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc
index 3f732b2..6b26893 100644
--- a/third_party/blink/renderer/core/timing/performance.cc
+++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -672,9 +672,9 @@
                                     base::TimeTicks end_time,
                                     const AtomicString& name,
                                     const AtomicString& container_type,
-                                    const String& container_src,
-                                    const String& container_id,
-                                    const String& container_name) {
+                                    const AtomicString& container_src,
+                                    const AtomicString& container_id,
+                                    const AtomicString& container_name) {
   auto* entry = MakeGarbageCollected<PerformanceLongTaskTiming>(
       MonotonicTimeToDOMHighResTimeStamp(start_time),
       MonotonicTimeToDOMHighResTimeStamp(end_time), name, container_type,
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h
index 8609a2a..dc7bb95 100644
--- a/third_party/blink/renderer/core/timing/performance.h
+++ b/third_party/blink/renderer/core/timing/performance.h
@@ -159,9 +159,9 @@
                          base::TimeTicks end_time,
                          const AtomicString& name,
                          const AtomicString& container_type,
-                         const String& container_src,
-                         const String& container_id,
-                         const String& container_name);
+                         const AtomicString& container_src,
+                         const AtomicString& container_id,
+                         const AtomicString& container_name);
 
   // Generates and add a performance entry for the given ResourceTimingInfo.
   // |overridden_initiator_type| allows the initiator type to be overridden to
diff --git a/third_party/blink/renderer/core/timing/performance.idl b/third_party/blink/renderer/core/timing/performance.idl
index 4939cad..2ec3c0f 100644
--- a/third_party/blink/renderer/core/timing/performance.idl
+++ b/third_party/blink/renderer/core/timing/performance.idl
@@ -67,7 +67,7 @@
     // https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ
     [Exposed=Window, Measure] readonly attribute MemoryInfo memory;
 
-    [MeasureAs=MeasureMemory, Exposed=Window, CallWith=ScriptState, RuntimeEnabled=MeasureMemory, RaisesException] Promise<MeasureMemory> measureMemory();
+    [MeasureAs=MeasureMemory, Exposed=Window, CallWith=ScriptState, RuntimeEnabled=MeasureMemory, RaisesException] Promise<MemoryMeasurement> measureMemory();
 
     // JS Self-Profiling API
     // https://github.com/WICG/js-self-profiling/
diff --git a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
index 83ced4eb..aa9acb0d 100644
--- a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
@@ -18,9 +18,9 @@
     double end_time,
     const AtomicString& name,
     const AtomicString& culprit_type,
-    const String& culprit_src,
-    const String& culprit_id,
-    const String& culprit_name)
+    const AtomicString& culprit_src,
+    const AtomicString& culprit_id,
+    const AtomicString& culprit_name)
     : PerformanceEntry(name, start_time, end_time) {
   auto* attribution_entry = MakeGarbageCollected<TaskAttributionTiming>(
       "unknown", culprit_type, culprit_src, culprit_id, culprit_name);
diff --git a/third_party/blink/renderer/core/timing/performance_long_task_timing.h b/third_party/blink/renderer/core/timing/performance_long_task_timing.h
index 8dd3530e..5b68481 100644
--- a/third_party/blink/renderer/core/timing/performance_long_task_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_long_task_timing.h
@@ -23,9 +23,9 @@
                             double end_time,
                             const AtomicString& name,
                             const AtomicString& culprit_type,
-                            const String& culprit_src,
-                            const String& culprit_id,
-                            const String& culprit_name);
+                            const AtomicString& culprit_src,
+                            const AtomicString& culprit_id,
+                            const AtomicString& culprit_name);
 
   AtomicString entryType() const override;
   PerformanceEntryType EntryTypeEnum() const override;
diff --git a/third_party/blink/renderer/core/timing/task_attribution_timing.cc b/third_party/blink/renderer/core/timing/task_attribution_timing.cc
index 2588b14..67c00aa 100644
--- a/third_party/blink/renderer/core/timing/task_attribution_timing.cc
+++ b/third_party/blink/renderer/core/timing/task_attribution_timing.cc
@@ -12,9 +12,9 @@
 
 TaskAttributionTiming::TaskAttributionTiming(const AtomicString& name,
                                              const AtomicString& container_type,
-                                             const String& container_src,
-                                             const String& container_id,
-                                             const String& container_name)
+                                             const AtomicString& container_src,
+                                             const AtomicString& container_id,
+                                             const AtomicString& container_name)
     : PerformanceEntry(name, 0.0, 0.0),
       container_type_(container_type),
       container_src_(container_src),
diff --git a/third_party/blink/renderer/core/timing/task_attribution_timing.h b/third_party/blink/renderer/core/timing/task_attribution_timing.h
index 2c2ead9..7f33034e 100644
--- a/third_party/blink/renderer/core/timing/task_attribution_timing.h
+++ b/third_party/blink/renderer/core/timing/task_attribution_timing.h
@@ -28,9 +28,9 @@
 
   TaskAttributionTiming(const AtomicString& type,
                         const AtomicString& container_type,
-                        const String& container_src,
-                        const String& container_id,
-                        const String& container_name);
+                        const AtomicString& container_src,
+                        const AtomicString& container_id,
+                        const AtomicString& container_name);
   ~TaskAttributionTiming() override;
 
  private:
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc
index bf39c37..3627e09 100644
--- a/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -314,7 +314,7 @@
   if (!culprit_dom_window || !culprit_dom_window->GetFrame() ||
       !culprit_dom_window->GetFrame()->DeprecatedLocalOwner()) {
     AddLongTaskTiming(start_time, end_time, attribution.first, "window",
-                      g_empty_string, g_empty_string, g_empty_string);
+                      g_empty_atom, g_empty_atom, g_empty_atom);
   } else {
     HTMLFrameOwnerElement* frame_owner =
         culprit_dom_window->GetFrame()->DeprecatedLocalOwner();
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
index 414b6560..776f9bbd 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -354,7 +354,7 @@
                             nullptr /* loader_factory */, this));
   }
   if (IsContextPaused())
-    fetcher->SetDefersLoading(true);
+    fetcher->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   resource_fetchers_.insert(fetcher);
   return fetcher;
 }
@@ -514,7 +514,7 @@
 }
 
 void WorkerOrWorkletGlobalScope::SetDefersLoadingForResourceFetchers(
-    bool defers) {
+    WebURLLoader::DeferType defers) {
   for (ResourceFetcher* resource_fetcher : resource_fetchers_)
     resource_fetcher->SetDefersLoading(defers);
 }
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
index 9722f73e..29e33dc5 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -152,7 +152,7 @@
 
   void ApplySandboxFlags(network::mojom::blink::WebSandboxFlags mask);
 
-  void SetDefersLoadingForResourceFetchers(bool defers);
+  void SetDefersLoadingForResourceFetchers(WebURLLoader::DeferType defers);
 
   virtual int GetOutstandingThrottledLimit() const;
 
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
index 4fc91c60..7a04127a6 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -865,7 +865,8 @@
          state == mojom::FrameLifecycleState::kPaused);
   pause_or_freeze_count_++;
   GlobalScope()->SetLifecycleState(state);
-  GlobalScope()->SetDefersLoadingForResourceFetchers(true);
+  GlobalScope()->SetDefersLoadingForResourceFetchers(
+      WebURLLoader::DeferType::kDeferred);
 
   // If already paused return early.
   if (pause_or_freeze_count_ > 1)
@@ -884,7 +885,8 @@
         &nested_runner_, nested_runner.get());
     nested_runner->Run();
   }
-  GlobalScope()->SetDefersLoadingForResourceFetchers(false);
+  GlobalScope()->SetDefersLoadingForResourceFetchers(
+      WebURLLoader::DeferType::kNotDeferred);
   GlobalScope()->SetLifecycleState(mojom::FrameLifecycleState::kRunning);
 }
 
diff --git a/third_party/blink/renderer/modules/nfc/ndef_record.cc b/third_party/blink/renderer/modules/nfc/ndef_record.cc
index 5fbbab2..854c35d 100644
--- a/third_party/blink/renderer/modules/nfc/ndef_record.cc
+++ b/third_party/blink/renderer/modules/nfc/ndef_record.cc
@@ -528,7 +528,7 @@
   return DOMDataView::Create(dom_buffer, 0, payload_data_.size());
 }
 
-// https://w3c.github.io/web-nfc/#dfn-convert-ndefrecord-payloaddata-bytes
+// https://w3c.github.io/web-nfc/#dfn-convert-ndefrecord-data-bytes
 base::Optional<HeapVector<Member<NDEFRecord>>> NDEFRecord::toRecords(
     ExceptionState& exception_state) const {
   if (record_type_ != "smart-poster" &&
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
index aa9ceb3..557c0827 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
@@ -12,11 +12,10 @@
 #include <utility>
 #include <vector>
 
-#include "base/power_monitor/power_observer.h"
 #include "base/stl_util.h"
 #include "base/values.h"
-#include "third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h"
 #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_media_stream.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/web/web_document.h"
@@ -726,9 +725,7 @@
 void PeerConnectionTracker::OnThermalStateChange(
     mojom::blink::DeviceThermalState thermal_state) {
   DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
-  mojo::EnumTraits<mojom::blink::DeviceThermalState,
-                   base::PowerObserver::DeviceThermalState>::
-      FromMojom(thermal_state, &current_thermal_state_);
+  current_thermal_state_ = thermal_state;
   for (auto& entry : peer_connection_local_id_map_) {
     entry.key->OnThermalStateChange(current_thermal_state_);
   }
@@ -808,8 +805,7 @@
 
   peer_connection_local_id_map_.insert(pc_handler, lid);
 
-  if (current_thermal_state_ !=
-      base::PowerObserver::DeviceThermalState::kUnknown) {
+  if (current_thermal_state_ != mojom::blink::DeviceThermalState::kUnknown) {
     pc_handler->OnThermalStateChange(current_thermal_state_);
   }
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
index 7000bc4..ee047f78 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
@@ -7,7 +7,6 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/power_monitor/power_observer.h"
 #include "base/threading/thread_checker.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -282,8 +281,8 @@
   // This map stores the local ID assigned to each RTCPeerConnectionHandler.
   typedef WTF::HashMap<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap;
   PeerConnectionLocalIdMap peer_connection_local_id_map_;
-  base::PowerObserver::DeviceThermalState current_thermal_state_ =
-      base::PowerObserver::DeviceThermalState::kUnknown;
+  mojom::blink::DeviceThermalState current_thermal_state_ =
+      mojom::blink::DeviceThermalState::kUnknown;
 
   // This keeps track of the next available local ID.
   int next_local_id_;
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc
index 6991518..7c7a0c1 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc
@@ -127,8 +127,7 @@
             /*force_encoded_audio_insertable_streams=*/false,
             /*force_encoded_video_insertable_streams=*/false) {}
   MOCK_METHOD0(CloseClientPeerConnection, void());
-  MOCK_METHOD1(OnThermalStateChange,
-               void(base::PowerObserver::DeviceThermalState));
+  MOCK_METHOD1(OnThermalStateChange, void(mojom::blink::DeviceThermalState));
 
  private:
   blink::MockPeerConnectionDependencyFactory dependency_factory_;
@@ -195,35 +194,30 @@
   CreateTrackerWithMocks();
   CreateAndRegisterPeerConnectionHandler();
 
-  EXPECT_CALL(
-      *mock_handler_,
-      OnThermalStateChange(base::PowerObserver::DeviceThermalState::kUnknown))
+  EXPECT_CALL(*mock_handler_,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown))
       .Times(1);
-  tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown);
+  tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown);
 
-  EXPECT_CALL(
-      *mock_handler_,
-      OnThermalStateChange(base::PowerObserver::DeviceThermalState::kNominal))
+  EXPECT_CALL(*mock_handler_,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal))
       .Times(1);
-  tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal);
+  tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal);
 
-  EXPECT_CALL(
-      *mock_handler_,
-      OnThermalStateChange(base::PowerObserver::DeviceThermalState::kFair))
+  EXPECT_CALL(*mock_handler_,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kFair))
       .Times(1);
-  tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kFair);
+  tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kFair);
 
-  EXPECT_CALL(
-      *mock_handler_,
-      OnThermalStateChange(base::PowerObserver::DeviceThermalState::kSerious))
+  EXPECT_CALL(*mock_handler_,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kSerious))
       .Times(1);
-  tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kSerious);
+  tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kSerious);
 
-  EXPECT_CALL(
-      *mock_handler_,
-      OnThermalStateChange(base::PowerObserver::DeviceThermalState::kCritical))
+  EXPECT_CALL(*mock_handler_,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kCritical))
       .Times(1);
-  tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kCritical);
+  tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kCritical);
 }
 
 TEST_F(PeerConnectionTrackerTest, ReportInitialThermalState) {
@@ -241,14 +235,14 @@
   base::RunLoop().RunUntilIdle();
 
   // Report a known thermal state.
-  EXPECT_CALL(handler0, OnThermalStateChange(
-                            base::PowerObserver::DeviceThermalState::kNominal))
+  EXPECT_CALL(handler0,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal))
       .Times(1);
-  tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal);
+  tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal);
 
   // Handlers registered late will get the event upon registering.
-  EXPECT_CALL(handler1, OnThermalStateChange(
-                            base::PowerObserver::DeviceThermalState::kNominal))
+  EXPECT_CALL(handler1,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal))
       .Times(1);
   EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1);
   tracker_->RegisterPeerConnection(
@@ -257,13 +251,13 @@
   base::RunLoop().RunUntilIdle();
 
   // Report the unknown thermal state.
-  EXPECT_CALL(handler0, OnThermalStateChange(
-                            base::PowerObserver::DeviceThermalState::kUnknown))
+  EXPECT_CALL(handler0,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown))
       .Times(1);
-  EXPECT_CALL(handler1, OnThermalStateChange(
-                            base::PowerObserver::DeviceThermalState::kUnknown))
+  EXPECT_CALL(handler1,
+              OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown))
       .Times(1);
-  tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown);
+  tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown);
 
   // Handlers registered late get no event.
   EXPECT_CALL(handler2, OnThermalStateChange(_)).Times(0);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
index aaf34b44f..2531921 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
@@ -2066,7 +2066,7 @@
 }
 
 void RTCPeerConnectionHandler::OnThermalStateChange(
-    base::PowerObserver::DeviceThermalState thermal_state) {
+    mojom::blink::DeviceThermalState thermal_state) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (is_closed_)
     return;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
index 13c92ab..3b1b9f60 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
@@ -15,8 +15,8 @@
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/power_monitor/power_observer.h"
 #include "base/single_thread_task_runner.h"
+#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/modules/peerconnection/media_stream_track_metrics.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h"
@@ -211,7 +211,7 @@
   // Invoked when a new thermal state is received from the OS.
   // Virtual for testing purposes.
   virtual void OnThermalStateChange(
-      base::PowerObserver::DeviceThermalState thermal_state);
+      mojom::blink::DeviceThermalState thermal_state);
 
   // Start recording an event log.
   void StartEventLog(int output_period_ms);
@@ -473,8 +473,8 @@
   scoped_refptr<ThermalResource> thermal_resource_ = nullptr;
   // ThermalUmaListener is only tracked on peer connection that add a track.
   std::unique_ptr<ThermalUmaListener> thermal_uma_listener_ = nullptr;
-  base::PowerObserver::DeviceThermalState last_thermal_state_ =
-      base::PowerObserver::DeviceThermalState::kUnknown;
+  mojom::blink::DeviceThermalState last_thermal_state_ =
+      mojom::blink::DeviceThermalState::kUnknown;
 
   // Record info about the first SessionDescription from the local and
   // remote side to record UMA stats once both are set.  We only check
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
index 8f05c34..baf1dfbd 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -1289,7 +1289,7 @@
 TEST_F(RTCPeerConnectionHandlerTest, ThermalResourceDefaultValue) {
   EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
   pc_handler_->OnThermalStateChange(
-      base::PowerObserver::DeviceThermalState::kCritical);
+      mojom::blink::DeviceThermalState::kCritical);
 #if defined(OS_MAC)
   bool expect_disabled = false;
 #else
@@ -1308,7 +1308,7 @@
 
   EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
   pc_handler_->OnThermalStateChange(
-      base::PowerObserver::DeviceThermalState::kCritical);
+      mojom::blink::DeviceThermalState::kCritical);
   // A ThermalResource is created in response to the thermal signal.
   EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
 }
@@ -1322,7 +1322,7 @@
   EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
   // ThermalResource is created and injected on the fly.
   pc_handler_->OnThermalStateChange(
-      base::PowerObserver::DeviceThermalState::kCritical);
+      mojom::blink::DeviceThermalState::kCritical);
   auto resources = mock_peer_connection_->adaptation_resources();
   ASSERT_EQ(1u, resources.size());
   auto thermal_resource = resources[0];
@@ -1334,8 +1334,7 @@
   EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
             resource_listener.latest_measurement());
   // ThermalResource responds to new measurements.
-  pc_handler_->OnThermalStateChange(
-      base::PowerObserver::DeviceThermalState::kNominal);
+  pc_handler_->OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal);
   EXPECT_EQ(2u, resource_listener.measurement_count());
   EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
             resource_listener.latest_measurement());
diff --git a/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc b/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc
index 28a108e..23f7476 100644
--- a/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc
+++ b/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc
@@ -35,7 +35,7 @@
     : task_runner_(std::move(task_runner)) {}
 
 void ThermalResource::OnThermalMeasurement(
-    base::PowerObserver::DeviceThermalState measurement) {
+    mojom::blink::DeviceThermalState measurement) {
   base::AutoLock auto_lock(lock_);
   measurement_ = measurement;
   ++measurement_id_;
@@ -50,8 +50,7 @@
   base::AutoLock auto_lock(lock_);
   DCHECK(!listener_ || !listener) << "Must not overwrite existing listener.";
   listener_ = listener;
-  if (listener_ &&
-      measurement_ != base::PowerObserver::DeviceThermalState::kUnknown) {
+  if (listener_ && measurement_ != mojom::blink::DeviceThermalState::kUnknown) {
     ReportMeasurementWhileHoldingLock(measurement_id_);
   }
 }
@@ -68,16 +67,16 @@
   if (measurement_id != measurement_id_ || !listener_)
     return;
   switch (measurement_) {
-    case base::PowerObserver::DeviceThermalState::kUnknown:
+    case mojom::blink::DeviceThermalState::kUnknown:
       // Stop repeating measurements.
       return;
-    case base::PowerObserver::DeviceThermalState::kNominal:
-    case base::PowerObserver::DeviceThermalState::kFair:
+    case mojom::blink::DeviceThermalState::kNominal:
+    case mojom::blink::DeviceThermalState::kFair:
       listener_->OnResourceUsageStateMeasured(
           this, webrtc::ResourceUsageState::kUnderuse);
       break;
-    case base::PowerObserver::DeviceThermalState::kSerious:
-    case base::PowerObserver::DeviceThermalState::kCritical:
+    case mojom::blink::DeviceThermalState::kSerious:
+    case mojom::blink::DeviceThermalState::kCritical:
       listener_->OnResourceUsageStateMeasured(
           this, webrtc::ResourceUsageState::kOveruse);
       break;
diff --git a/third_party/blink/renderer/modules/peerconnection/thermal_resource.h b/third_party/blink/renderer/modules/peerconnection/thermal_resource.h
index 281caaf..0f0d1c89 100644
--- a/third_party/blink/renderer/modules/peerconnection/thermal_resource.h
+++ b/third_party/blink/renderer/modules/peerconnection/thermal_resource.h
@@ -7,10 +7,10 @@
 
 #include "base/feature_list.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/power_monitor/power_observer.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
+#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/webrtc/api/adaptation/resource.h"
 
@@ -46,8 +46,7 @@
       scoped_refptr<base::SequencedTaskRunner> task_runner);
   ~ThermalResource() override = default;
 
-  void OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState measurement);
+  void OnThermalMeasurement(mojom::blink::DeviceThermalState measurement);
 
   // webrtc::Resource implementation.
   std::string Name() const override;
@@ -61,8 +60,8 @@
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
   base::Lock lock_;
   webrtc::ResourceListener* listener_ GUARDED_BY(&lock_) = nullptr;
-  base::PowerObserver::DeviceThermalState measurement_ GUARDED_BY(&lock_) =
-      base::PowerObserver::DeviceThermalState::kUnknown;
+  mojom::blink::DeviceThermalState measurement_ GUARDED_BY(&lock_) =
+      mojom::blink::DeviceThermalState::kUnknown;
   size_t measurement_id_ GUARDED_BY(&lock_) = 0u;
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc b/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc
index 628a170c..4e1dd30 100644
--- a/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc
@@ -50,8 +50,7 @@
 
 TEST_F(ThermalResourceTest, NominalTriggersUnderuse) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kNominal);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kNominal);
   EXPECT_EQ(1u, listener_.measurement_count());
   EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
             listener_.latest_measurement());
@@ -59,8 +58,7 @@
 
 TEST_F(ThermalResourceTest, FairTriggersUnderuse) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kFair);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kFair);
   EXPECT_EQ(1u, listener_.measurement_count());
   EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
             listener_.latest_measurement());
@@ -68,8 +66,7 @@
 
 TEST_F(ThermalResourceTest, SeriousTriggersOveruse) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious);
   EXPECT_EQ(1u, listener_.measurement_count());
   EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
             listener_.latest_measurement());
@@ -77,8 +74,7 @@
 
 TEST_F(ThermalResourceTest, CriticalTriggersOveruse) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kCritical);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kCritical);
   EXPECT_EQ(1u, listener_.measurement_count());
   EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
             listener_.latest_measurement());
@@ -86,15 +82,13 @@
 
 TEST_F(ThermalResourceTest, UnknownDoesNotTriggerUsage) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kUnknown);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kUnknown);
   EXPECT_EQ(0u, listener_.measurement_count());
 }
 
 TEST_F(ThermalResourceTest, MeasurementsRepeatEvery10Seconds) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious);
   size_t expected_count = listener_.measurement_count();
 
   // First Interval.
@@ -130,8 +124,7 @@
 
 TEST_F(ThermalResourceTest, NewMeasurementInvalidatesInFlightRepetition) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious);
   task_runner_->FastForwardBy(
       base::TimeDelta::FromMilliseconds(kReportIntervalMs));
 
@@ -146,8 +139,7 @@
   EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
             listener_.latest_measurement());
   // Trigger kUnderuse.
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kNominal);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kNominal);
   EXPECT_EQ(3u, listener_.measurement_count());
   EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
             listener_.latest_measurement());
@@ -169,15 +161,13 @@
 
 TEST_F(ThermalResourceTest, UnknownStopsRepeatedMeasurements) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious);
   task_runner_->FastForwardBy(
       base::TimeDelta::FromMilliseconds(kReportIntervalMs));
   // The measurement is repeating.
   EXPECT_EQ(2u, listener_.measurement_count());
 
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kUnknown);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kUnknown);
   task_runner_->FastForwardBy(
       base::TimeDelta::FromMilliseconds(kReportIntervalMs));
   // No more measurements.
@@ -186,8 +176,7 @@
 
 TEST_F(ThermalResourceTest, UnregisteringStopsRepeatedMeasurements) {
   resource_->SetResourceListener(&listener_);
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious);
   task_runner_->FastForwardBy(
       base::TimeDelta::FromMilliseconds(kReportIntervalMs));
   // The measurement is repeating.
@@ -201,8 +190,7 @@
 }
 
 TEST_F(ThermalResourceTest, RegisteringLateTriggersRepeatedMeasurements) {
-  resource_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+  resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious);
   task_runner_->FastForwardBy(
       base::TimeDelta::FromMilliseconds(kReportIntervalMs));
   EXPECT_EQ(0u, listener_.measurement_count());
diff --git a/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc b/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc
index d1e63fa..5bdc078 100644
--- a/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc
+++ b/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc
@@ -10,8 +10,8 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
-#include "base/power_monitor/power_observer.h"
 #include "base/sequenced_task_runner.h"
+#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
 
 namespace blink {
 
@@ -27,16 +27,15 @@
   kMaxValue = kCritical,
 };
 
-ThermalStateUMA ToThermalStateUMA(
-    base::PowerObserver::DeviceThermalState state) {
+ThermalStateUMA ToThermalStateUMA(mojom::blink::DeviceThermalState state) {
   switch (state) {
-    case base::PowerObserver::DeviceThermalState::kNominal:
+    case mojom::blink::DeviceThermalState::kNominal:
       return ThermalStateUMA::kNominal;
-    case base::PowerObserver::DeviceThermalState::kFair:
+    case mojom::blink::DeviceThermalState::kFair:
       return ThermalStateUMA::kFair;
-    case base::PowerObserver::DeviceThermalState::kSerious:
+    case mojom::blink::DeviceThermalState::kSerious:
       return ThermalStateUMA::kSerious;
-    case base::PowerObserver::DeviceThermalState::kCritical:
+    case mojom::blink::DeviceThermalState::kCritical:
       return ThermalStateUMA::kCritical;
     default:
       NOTREACHED();
@@ -58,13 +57,13 @@
 ThermalUmaListener::ThermalUmaListener(
     scoped_refptr<base::SequencedTaskRunner> task_runner)
     : task_runner_(std::move(task_runner)),
-      current_thermal_state_(base::PowerObserver::DeviceThermalState::kUnknown),
+      current_thermal_state_(mojom::blink::DeviceThermalState::kUnknown),
       weak_ptr_factor_(this) {
   DCHECK(task_runner_);
 }
 
 void ThermalUmaListener::OnThermalMeasurement(
-    base::PowerObserver::DeviceThermalState measurement) {
+    mojom::blink::DeviceThermalState measurement) {
   base::AutoLock crit(lock_);
   current_thermal_state_ = measurement;
 }
@@ -79,8 +78,7 @@
 void ThermalUmaListener::ReportStats() {
   {
     base::AutoLock crit(lock_);
-    if (current_thermal_state_ !=
-        base::PowerObserver::DeviceThermalState::kUnknown) {
+    if (current_thermal_state_ != mojom::blink::DeviceThermalState::kUnknown) {
       UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ThermalState",
                                 ToThermalStateUMA(current_thermal_state_));
     }
diff --git a/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h b/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h
index a4006a3..16e9fd6b 100644
--- a/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h
+++ b/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h
@@ -10,10 +10,10 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
-#include "base/power_monitor/power_observer.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
+#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 
@@ -29,8 +29,7 @@
       scoped_refptr<base::SequencedTaskRunner> task_runner);
   ~ThermalUmaListener() = default;
 
-  void OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState measurement);
+  void OnThermalMeasurement(mojom::blink::DeviceThermalState measurement);
 
  private:
   void ReportStats();
@@ -38,8 +37,7 @@
 
   base::Lock lock_;
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  base::PowerObserver::DeviceThermalState current_thermal_state_
-      GUARDED_BY(&lock_);
+  mojom::blink::DeviceThermalState current_thermal_state_ GUARDED_BY(&lock_);
   base::WeakPtrFactory<ThermalUmaListener> weak_ptr_factor_;
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc b/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc
index 4e3bc30..aa144e98 100644
--- a/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc
@@ -4,10 +4,10 @@
 
 #include <memory>
 
-#include "base/power_monitor/power_observer.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
 #include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
 
@@ -48,7 +48,7 @@
 
 TEST_F(ThermalUmaListenerTest, HistogramAfterSignal) {
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kFair);
+      mojom::blink::DeviceThermalState::kFair);
   task_runner_->FastForwardBy(kStatsReportingPeriod);
 
   EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
@@ -57,7 +57,7 @@
 
 TEST_F(ThermalUmaListenerTest, DeletionCancelsListener) {
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kFair);
+      mojom::blink::DeviceThermalState::kFair);
   task_runner_->FastForwardBy(2 * kStatsReportingPeriod);
   EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
               testing::ElementsAre(Bucket(1, 2)));
@@ -70,10 +70,10 @@
 
 TEST_F(ThermalUmaListenerTest, RecordsMostRecentState) {
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kFair);
+      mojom::blink::DeviceThermalState::kFair);
   task_runner_->FastForwardBy(kStatsReportingPeriod / 2);
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+      mojom::blink::DeviceThermalState::kSerious);
   task_runner_->FastForwardBy(kStatsReportingPeriod / 2);
 
   EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
@@ -82,16 +82,16 @@
 
 TEST_F(ThermalUmaListenerTest, HistogramBucketsIncludesPreviousPeriod) {
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kNominal);
+      mojom::blink::DeviceThermalState::kNominal);
   task_runner_->FastForwardBy(kStatsReportingPeriod);
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kFair);
+      mojom::blink::DeviceThermalState::kFair);
   task_runner_->FastForwardBy(kStatsReportingPeriod);
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kSerious);
+      mojom::blink::DeviceThermalState::kSerious);
   task_runner_->FastForwardBy(kStatsReportingPeriod);
   thermal_uma_listener_->OnThermalMeasurement(
-      base::PowerObserver::DeviceThermalState::kCritical);
+      mojom::blink::DeviceThermalState::kCritical);
   task_runner_->FastForwardBy(kStatsReportingPeriod);
 
   EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
diff --git a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
index c4c11d6c..ea7be1b94 100644
--- a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
+++ b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
@@ -85,7 +85,7 @@
     // Don't handle other requests intentionally to emulate ongoing load.
   }
 
-  void SetDefersLoading(bool defers) override {}
+  void SetDefersLoading(DeferType defers) override {}
   void DidChangePriority(WebURLRequest::Priority, int) override {}
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForBodyLoader()
       override {
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 7a6602e..45b6e88 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -271,20 +271,9 @@
                                       ExceptionState& exception_state) {
   switch (config->codec) {
     case media::kCodecVP8:
-      if (config->acc_pref == AccelerationPreference::kRequire) {
-        exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
-                                          "Accelerated vp8 is not supported");
-        return false;
-      }
       break;
 
     case media::kCodecVP9:
-      if (config->acc_pref == AccelerationPreference::kRequire) {
-        exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
-                                          "Accelerated vp9 is not supported");
-        return false;
-      }
-
       // TODO(https://crbug.com/1119636): Implement / call a proper method for
       // detecting support of encoder configs.
       if (config->profile == media::VideoCodecProfile::VP9PROFILE_PROFILE1 ||
diff --git a/third_party/blink/renderer/platform/bindings/runtime_call_stats.h b/third_party/blink/renderer/platform/bindings/runtime_call_stats.h
index 96136b3..99a79bb2 100644
--- a/third_party/blink/renderer/platform/bindings/runtime_call_stats.h
+++ b/third_party/blink/renderer/platform/bindings/runtime_call_stats.h
@@ -250,7 +250,6 @@
 #define CALLBACK_COUNTERS(V)                       \
   BINDINGS_METHOD(V, ElementGetBoundingClientRect) \
   BINDINGS_METHOD(V, ElementGetInnerHTML)          \
-  BINDINGS_METHOD(V, ElementSetInnerHTML)          \
   BINDINGS_METHOD(V, EventTargetDispatchEvent)     \
   BINDINGS_METHOD(V, HTMLElementClick)             \
   BINDINGS_METHOD(V, NodeAppendChild)              \
diff --git a/third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h b/third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h
index 62d6bb25..d081bc5 100644
--- a/third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h
+++ b/third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h
@@ -7,7 +7,23 @@
 
 namespace blink {
 
-enum class CanvasRotationInVertical : char { kRegular, kRotateCanvasUpright };
+enum class CanvasRotationInVertical : char {
+  kRegular = 0,
+  kRotateCanvasUpright = 1,
+  kOblique = 2,
+  kRotateCanvasUprightOblique = 3,
+};
+
+inline bool IsCanvasRotationInVerticalUpright(CanvasRotationInVertical r) {
+  return static_cast<char>(r) &
+         static_cast<char>(CanvasRotationInVertical::kRotateCanvasUpright);
 }
 
+inline bool IsCanvasRotationOblque(CanvasRotationInVertical r) {
+  return static_cast<char>(r) &
+         static_cast<char>(CanvasRotationInVertical::kOblique);
+}
+
+}  // namespace blink
+
 #endif
diff --git a/third_party/blink/renderer/platform/fonts/font.cc b/third_party/blink/renderer/platform/fonts/font.cc
index 9f59ca8f..b8d4089 100644
--- a/third_party/blink/renderer/platform/fonts/font.cc
+++ b/third_party/blink/renderer/platform/fonts/font.cc
@@ -168,12 +168,45 @@
   for (const auto& blob_info : blobs) {
     DCHECK(blob_info.blob);
     cc::PaintCanvasAutoRestore auto_restore(canvas, false);
-    if (blob_info.rotation == CanvasRotationInVertical::kRotateCanvasUpright) {
-      canvas->save();
+    switch (blob_info.rotation) {
+      case CanvasRotationInVertical::kRegular:
+        break;
+      case CanvasRotationInVertical::kRotateCanvasUpright: {
+        canvas->save();
 
-      SkMatrix m;
-      m.setSinCos(-1, 0, point.X(), point.Y());
-      canvas->concat(m);
+        SkMatrix m;
+        m.setSinCos(-1, 0, point.X(), point.Y());
+        canvas->concat(m);
+        break;
+      }
+      case CanvasRotationInVertical::kRotateCanvasUprightOblique: {
+        canvas->save();
+
+        SkMatrix m;
+        m.setSinCos(-1, 0, point.X(), point.Y());
+        // TODO(yosin): We should use angle specified in CSS instead of
+        // constant value -15deg.
+        // Note: We draw glyph in right-top corner upper.
+        // See CSS "transform: skew(0, -15deg)"
+        SkMatrix skewY;
+        constexpr SkScalar kSkewY = -0.2679491924311227;  // tan(-15deg)
+        skewY.setSkew(0, kSkewY, point.X(), point.Y());
+        m.preConcat(skewY);
+        canvas->concat(m);
+        break;
+      }
+      case CanvasRotationInVertical::kOblique: {
+        // TODO(yosin): We should use angle specified in CSS instead of
+        // constant value 15deg.
+        // Note: We draw glyph in right-top corner upper.
+        // See CSS "transform: skew(0, -15deg)"
+        canvas->save();
+        SkMatrix skewX;
+        constexpr SkScalar kSkewX = 0.2679491924311227;  // tan(15deg)
+        skewX.setSkew(kSkewX, 0, point.X(), point.Y());
+        canvas->concat(skewX);
+        break;
+      }
     }
     if (node_id != cc::kInvalidNodeId) {
       canvas->drawTextBlob(blob_info.blob, point.X(), point.Y(), node_id,
@@ -372,7 +405,7 @@
     // for a change in font. A TextBlob can contain runs with differing fonts
     // and the getTextBlobIntercepts method handles multiple fonts for us. For
     // upright in vertical blobs we currently have to bail, see crbug.com/655154
-    if (blob_info.rotation == CanvasRotationInVertical::kRotateCanvasUpright)
+    if (IsCanvasRotationInVerticalUpright(blob_info.rotation))
       continue;
 
     SkScalar* offset_intercepts_buffer = nullptr;
diff --git a/third_party/blink/renderer/platform/fonts/font_description.cc b/third_party/blink/renderer/platform/fonts/font_description.cc
index 4b2592ef..f1284ccf 100644
--- a/third_party/blink/renderer/platform/fonts/font_description.cc
+++ b/third_party/blink/renderer/platform/fonts/font_description.cc
@@ -372,6 +372,31 @@
   return hash;
 }
 
+void FontDescription::SetOrientation(FontOrientation orientation) {
+  fields_.orientation_ = static_cast<unsigned>(orientation);
+  UpdateSyntheticOblique();
+}
+
+void FontDescription::SetStyle(FontSelectionValue value) {
+  font_selection_request_.slope = value;
+  original_slope = value;
+  UpdateSyntheticOblique();
+}
+
+void FontDescription::UpdateSyntheticOblique() {
+  // Doing synthetic oblique for vertical writing mode with upright text
+  // orientation when negative angle parameter of "oblique" keyword, e.g.
+  // "font-style: oblique -15deg" for simulating "tts:fontShear"[1][2], we
+  // need to have normal font style instead of italic/oblique.
+  // [1]
+  // https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-fontShear
+  // [2] See http://crbug.com/1112923
+  fields_.synthetic_oblique_ =
+      IsVerticalAnyUpright() && original_slope < FontSelectionValue(0);
+  font_selection_request_.slope =
+      fields_.synthetic_oblique_ ? NormalSlopeValue() : original_slope;
+}
+
 SkFontStyle FontDescription::SkiaFontStyle() const {
   // FIXME(drott): This is a lossy conversion, compare
   // https://bugs.chromium.org/p/skia/issues/detail?id=6844
diff --git a/third_party/blink/renderer/platform/fonts/font_description.h b/third_party/blink/renderer/platform/fonts/font_description.h
index ffb0d7c8..9a79125 100644
--- a/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/third_party/blink/renderer/platform/fonts/font_description.h
@@ -228,6 +228,7 @@
   UScriptCode GetScript() const { return LocaleOrDefault().GetScript(); }
   bool IsSyntheticBold() const { return fields_.synthetic_bold_; }
   bool IsSyntheticItalic() const { return fields_.synthetic_italic_; }
+  bool IsSyntheticOblique() const { return fields_.synthetic_oblique_; }
   bool UseSubpixelPositioning() const {
     return fields_.subpixel_text_position_;
   }
@@ -273,7 +274,7 @@
   void SetAdjustedSize(float s) { adjusted_size_ = clampTo<float>(s); }
   void SetSizeAdjust(float aspect) { size_adjust_ = clampTo<float>(aspect); }
 
-  void SetStyle(FontSelectionValue i) { font_selection_request_.slope = i; }
+  void SetStyle(FontSelectionValue i);
   void SetWeight(FontSelectionValue w) { font_selection_request_.weight = w; }
   void SetStretch(FontSelectionValue s) { font_selection_request_.width = s; }
 
@@ -301,9 +302,7 @@
     fields_.text_rendering_ = rendering;
     UpdateTypesettingFeatures();
   }
-  void SetOrientation(FontOrientation orientation) {
-    fields_.orientation_ = static_cast<unsigned>(orientation);
-  }
+  void SetOrientation(FontOrientation orientation);
   void SetWidthVariant(FontWidthVariant width_variant) {
     fields_.width_variant_ = width_variant;
   }
@@ -383,6 +382,8 @@
   String ToString() const;
 
  private:
+  void UpdateSyntheticOblique();
+
   FontFamily family_list_;  // The list of font families to be used.
   scoped_refptr<FontFeatureSettings> feature_settings_;
   scoped_refptr<FontVariationSettings> variation_settings_;
@@ -409,6 +410,7 @@
 
   // Covers stretch, style, weight.
   FontSelectionRequest font_selection_request_;
+  FontSelectionValue original_slope;
 
   struct BitFields {
     DISALLOW_NEW();
@@ -443,6 +445,7 @@
     unsigned text_rendering_ : 2;  // TextRenderingMode
     unsigned synthetic_bold_ : 1;
     unsigned synthetic_italic_ : 1;
+    unsigned synthetic_oblique_ : 1;
     unsigned subpixel_text_position_ : 1;
     unsigned typesetting_features_ : 3;
     unsigned variant_numeric_ : 8;
diff --git a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
index 3138186..babb8dfb 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
+++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
@@ -162,8 +162,7 @@
     FontOrientation orientation = font->GetFontDescription().Orientation();
     hb_direction_t direction =
         IsVerticalAnyUpright(orientation) &&
-                (canvas_rotation ==
-                 CanvasRotationInVertical::kRotateCanvasUpright)
+                IsCanvasRotationInVerticalUpright(canvas_rotation)
             ? HB_DIRECTION_TTB
             : HB_DIRECTION_LTR;
     return text_direction == TextDirection::kRtl
@@ -305,11 +304,25 @@
 
 CanvasRotationInVertical CanvasRotationForRun(
     FontOrientation font_orientation,
-    OrientationIterator::RenderOrientation render_orientation) {
-  if (font_orientation == FontOrientation::kVerticalUpright ||
-      (font_orientation == FontOrientation::kVerticalMixed &&
-       render_orientation == OrientationIterator::kOrientationKeep))
-    return CanvasRotationInVertical::kRotateCanvasUpright;
+    OrientationIterator::RenderOrientation render_orientation,
+    const FontDescription& font_description) {
+  if (font_orientation == FontOrientation::kVerticalUpright) {
+    return font_description.IsSyntheticOblique()
+               ? CanvasRotationInVertical::kRotateCanvasUprightOblique
+               : CanvasRotationInVertical::kRotateCanvasUpright;
+  }
+
+  if (font_orientation == FontOrientation::kVerticalMixed) {
+    if (render_orientation == OrientationIterator::kOrientationKeep) {
+      return font_description.IsSyntheticOblique()
+                 ? CanvasRotationInVertical::kRotateCanvasUprightOblique
+                 : CanvasRotationInVertical::kRotateCanvasUpright;
+    }
+    return font_description.IsSyntheticOblique()
+               ? CanvasRotationInVertical::kOblique
+               : CanvasRotationInVertical::kRegular;
+  }
+
   return CanvasRotationInVertical::kRegular;
 }
 
@@ -940,7 +953,7 @@
 
     CanvasRotationInVertical canvas_rotation =
         CanvasRotationForRun(adjusted_font->PlatformData().Orientation(),
-                             segment.render_orientation);
+                             segment.render_orientation, font_description);
 
     CapsFeatureSettingsScopedOverlay caps_overlay(
         &range_data->font_features,
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc
index 0e70769..2d2d0f79 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc
@@ -96,8 +96,7 @@
 
   bool is_vertical =
       emphasis_font_data->PlatformData().IsVerticalAnyUpright() &&
-      emphasis_data.canvas_rotation ==
-          CanvasRotationInVertical::kRotateCanvasUpright;
+      IsCanvasRotationInVerticalUpright(emphasis_data.canvas_rotation);
 
   if (!is_vertical) {
     bloberizer.Add(emphasis_data.glyph, emphasis_font_data,
@@ -105,8 +104,7 @@
                    mid_glyph_offset - glyph_center.X());
   } else {
     bloberizer.Add(
-        emphasis_data.glyph, emphasis_font_data,
-        CanvasRotationInVertical::kRotateCanvasUpright,
+        emphasis_data.glyph, emphasis_font_data, emphasis_data.canvas_rotation,
         FloatPoint(-glyph_center.X(), mid_glyph_offset - glyph_center.Y()));
   }
 }
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h
index 2dc99db0..f58ce13e 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h
@@ -57,7 +57,8 @@
       CommitPendingRun();
       pending_font_data_ = font_data;
       pending_canvas_rotation_ = canvas_rotation;
-      DCHECK_EQ(canvas_rotation, CanvasRotationInVertical::kRegular);
+      DCHECK(!IsCanvasRotationInVerticalUpright(canvas_rotation))
+          << static_cast<int>(canvas_rotation);
     }
 
     pending_glyphs_.push_back(glyph);
@@ -77,7 +78,7 @@
       pending_font_data_ = font_data;
       pending_canvas_rotation_ = canvas_rotation;
       pending_vertical_baseline_x_offset_ =
-          canvas_rotation == CanvasRotationInVertical::kRegular
+          !IsCanvasRotationInVerticalUpright(canvas_rotation)
               ? 0
               : font_data->GetFontMetrics().FloatAscent() -
                     font_data->GetFontMetrics().FloatAscent(
diff --git a/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h b/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
index 98e2295..8600f44 100644
--- a/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
+++ b/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
@@ -36,6 +36,9 @@
     return 0;
   }
   bool IsPaused() const override { return false; }
+  WebURLLoader::DeferType DeferType() const override {
+    return WebURLLoader::DeferType::kNotDeferred;
+  }
   bool IsDetached() const override { return true; }
   bool IsLoadDeferred() const override { return false; }
   bool IsLoadComplete() const override { return true; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 900b1ce..25ad130 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -2072,7 +2072,7 @@
   StopFetchingInternal(StopFetchingTarget::kExcludingKeepaliveLoaders);
 }
 
-void ResourceFetcher::SetDefersLoading(bool defers) {
+void ResourceFetcher::SetDefersLoading(WebURLLoader::DeferType defers) {
   for (const auto& loader : non_blocking_loaders_)
     loader->SetDefersLoading(defers);
   for (const auto& loader : loaders_)
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index 981c18e..6ea8adc 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -34,6 +34,7 @@
 #include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-blink-forward.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
 #include "third_party/blink/renderer/platform/loader/fetch/preload_key.h"
@@ -63,7 +64,6 @@
 class ResourceTimingInfo;
 class SubresourceWebBundle;
 class WebCodeCacheLoader;
-class WebURLLoader;
 struct ResourceFetcherInit;
 struct ResourceLoaderOptions;
 
@@ -218,7 +218,7 @@
 
   MHTMLArchive* Archive() const { return archive_.Get(); }
 
-  void SetDefersLoading(bool);
+  void SetDefersLoading(WebURLLoader::DeferType);
   void StopFetching();
 
   bool ShouldDeferImageLoad(const KURL&) const;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
index 0fbb2d13..f1bffa6 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_FETCHER_PROPERTIES_H_
 
 #include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-blink.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/scheduler/public/frame_status.h"
@@ -64,6 +65,9 @@
   // https://html.spec.whatwg.org/C/webappapis.html#pause
   virtual bool IsPaused() const = 0;
 
+  // Returns the deferred status of the loading in the global context.
+  virtual WebURLLoader::DeferType DeferType() const = 0;
+
   // Returns whether this global context is detached. Note that in some cases
   // the loading pipeline continues working after detached (e.g., for fetch()
   // operations with "keepalive" specified).
@@ -133,6 +137,9 @@
   bool IsPaused() const override {
     return properties_ ? properties_->IsPaused() : paused_;
   }
+  WebURLLoader::DeferType DeferType() const override {
+    return properties_ ? properties_->DeferType() : defer_type_;
+  }
   bool IsDetached() const override {
     return properties_ ? properties_->IsDetached() : true;
   }
@@ -173,6 +180,7 @@
   Member<const FetchClientSettingsObject> fetch_client_settings_object_;
   bool is_main_frame_ = false;
   bool paused_ = false;
+  WebURLLoader::DeferType defer_type_;
   bool load_complete_ = false;
   bool is_subframe_deprioritization_enabled_ = false;
   KURL web_bundle_physical_url_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index cf87379..e9c81d6 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -206,7 +206,7 @@
  public:
   CodeCacheRequest(std::unique_ptr<WebCodeCacheLoader> code_cache_loader,
                    const KURL& url,
-                   bool defers_loading)
+                   WebURLLoader::DeferType defers_loading)
       : status_(kNoRequestSent),
         code_cache_loader_(std::move(code_cache_loader)),
         url_(url),
@@ -232,7 +232,7 @@
   // once fetching from code cache is finished. Returns true if the
   // request is handled here and hence need not be handled by the loader.
   // Returns false otherwise.
-  bool SetDefersLoading(bool defers);
+  bool SetDefersLoading(WebURLLoader::DeferType defers);
 
  private:
   enum CodeCacheRequestStatus {
@@ -259,7 +259,8 @@
   CodeCacheRequestStatus status_;
   std::unique_ptr<WebCodeCacheLoader> code_cache_loader_;
   const WebURL url_;
-  bool defers_loading_ = false;
+  WebURLLoader::DeferType defers_loading_ =
+      WebURLLoader::DeferType::kNotDeferred;
   mojo_base::BigBuffer cached_code_;
   base::Time cached_code_response_time_;
   base::Time resource_response_time_;
@@ -279,7 +280,7 @@
   // ensure that the resource receives cached code before the response data.
   // This directly calls the WebURLLoader's SetDefersLoading without going
   // through ResourceLoader.
-  url_loader->SetDefersLoading(true);
+  url_loader->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
 
   WebCodeCacheLoader::FetchCodeCacheCallback callback =
       base::BindOnce(&ResourceLoader::CodeCacheRequest::DidReceiveCachedCode,
@@ -317,7 +318,8 @@
 
 // Returns true if |this| handles |defers| and therefore the callsite, i.e. the
 // loader, doesn't need to take care of it). Returns false otherwise.
-bool ResourceLoader::CodeCacheRequest::SetDefersLoading(bool defers) {
+bool ResourceLoader::CodeCacheRequest::SetDefersLoading(
+    WebURLLoader::DeferType defers) {
   defers_loading_ = defers;
   if (status_ == kPendingResponse) {
     // The flag doesn't need to be handled by the loader. The value is stored
@@ -578,12 +580,12 @@
 
   is_downloading_to_blob_ = request.DownloadToBlob();
 
-  SetDefersLoading(fetcher_->GetProperties().IsLoadDeferred());
+  SetDefersLoading(fetcher_->GetProperties().DeferType());
 
   if (ShouldFetchCodeCache()) {
     code_cache_request_ = std::make_unique<CodeCacheRequest>(
         fetcher_->CreateCodeCacheLoader(), request.Url(),
-        fetcher_->GetProperties().IsLoadDeferred());
+        fetcher_->GetProperties().DeferType());
   }
 
   if (is_cache_aware_loading_activated_) {
@@ -620,7 +622,7 @@
   StartWith(request);
 }
 
-void ResourceLoader::SetDefersLoading(bool defers) {
+void ResourceLoader::SetDefersLoading(WebURLLoader::DeferType defers) {
   DCHECK(loader_);
   defers_ = defers;
   // If CodeCacheRequest handles this, then no need to handle here.
@@ -628,16 +630,18 @@
     return;
 
   if (response_body_loader_) {
-    if (defers && !response_body_loader_->IsSuspended()) {
+    if (defers != WebURLLoader::DeferType::kNotDeferred &&
+        !response_body_loader_->IsSuspended()) {
       response_body_loader_->Suspend();
     }
-    if (!defers && response_body_loader_->IsSuspended()) {
+    if (defers == WebURLLoader::DeferType::kNotDeferred &&
+        response_body_loader_->IsSuspended()) {
       response_body_loader_->Resume();
     }
   }
 
   if (defers_handling_data_url_) {
-    if (!defers_) {
+    if (defers_ == WebURLLoader::DeferType::kNotDeferred) {
       defers_handling_data_url_ = false;
       GetLoadingTaskRunner()->PostTask(
           FROM_HERE,
@@ -646,7 +650,7 @@
   }
 
   loader_->SetDefersLoading(defers);
-  if (defers) {
+  if (defers != WebURLLoader::DeferType::kNotDeferred) {
     resource_->VirtualTimePauser().UnpauseVirtualTime();
   } else {
     resource_->VirtualTimePauser().PauseVirtualTime();
@@ -1454,7 +1458,7 @@
 void ResourceLoader::HandleDataUrl() {
   if (!IsLoading())
     return;
-  if (defers_) {
+  if (defers_ != WebURLLoader::DeferType::kNotDeferred) {
     defers_handling_data_url_ = true;
     return;
   }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
index aa72efa..edf5958 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
@@ -84,7 +84,7 @@
   void ScheduleCancel();
   void Cancel();
 
-  void SetDefersLoading(bool);
+  void SetDefersLoading(WebURLLoader::DeferType);
 
   void DidChangePriority(ResourceLoadPriority, int intra_priority_value);
 
@@ -239,9 +239,8 @@
   base::Optional<DeferredFinishLoadingInfo> deferred_finish_loading_info_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_body_loader_;
 
-  // True if loading is deferred.
-  bool defers_ = false;
-  // True if the next call of SetDefersLoading(false) needs to invoke
+  WebURLLoader::DeferType defers_ = WebURLLoader::DeferType::kNotDeferred;
+  // True if the next call of SetDefersLoading(kNotDeferred) needs to invoke
   // HandleDataURL().
   bool defers_handling_data_url_ = false;
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc
index ef2a633..b3755010 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h"
 
 #include "base/bind.h"
+#include "base/debug/stack_trace.h"
 #include "mojo/public/cpp/base/big_buffer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
@@ -56,7 +57,7 @@
 // A mock WebURLLoader to know the status of defers flag.
 class TestWebURLLoader final : public WebURLLoader {
  public:
-  explicit TestWebURLLoader(bool* const defers_flag_ptr)
+  explicit TestWebURLLoader(WebURLLoader::DeferType* const defers_flag_ptr)
       : defers_flag_ptr_(defers_flag_ptr) {}
   ~TestWebURLLoader() override = default;
 
@@ -87,7 +88,9 @@
           resource_load_info_notifier_wrapper,
       WebURLLoaderClient*) override {}
 
-  void SetDefersLoading(bool defers) override { *defers_flag_ptr_ = defers; }
+  void SetDefersLoading(WebURLLoader::DeferType defers) override {
+    *defers_flag_ptr_ = defers;
+  }
   void DidChangePriority(WebURLRequest::Priority, int) override {
     NOTREACHED();
   }
@@ -98,13 +101,13 @@
 
  private:
   // Points to |ResourceLoaderDefersLoadingTest::web_url_loader_defers_|.
-  bool* const defers_flag_ptr_;
+  WebURLLoader::DeferType* const defers_flag_ptr_;
 };
 
 class DeferTestLoaderFactory final : public ResourceFetcher::LoaderFactory {
  public:
   DeferTestLoaderFactory(
-      bool* const defers_flag,
+      WebURLLoader::DeferType* const defers_flag,
       ProcessCodeCacheRequestCallback process_code_cache_request_callback)
       : defers_flag_(defers_flag),
         process_code_cache_request_callback_(
@@ -127,7 +130,7 @@
 
  private:
   // Points to |ResourceLoaderDefersLoadingTest::web_url_loader_defers_|.
-  bool* const defers_flag_;
+  WebURLLoader::DeferType* const defers_flag_;
 
   ProcessCodeCacheRequestCallback process_code_cache_request_callback_;
 };
@@ -167,7 +170,8 @@
   WebCodeCacheLoader::FetchCodeCacheCallback code_cache_response_callback_;
   // Passed to TestWebURLLoader (via |platform_|) and updated when its
   // SetDefersLoading method is called.
-  bool web_url_loader_defers_ = false;
+  WebURLLoader::DeferType web_url_loader_defers_ =
+      WebURLLoader::DeferType::kNotDeferred;
   const KURL test_url_ = KURL("http://example.com/");
 
   ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
@@ -186,11 +190,11 @@
   Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
 
   // After code cache fetch it should have deferred WebURLLoader.
-  DCHECK(web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
   DCHECK(resource);
   std::move(code_cache_response_callback_).Run(base::Time(), {});
   // Once the response is received it should be reset.
-  DCHECK(!web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kNotDeferred);
 }
 
 TEST_F(ResourceLoaderDefersLoadingTest, CodeCacheFetchSyncReturn) {
@@ -210,7 +214,7 @@
   Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
   DCHECK(resource);
   // The callback would be called so it should not be deferred.
-  DCHECK(!web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kNotDeferred);
 }
 
 TEST_F(ResourceLoaderDefersLoadingTest, ChangeDefersToFalse) {
@@ -223,13 +227,13 @@
       FetchParameters::CreateForTest(std::move(request));
 
   Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
-  DCHECK(web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
 
   // Change Defers loading to false. This should not be sent to
   // WebURLLoader since a code cache request is still pending.
   ResourceLoader* loader = resource->Loader();
-  loader->SetDefersLoading(false);
-  DCHECK(web_url_loader_defers_);
+  loader->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
 }
 
 TEST_F(ResourceLoaderDefersLoadingTest, ChangeDefersToTrue) {
@@ -242,16 +246,40 @@
       FetchParameters::CreateForTest(std::move(request));
 
   Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
-  DCHECK(web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
 
   ResourceLoader* loader = resource->Loader();
-  loader->SetDefersLoading(true);
-  DCHECK(web_url_loader_defers_);
+  loader->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
 
   std::move(code_cache_response_callback_).Run(base::Time(), {});
   // Since it was requested to be deferred, it should be reset to the
   // correct value.
-  DCHECK(web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
+}
+
+TEST_F(ResourceLoaderDefersLoadingTest, ChangeDefersToBfcacheDefer) {
+  auto* fetcher = CreateFetcher();
+
+  ResourceRequest request;
+  request.SetUrl(test_url_);
+  request.SetRequestContext(mojom::blink::RequestContextType::FETCH);
+  FetchParameters fetch_parameters =
+      FetchParameters::CreateForTest(std::move(request));
+
+  Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
+
+  ResourceLoader* loader = resource->Loader();
+  loader->SetDefersLoading(
+      WebURLLoader::DeferType::kDeferredWithBackForwardCache);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
+
+  std::move(code_cache_response_callback_).Run(base::Time(), {});
+  // Since it was requested to be deferred, it should be reset to the
+  // correct value.
+  DCHECK_EQ(web_url_loader_defers_,
+            WebURLLoader::DeferType::kDeferredWithBackForwardCache);
 }
 
 TEST_F(ResourceLoaderDefersLoadingTest, ChangeDefersMultipleTimes) {
@@ -264,17 +292,17 @@
   FetchParameters fetch_parameters =
       FetchParameters::CreateForTest(std::move(request));
   Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
-  DCHECK(web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
 
   ResourceLoader* loader = resource->Loader();
-  loader->SetDefersLoading(true);
-  DCHECK(web_url_loader_defers_);
+  loader->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
 
-  loader->SetDefersLoading(false);
-  DCHECK(web_url_loader_defers_);
+  loader->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kDeferred);
 
   std::move(code_cache_response_callback_).Run(base::Time(), {});
-  DCHECK(!web_url_loader_defers_);
+  DCHECK_EQ(web_url_loader_defers_, WebURLLoader::DeferType::kNotDeferred);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
index 60cce06..615e434e 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
@@ -112,7 +112,7 @@
             resource_load_info_notifier_wrapper,
         WebURLLoaderClient*) override {}
 
-    void SetDefersLoading(bool) override {}
+    void SetDefersLoading(WebURLLoader::DeferType) override {}
     void DidChangePriority(WebURLRequest::Priority, int) override {
       NOTREACHED();
     }
@@ -388,24 +388,24 @@
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
 
   // The resource should still be pending since it's deferred.
-  fetcher->SetDefersLoading(true);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   task_runner->RunUntilIdle();
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
 
   // The resource should still be pending since it's deferred again.
-  fetcher->SetDefersLoading(true);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   task_runner->RunUntilIdle();
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
 
   // The resource should still be pending if it's unset and set in a single
   // task.
-  fetcher->SetDefersLoading(false);
-  fetcher->SetDefersLoading(true);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   task_runner->RunUntilIdle();
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
 
   // The resource has a parsed body.
-  fetcher->SetDefersLoading(false);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
   task_runner->RunUntilIdle();
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kCached);
   scoped_refptr<const SharedBuffer> buffer = resource->ResourceBuffer();
@@ -435,7 +435,7 @@
   auto* raw_resource_client = MakeGarbageCollected<TestRawResourceClient>();
   Resource* resource = RawResource::Fetch(params, fetcher, raw_resource_client);
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
-  fetcher->SetDefersLoading(true);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   task_runner->RunUntilIdle();
 
   // It's still pending because the body should not provided yet.
@@ -444,14 +444,14 @@
 
   // The body should be provided since not deferring now, but it's still pending
   // since we haven't read the body yet.
-  fetcher->SetDefersLoading(false);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
   task_runner->RunUntilIdle();
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
   EXPECT_TRUE(raw_resource_client->body());
 
   // The resource should still be pending when it's set to deferred again. No
   // body is provided when deferred.
-  fetcher->SetDefersLoading(true);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   task_runner->RunUntilIdle();
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
   const char* buffer;
@@ -462,15 +462,15 @@
 
   // The resource should still be pending if it's unset and set in a single
   // task. No body is provided when deferred.
-  fetcher->SetDefersLoading(false);
-  fetcher->SetDefersLoading(true);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   task_runner->RunUntilIdle();
   EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
   result = raw_resource_client->body()->BeginRead(&buffer, &available);
   EXPECT_EQ(BytesConsumer::Result::kShouldWait, result);
 
   // Read through the bytes consumer passed back from the ResourceLoader.
-  fetcher->SetDefersLoading(false);
+  fetcher->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
   task_runner->RunUntilIdle();
   auto* test_reader = MakeGarbageCollected<BytesConsumerTestReader>(
       raw_resource_client->body());
diff --git a/third_party/blink/renderer/platform/loader/internet_disconnected_web_url_loader.cc b/third_party/blink/renderer/platform/loader/internet_disconnected_web_url_loader.cc
index e0e6edd..2028e369 100644
--- a/third_party/blink/renderer/platform/loader/internet_disconnected_web_url_loader.cc
+++ b/third_party/blink/renderer/platform/loader/internet_disconnected_web_url_loader.cc
@@ -76,7 +76,7 @@
           WebURLError(net::ERR_INTERNET_DISCONNECTED, KURL(request->url))));
 }
 
-void InternetDisconnectedWebURLLoader::SetDefersLoading(bool defers) {}
+void InternetDisconnectedWebURLLoader::SetDefersLoading(DeferType defers) {}
 
 void InternetDisconnectedWebURLLoader::DidChangePriority(
     WebURLRequest::Priority,
diff --git a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc
index 0773f8c..b1a55ce 100644
--- a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc
+++ b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc
@@ -33,7 +33,8 @@
   Continue();
 }
 
-void StaticDataNavigationBodyLoader::SetDefersLoading(bool defers) {
+void StaticDataNavigationBodyLoader::SetDefersLoading(
+    WebURLLoader::DeferType defers) {
   defers_loading_ = defers;
   Continue();
 }
@@ -47,7 +48,8 @@
 }
 
 void StaticDataNavigationBodyLoader::Continue() {
-  if (defers_loading_ || !client_ || is_in_continue_)
+  if (defers_loading_ != WebURLLoader::DeferType::kNotDeferred || !client_ ||
+      is_in_continue_)
     return;
 
   // We don't want reentrancy in this method -
@@ -72,7 +74,7 @@
           return;
       }
 
-      if (defers_loading_) {
+      if (defers_loading_ != WebURLLoader::DeferType::kNotDeferred) {
         is_in_continue_ = false;
         return;
       }
diff --git a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.h b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.h
index 3f68d65..2bb84a7 100644
--- a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.h
+++ b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.h
@@ -26,7 +26,7 @@
   void Write(const SharedBuffer&);
   void Finish();
 
-  void SetDefersLoading(bool defers) override;
+  void SetDefersLoading(WebURLLoader::DeferType defers) override;
   void StartLoadingBody(WebNavigationBodyLoader::Client*,
                         bool use_isolated_code_cache) override;
 
@@ -35,7 +35,8 @@
 
   scoped_refptr<SharedBuffer> data_;
   WebNavigationBodyLoader::Client* client_ = nullptr;
-  bool defers_loading_ = false;
+  WebURLLoader::DeferType defers_loading_ =
+      WebURLLoader::DeferType::kNotDeferred;
   bool sent_all_data_ = false;
   bool received_all_data_ = false;
   bool is_in_continue_ = false;
diff --git a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader_test.cc b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader_test.cc
index df6d181..db929cf 100644
--- a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader_test.cc
+++ b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader_test.cc
@@ -47,9 +47,9 @@
   }
 
   void TakeActions() {
-    if (set_defers_loading_) {
-      set_defers_loading_ = false;
-      loader_->SetDefersLoading(true);
+    if (set_defers_loading_ != WebURLLoader::DeferType::kNotDeferred) {
+      set_defers_loading_ = WebURLLoader::DeferType::kNotDeferred;
+      loader_->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
     }
     if (!buffer_to_write_.IsEmpty()) {
       String buffer = buffer_to_write_;
@@ -74,7 +74,8 @@
   bool expecting_finished_ = false;
   bool did_finish_ = false;
   String buffer_to_write_;
-  bool set_defers_loading_ = false;
+  WebURLLoader::DeferType set_defers_loading_ =
+      WebURLLoader::DeferType::kNotDeferred;
   bool destroy_loader_ = false;
   String data_received_;
 };
@@ -98,11 +99,23 @@
        SetDefersLoadingAndWriteFromDataReceived) {
   loader_->StartLoadingBody(this, false);
   expecting_data_received_ = true;
-  set_defers_loading_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferred;
   buffer_to_write_ = "world";
   Write("hello");
   EXPECT_EQ("hello", TakeDataReceived());
-  loader_->SetDefersLoading(false);
+  loader_->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
+  EXPECT_EQ("world", TakeDataReceived());
+}
+
+TEST_F(StaticDataNavigationBodyLoaderTest,
+       SetDefersLoadingWithBfcacheAndWriteFromDataReceived) {
+  loader_->StartLoadingBody(this, false);
+  expecting_data_received_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferredWithBackForwardCache;
+  buffer_to_write_ = "world";
+  Write("hello");
+  EXPECT_EQ("hello", TakeDataReceived());
+  loader_->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
   EXPECT_EQ("world", TakeDataReceived());
 }
 
@@ -117,7 +130,18 @@
 TEST_F(StaticDataNavigationBodyLoaderTest, SetDefersLoadingFromDataReceived) {
   loader_->StartLoadingBody(this, false);
   expecting_data_received_ = true;
-  set_defers_loading_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferred;
+  Write("hello");
+  EXPECT_EQ("hello", TakeDataReceived());
+  Write("world");
+  EXPECT_EQ("", TakeDataReceived());
+}
+
+TEST_F(StaticDataNavigationBodyLoaderTest,
+       SetDefersLoadingWithBfcacheFromDataReceived) {
+  loader_->StartLoadingBody(this, false);
+  expecting_data_received_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferredWithBackForwardCache;
   Write("hello");
   EXPECT_EQ("hello", TakeDataReceived());
   Write("world");
@@ -140,21 +164,45 @@
   Write("hello");
   loader_->Finish();
   expecting_data_received_ = true;
-  set_defers_loading_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferred;
   loader_->StartLoadingBody(this, false);
   EXPECT_EQ("hello", TakeDataReceived());
   expecting_finished_ = true;
-  loader_->SetDefersLoading(false);
+  loader_->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
+  EXPECT_EQ("", TakeDataReceived());
+  EXPECT_TRUE(did_finish_);
+}
+
+TEST_F(StaticDataNavigationBodyLoaderTest,
+       SetDefersLoadingWithBfcacheFromFinishedDataReceived) {
+  Write("hello");
+  loader_->Finish();
+  expecting_data_received_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferredWithBackForwardCache;
+  loader_->StartLoadingBody(this, false);
+  EXPECT_EQ("hello", TakeDataReceived());
+  expecting_finished_ = true;
+  loader_->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
   EXPECT_EQ("", TakeDataReceived());
   EXPECT_TRUE(did_finish_);
 }
 
 TEST_F(StaticDataNavigationBodyLoaderTest, StartDeferred) {
-  loader_->SetDefersLoading(true);
+  loader_->SetDefersLoading(WebURLLoader::DeferType::kDeferred);
   loader_->StartLoadingBody(this, false);
   Write("hello");
   expecting_data_received_ = true;
-  loader_->SetDefersLoading(false);
+  loader_->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
+  EXPECT_EQ("hello", TakeDataReceived());
+}
+
+TEST_F(StaticDataNavigationBodyLoaderTest, StartDeferredWithBackForwardCache) {
+  loader_->SetDefersLoading(
+      WebURLLoader::DeferType::kDeferredWithBackForwardCache);
+  loader_->StartLoadingBody(this, false);
+  Write("hello");
+  expecting_data_received_ = true;
+  loader_->SetDefersLoading(WebURLLoader::DeferType::kNotDeferred);
   EXPECT_EQ("hello", TakeDataReceived());
 }
 
@@ -169,9 +217,17 @@
 TEST_F(StaticDataNavigationBodyLoaderTest, SetDefersLoadingFromFinished) {
   loader_->StartLoadingBody(this, false);
   expecting_finished_ = true;
-  set_defers_loading_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferred;
   loader_->Finish();
   EXPECT_TRUE(did_finish_);
 }
 
+TEST_F(StaticDataNavigationBodyLoaderTest,
+       SetDefersLoadingWithBfcacheFromFinished) {
+  loader_->StartLoadingBody(this, false);
+  expecting_finished_ = true;
+  set_defers_loading_ = WebURLLoader::DeferType::kDeferredWithBackForwardCache;
+  loader_->Finish();
+  EXPECT_TRUE(did_finish_);
+}
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h b/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
index 6245044..c565a54 100644
--- a/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
+++ b/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
@@ -44,6 +44,7 @@
     return service_worker_id_;
   }
   bool IsPaused() const override { return paused_; }
+  WebURLLoader::DeferType DeferType() const override { return defer_type_; }
   bool IsDetached() const override { return false; }
   bool IsLoadDeferred() const override { return false; }
   bool IsLoadComplete() const override { return load_complete_; }
@@ -83,6 +84,7 @@
       ControllerServiceWorkerMode::kNoController;
   int64_t service_worker_id_ = 0;
   bool paused_ = false;
+  WebURLLoader::DeferType defer_type_ = WebURLLoader::DeferType::kNotDeferred;
   bool load_complete_ = false;
   bool should_block_loading_sub_resource_ = false;
   bool is_subframe_deprioritization_enabled_ = false;
diff --git a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
index 165cfd5..afc339c5 100644
--- a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -154,6 +154,7 @@
   bool OptedOutFromAggressiveThrottlingForTest() const override {
     return false;
   }
+  bool IsInBackForwardCache() const override { return false; }
   bool RequestBeginMainFrameNotExpected(bool) override { return false; }
   WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
       const String& name,
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index dcc2479..ff5aeb8 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -1220,7 +1220,7 @@
 }
 
 void FrameSchedulerImpl::SetOnIPCTaskPostedWhileInBackForwardCacheHandler() {
-  DCHECK(parent_page_scheduler_->is_stored_in_back_forward_cache());
+  DCHECK(parent_page_scheduler_->IsInBackForwardCache());
   for (const auto& task_queue_and_voter :
        frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
     task_queue_and_voter.first->SetOnIPCTaskPosted(base::BindRepeating(
@@ -1270,7 +1270,7 @@
         ipc_interface_name);
   }
 
-  DCHECK(parent_page_scheduler_->is_stored_in_back_forward_cache());
+  DCHECK(parent_page_scheduler_->IsInBackForwardCache());
   base::UmaHistogramSparse(
       "BackForwardCache.Experimental.UnexpectedIPCMessagePostedToCachedFrame."
       "MethodHash",
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index 51a1727..d6bdc95 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -762,7 +762,7 @@
 
 bool MainThreadSchedulerImpl::IsIpcTrackingEnabledForAllPages() {
   for (auto* scheduler : main_thread_only().page_schedulers) {
-    if (!(scheduler->is_stored_in_back_forward_cache() &&
+    if (!(scheduler->IsInBackForwardCache() &&
           scheduler->has_ipc_detection_enabled())) {
       return false;
     }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
index 36aa818..27dfaab 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -70,7 +70,7 @@
   base::TimeTicks GetStoredInBackForwardCacheTimestamp() {
     return stored_in_back_forward_cache_timestamp_;
   }
-  bool is_stored_in_back_forward_cache() {
+  bool IsInBackForwardCache() const override {
     return is_stored_in_back_forward_cache_;
   }
   bool has_ipc_detection_enabled() { return has_ipc_detection_enabled_; }
diff --git a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
index a0a59ea..db5544f 100644
--- a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -61,6 +61,8 @@
   // Invoked when the local main frame's network becomes almost idle.
   // Never invoked if the main frame is remote.
   virtual void OnLocalMainFrameNetworkAlmostIdle() = 0;
+  // Whether the main frame of this page is in BackForwardCache or not.
+  virtual bool IsInBackForwardCache() const = 0;
 
   // Creates a new FrameScheduler. The caller is responsible for deleting
   // it. All tasks executed by the frame scheduler will be attributed to
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
index e3f05e3c..c59b2f4 100644
--- a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
@@ -90,6 +90,7 @@
   scheduler::WebAgentGroupScheduler& GetAgentGroupScheduler() override {
     return *agent_group_scheduler_;
   }
+  bool IsInBackForwardCache() const override { return false; }
 
  private:
   bool is_audio_playing_;
diff --git a/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc b/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
index 0a21e63..6bb318e 100644
--- a/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
+++ b/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
@@ -135,10 +135,10 @@
   factory_->CancelLoad(this);
 }
 
-void WebURLLoaderMock::SetDefersLoading(bool deferred) {
-  is_deferred_ = deferred;
+void WebURLLoaderMock::SetDefersLoading(DeferType deferred) {
+  is_deferred_ = (deferred != DeferType::kNotDeferred);
   // Ignores setDefersLoading(false) safely.
-  if (!deferred)
+  if (!is_deferred_)
     return;
 
   // setDefersLoading(true) is not implemented.
diff --git a/third_party/blink/renderer/platform/testing/weburl_loader_mock.h b/third_party/blink/renderer/platform/testing/weburl_loader_mock.h
index e700c091..4a036b4 100644
--- a/third_party/blink/renderer/platform/testing/weburl_loader_mock.h
+++ b/third_party/blink/renderer/platform/testing/weburl_loader_mock.h
@@ -68,7 +68,7 @@
       std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
           resource_load_info_notifier_wrapper,
       WebURLLoaderClient* client) override;
-  void SetDefersLoading(bool defer) override;
+  void SetDefersLoading(DeferType defer) override;
   void DidChangePriority(WebURLRequest::Priority new_priority,
                          int intra_priority_value) override;
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForBodyLoader()
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index 637086b..525599a 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -740,6 +740,7 @@
 
 ### webcodecs/
 crbug.com/591099 webcodecs/basic_video_encoding.html [ Failure ]
+crbug.com/591099 webcodecs/reconfiguring_encooder.html [ Failure ]
 
 # broken by https://chromium-review.googlesource.com/c/chromium/src/+/2392444
 crbug.com/958381 external/wpt/css/css-flexbox/table-as-item-wide-content.html [ Failure ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index 55d35c3a..ef5b3cd 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2082,6 +2082,9 @@
 # Memory measurement tests are run as virtual tests.
 external/wpt/measure-memory/* [ Skip ]
 virtual/force-eager/external/wpt/measure-memory/* [ Pass ]
+crbug.com/1150938 virtual/force-eager/external/wpt/measure-memory/detached.tentative.https.window.html [ Skip ]
+crbug.com/1150938 virtual/force-eager/external/wpt/measure-memory/window-open.mix.tentative.https.window.html [ Skip ]
+crbug.com/1085129 virtual/force-eager/external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.html [ Skip ]
 
 # Legacy SameSite cookie tests do not apply when non-legacy behavior is in effect.
 crbug.com/961439 external/wpt/cookies/samesite/fetch.https.html?legacy-samesite [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 26ea61a9b..664b6ccc 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1070,7 +1070,6 @@
 crbug.com/1130451 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-list-item-002.html [ Failure ]
 crbug.com/1079031 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-003.xht [ Crash Failure Timeout ]
 crbug.com/829028 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-004.html [ Failure ]
-crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/abspos-after-break-after.html [ Failure ]
 crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/abspos-new-width-rebalance.html [ Crash Failure ]
 crbug.com/1066616 virtual/layout_ng_block_frag/fast/multicol/border-radius-clipped-layer-second-column.html [ Failure ]
 crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rect-nested.html [ Failure ]
@@ -1136,7 +1135,6 @@
 crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change.html [ Failure ]
 crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/nested-columns.html [ Crash Failure ]
 crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/widows.html [ Failure ]
-crbug.com/1079031 virtual/layout_ng_block_frag/fragmentation/abspos-after-forced-break.html [ Failure ]
 crbug.com/829028 virtual/layout_ng_block_frag/fragmentation/auto-scrollbar-shrink-to-fit.html [ Failure ]
 crbug.com/1079031 virtual/layout_ng_block_frag/fragmentation/content-preceding-first-fragmentainer.html [ Crash Failure ]
 crbug.com/1079031 virtual/layout_ng_block_frag/fragmentation/relayout-abspos.html [ Failure ]
@@ -5458,6 +5456,9 @@
 crbug.com/1006759 http/tests/devtools/profiler/cpu-profiler-save-load.js [ Pass Failure Timeout ]
 crbug.com/1006759 http/tests/devtools/profiler/heap-snapshot-loader.js [ Pass Failure ]
 
+# Landing a DevTools change
+crbug.com/1152362 http/tests/devtools/profiler/heap-snapshot-summary-retainers.js [ Pass Failure Timeout ]
+
 # Temporarily disabled to land changes in DevTools, multiple dependent CLs
 # [1] https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2049183
 # [2] https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2119670
@@ -6029,3 +6030,6 @@
 crbug.com/1149734 http/tests/devtools/sources/source-frame-toolbar-items.js [ Pass Failure ]
 crbug.com/1149734 http/tests/devtools/sources/debugger-frameworks/frameworks-sourcemap.js [ Pass Failure ]
 crbug.com/1149734 http/tests/devtools/sources/debugger-ui/continue-to-location-markers.js [ Pass Failure ]
+
+#Sheriff 2020-11-24
+crbug.com/1087242 http/tests/inspector-protocol/service-worker/network-extrainfo-main-request.js [ Pass Failure Timeout Crash ]
\ No newline at end of file
diff --git a/third_party/blink/web_tests/android/ChromiumWPTExpectations b/third_party/blink/web_tests/android/ChromiumWPTExpectations
index 5c4e7f76..12e8e04 100644
--- a/third_party/blink/web_tests/android/ChromiumWPTExpectations
+++ b/third_party/blink/web_tests/android/ChromiumWPTExpectations
@@ -3146,18 +3146,18 @@
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/tabindex-001.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/tabindex-002.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/detached.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.cross-origin.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.cross-site.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.same-origin.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/main-frame-and-worker.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/main-frame.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/redirect.client.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/redirect.server.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.cross-origin.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.cross-site.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.mix.tentative.window.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.same-origin.tentative.window.html [ Failure Pass ]
+crbug.com/1050754 external/wpt/measure-memory/detached.tentative.https.window.html [ Failure Timeout ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.cross-site.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.same-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/main-frame.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/redirect.client.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/redirect.server.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.cross-site.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.mix.tentative.https.window.html [ Failure Timeout ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.same-origin.tentative.https.window.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/decodingInfo.any.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/decodingInfo.any.worker.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/encodingInfo.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WeblayerWPTExpectations b/third_party/blink/web_tests/android/WeblayerWPTExpectations
index 14e31c95..7c706b6 100644
--- a/third_party/blink/web_tests/android/WeblayerWPTExpectations
+++ b/third_party/blink/web_tests/android/WeblayerWPTExpectations
@@ -3124,18 +3124,18 @@
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/tabindex-001.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/tabindex-002.html [ Failure Timeout ]
-crbug.com/1050754 external/wpt/measure-memory/detached.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.cross-origin.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.cross-site.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.same-origin.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/main-frame-and-worker.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/main-frame.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/redirect.client.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/redirect.server.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.cross-origin.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.cross-site.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.mix.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.same-origin.tentative.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/detached.tentative.https.window.html [ Failure Timeout ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.cross-site.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.same-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/main-frame.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/redirect.client.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/redirect.server.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.cross-site.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.mix.tentative.https.window.html [ Failure Timeout ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.same-origin.tentative.https.window.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/decodingInfo.any.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/decodingInfo.any.worker.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/encodingInfo.html [ Failure ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations
index e250f77..fd2ac5d 100644
--- a/third_party/blink/web_tests/android/WebviewWPTExpectations
+++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -3371,18 +3371,18 @@
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/tabindex-001.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/mathml/relations/html5-tree/tabindex-002.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/detached.tentative.window.html [ Failure Timeout ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.cross-origin.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.cross-site.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/iframe.same-origin.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/main-frame-and-worker.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/main-frame.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/redirect.client.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/redirect.server.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.cross-origin.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.cross-site.tentative.window.html [ Failure ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.mix.tentative.window.html [ Failure Timeout ]
-crbug.com/1050754 external/wpt/measure-memory/window-open.same-origin.tentative.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/detached.tentative.https.window.html [ Failure Timeout ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.cross-site.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/iframe.same-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/main-frame.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/redirect.client.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/redirect.server.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.cross-site.tentative.https.window.html [ Failure ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.mix.tentative.https.window.html [ Failure Timeout ]
+crbug.com/1050754 external/wpt/measure-memory/window-open.same-origin.tentative.https.window.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/decodingInfo.any.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/decodingInfo.any.worker.html [ Failure ]
 crbug.com/1050754 external/wpt/media-capabilities/encodingInfo.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.https.window.js
new file mode 100644
index 0000000..179e5e72
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.https.window.js
@@ -0,0 +1,196 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'cross-site-1',
+      children: [
+        {
+          id: 'same-origin-2',
+        },
+        {
+          id: 'same-origin-11',
+          window_open: true,
+        },
+      ],
+    },
+    {
+      id: 'same-origin-3',
+      children: [
+        {
+          id: 'same-origin-4',
+        },
+        {
+          id: 'same-origin-12',
+          window_open: true,
+        },
+      ],
+    },
+    {
+      id: 'cross-origin-5',
+      children: [
+        {
+          id: 'same-origin-6',
+        },
+        {
+          id: 'same-origin-13',
+          window_open: true,
+        },
+      ],
+    },
+    {
+      id: 'same-origin-7',
+      window_open: true,
+      children: [
+        {
+          id: 'same-origin-8',
+        }
+      ],
+    },
+    {
+      id: 'cross-origin-9',
+      window_open: true,
+      children: [
+        {
+          id: 'same-origin-10',
+        }
+      ],
+    },
+  ]);
+  const expected = [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: 'cross-origin-url',
+      scope: 'cross-origin-aggregated',
+      container: {
+        id: 'cross-site-1',
+        src: iframes['cross-site-1'].src,
+      },
+    },
+    {
+      url: windows['same-origin-2'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'cross-site-1',
+        src: iframes['cross-site-1'].src,
+      },
+    },
+    {
+      url: windows['same-origin-3'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-3',
+        src: iframes['same-origin-3'].src,
+      },
+    },
+    {
+      url: windows['same-origin-4'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-4',
+        src: iframes['same-origin-4'].src,
+      },
+    },
+    {
+      url: 'cross-origin-url',
+      scope: 'cross-origin-aggregated',
+      container: {
+        id: 'cross-origin-5',
+        src: iframes['cross-origin-5'].src,
+      },
+    },
+    {
+      url: windows['same-origin-6'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'cross-origin-5',
+        src: iframes['cross-origin-5'].src,
+      },
+    },
+    {
+      url: windows['same-origin-8'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-8',
+        src: iframes['same-origin-8'].src,
+      },
+    },
+    {
+      url: windows['same-origin-7'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-11'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-12'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-13'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+  ];
+  const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows));
+  // Detach iframes:
+  // 1) By setting src attribute:
+  iframes['cross-site-1'].src =
+      iframes['cross-site-1'].src.replace('iframe.sub', 'iframe.secret.sub');
+  // 2) By setting location attribute:
+  let url = iframes['same-origin-3'].contentWindow.location.href;
+  url = url.replace('iframe.sub', 'iframe.secret.sub');
+  iframes['same-origin-3'].contentWindow.location.href = url;
+  // 3) By removing from the DOM tree:
+  iframes['cross-origin-5'].parentNode.removeChild(iframes['cross-origin-5']);
+
+  // Detach windows:
+  // 1) By setting document.location attribute:
+  url = windows['same-origin-7'].location.href;
+  url = url.replace('window.sub', 'window.secret.sub');
+  windows['same-origin-7'].location.href = url;
+  // 2) By closing the window:
+  windows['same-origin-10'].parent.close();
+
+  await waitForMessage('cross-site-1');
+  await waitForMessage('same-origin-3');
+  await waitForMessage('same-origin-7');
+
+  expected.push({
+    url: 'cross-origin-url',
+    scope: 'cross-origin-aggregated',
+    container: {
+      id: 'cross-site-1',
+      src: iframes['cross-site-1'].src,
+    },
+  });
+
+  expected.push({
+    url: windows['same-origin-3'].location.href,
+    scope: 'Window',
+    container: {
+      id: 'same-origin-3',
+      src: iframes['same-origin-3'].src,
+    },
+  });
+  expected.push({
+    url: windows['same-origin-7'].location.href,
+    scope: 'Window',
+    container: null,
+  });
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, expected);
+}, 'performance.measureMemory URLs within a cross-site iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.window.js
deleted file mode 100644
index c6a133c..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/detached.tentative.window.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {iframes, windows} = await build([
-    {
-      id: 'cross-site-1',
-      children: [
-        {
-          id: 'same-origin-2',
-        },
-        {
-          id: 'same-origin-11',
-          window_open: true,
-        },
-      ],
-    },
-    {
-      id: 'same-origin-3',
-      children: [
-        {
-          id: 'same-origin-4',
-        },
-        {
-          id: 'same-origin-12',
-          window_open: true,
-        },
-      ],
-    },
-    {
-      id: 'cross-origin-5',
-      children: [
-        {
-          id: 'same-origin-6',
-        },
-        {
-          id: 'same-origin-13',
-          window_open: true,
-        },
-      ],
-    },
-    {
-      id: 'same-origin-7',
-      window_open: true,
-      children: [
-        {
-          id: 'same-origin-8',
-        }
-      ],
-    },
-    {
-      id: 'cross-origin-9',
-      window_open: true,
-      children: [
-        {
-          id: 'same-origin-10',
-        }
-      ],
-    },
-  ]);
-  const allowed = [
-    window.location.href,
-    iframes['cross-site-1'].src,
-    iframes['same-origin-3'].src,
-    iframes['same-origin-4'].src,
-    iframes['cross-origin-5'].src,
-    iframes['same-origin-8'].sec,
-    windows['same-origin-7'].location.href,
-    windows['same-origin-12'].location.href,
-  ];
-  const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows));
-  // Detach iframes:
-  // 1) By setting src attribute:
-  iframes['cross-site-1'].src =
-      iframes['cross-site-1'].src.replace('iframe.sub', 'iframe.secret.sub');
-  // 2) By setting location attribute:
-  let url = iframes['same-origin-3'].contentWindow.location.href;
-  url = url.replace('iframe.sub', 'iframe.secret.sub');
-  iframes['same-origin-3'].contentWindow.location.href = url;
-  // 3) By removing from the DOM tree:
-  iframes['cross-origin-5'].parentNode.removeChild(iframes['cross-origin-5']);
-
-  // Detach windows:
-  // 1) By setting document.location attribute:
-  url = windows['same-origin-7'].location.href;
-  url = url.replace('window.sub', 'window.secret.sub');
-  windows['same-origin-7'].location.href = url;
-  // 2) By closing the window:
-  windows['cross-origin-9'].close();
-
-  await waitForMessage('cross-site-1');
-  await waitForMessage('same-origin-3');
-  await waitForMessage('same-origin-7');
-
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: allowed.concat([
-        iframes['cross-site-1'].src,
-        iframes['same-origin-3'].contentWindow.location.href,
-        windows['same-origin-7'].location.href,
-      ]),
-      required: [
-        window.location.href,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory URLs within a cross-site iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.js
new file mode 100644
index 0000000..ac0641cc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.js
@@ -0,0 +1,49 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'cross-origin-1',
+      children: [
+        {
+          id: 'same-origin-2',
+        },
+        {
+          id: 'cross-origin-3',
+        },
+        {
+          id: 'cross-site-4',
+        }
+      ],
+    },
+  ]);
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: 'cross-origin-url',
+      scope: 'cross-origin-aggregated',
+      container: {
+        id: 'cross-origin-1',
+        src: iframes['cross-origin-1'].src,
+      },
+    },
+    {
+      url: windows['same-origin-2'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'cross-origin-1',
+        src: iframes['cross-origin-1'].src,
+      },
+    },
+  ]);
+}, 'performance.measureMemory URLs within a cross-origin iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.window.js
deleted file mode 100644
index a9dccc8..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-origin.tentative.window.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {iframes} = await build([
-    {
-      id: 'cross-origin-1',
-      children: [
-        {
-          id: 'same-origin-2',
-        },
-        {
-          id: 'cross-origin-3',
-        },
-        {
-          id: 'cross-site-4',
-        }
-      ],
-    },
-  ]);
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-        iframes['cross-origin-1'].src,
-      ],
-      required: [
-        window.location.href,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory URLs within a cross-origin iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.https.window.js
new file mode 100644
index 0000000..1b4dfc7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.https.window.js
@@ -0,0 +1,56 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'cross-site-1',
+      children: [
+        {
+          id: 'same-origin-2',
+        },
+        {
+          id: 'cross-origin-3',
+        },
+        {
+          id: 'cross-site-4',
+        }
+      ],
+    },
+  ]);
+  try {
+    const result = await performance.measureMemory();
+    checkMeasureMemory(result, [
+      {
+        url: window.location.href,
+        scope: 'Window',
+        container: null,
+      },
+      {
+        url: 'cross-origin-url',
+        scope: 'cross-origin-aggregated',
+        container: {
+          id: 'cross-site-1',
+          src: iframes['cross-site-1'].src,
+        },
+      },
+      {
+        url: windows['same-origin-2'].location.href,
+        scope: 'Window',
+        container: {
+          id: 'cross-site-1',
+          src: iframes['cross-site-1'].src,
+        },
+      },
+    ]);
+  } catch (error) {
+    if (!(error instanceof DOMException)) {
+      throw error;
+    }
+    assert_equals(error.name, 'SecurityError');
+  }
+}, 'performance.measureMemory URLs within a cross-site iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.window.js
deleted file mode 100644
index e40ce59..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.cross-site.tentative.window.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {iframes} = await build([
-    {
-      id: 'cross-site-1',
-      children: [
-        {
-          id: 'same-origin-2',
-        },
-        {
-          id: 'cross-origin-3',
-        },
-        {
-          id: 'cross-site-4',
-        }
-      ],
-    },
-  ]);
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-        iframes['cross-site-1'].src,
-      ],
-      required: [
-        window.location.href,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory URLs within a cross-site iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.https.window.js
new file mode 100644
index 0000000..1d546b2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.https.window.js
@@ -0,0 +1,43 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'same-origin-1',
+      children: [
+        {
+          id: 'same-origin-2',
+        }
+      ],
+    },
+  ]);
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-1'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-1',
+        src: iframes['same-origin-1'].src,
+      },
+    },
+    {
+      url: windows['same-origin-2'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-2',
+        src: iframes['same-origin-2'].src,
+      },
+    },
+  ]);
+}, 'Well-formed result of performance.measureMemory with same-origin iframes.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.window.js
deleted file mode 100644
index 7fc02036..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/iframe.same-origin.tentative.window.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {iframes} = await build([
-    {
-      id: 'same-origin-1',
-      children: [
-        {
-          id: 'same-origin-2',
-        }
-      ],
-    },
-  ]);
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-        iframes['same-origin-1'].src,
-        iframes['same-origin-2'].src,
-      ],
-      required: [
-        window.location.href,
-        iframes['same-origin-1'].src,
-        iframes['same-origin-2'].src,
-      ]
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'Well-formed result of performance.measureMemory with same-origin iframes.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.js
new file mode 100644
index 0000000..f0b8abf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.js
@@ -0,0 +1,26 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const BYTES_PER_WORKER = 10 * 1024 * 1024;
+  const worker_url = await createWorker(BYTES_PER_WORKER);
+  const result = await performance.measureMemory();
+  assert_greater_than_equal(result.bytes, BYTES_PER_WORKER);
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: worker_url,
+      scope: 'DedicatedWindow',
+      container: null,
+    },
+  ]);
+}, 'Well-formed result of performance.measureMemory.');
+
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.window.js
deleted file mode 100644
index 514a4ed0..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame-and-worker.tentative.window.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-
-promise_test(async testCase => {
- try {
-    const BYTES_PER_WORKER = 10 * 1024 * 1024;
-    await createWorker(BYTES_PER_WORKER);
-    const result = await performance.measureMemory();
-    assert_greater_than_equal(result.bytes, BYTES_PER_WORKER);
-    checkMeasureMemory(result, {
-      allowed: [window.location.href],
-      required: [window.location.href],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'Well-formed result of performance.measureMemory.');
-
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.https.window.js
new file mode 100644
index 0000000..fd58e93
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.https.window.js
@@ -0,0 +1,16 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+promise_test(async testCase => {
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+  ]);
+}, 'Well-formed result of performance.measureMemory.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.window.js
deleted file mode 100644
index 0a34abb..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/main-frame.tentative.window.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
- try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [window.location.href],
-      required: [window.location.href],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'Well-formed result of performance.measureMemory.');
-
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.https.window.js
new file mode 100644
index 0000000..36d9a9d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.https.window.js
@@ -0,0 +1,67 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'cross-origin-1',
+      redirect: 'client',
+      children: [
+        {
+          id: 'same-origin-2',
+        },
+        {
+          id: 'cross-origin-3',
+        },
+        {
+          id: 'cross-site-4',
+        }
+      ],
+    },
+    {
+      id: 'cross-origin-5',
+      redirect: 'client',
+      window_open: true,
+      children: [
+        {
+          id: 'same-origin-6',
+        },
+        {
+          id: 'cross-origin-7',
+        },
+        {
+          id: 'cross-site-8',
+        }
+      ],
+    },
+  ]);
+  const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows));
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: 'cross-origin-url',
+      scope: 'cross-origin-aggregated',
+      container: {
+        id: 'cross-origin-1',
+        src: frames['cross-origin-1'].src,
+      },
+    },
+    {
+      url: windows['same-origin-2'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'cross-origin-1',
+        src: iframes['cross-origin-1'].src,
+      },
+    },
+  ]);
+}, 'performance.measureMemory does not leak client redirected URL.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.window.js
deleted file mode 100644
index e38a325..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.client.tentative.window.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {iframes, windows} = await build([
-    {
-      id: 'cross-origin-1',
-      redirect: 'client',
-      children: [
-        {
-          id: 'same-origin-2',
-        },
-        {
-          id: 'cross-origin-3',
-        },
-        {
-          id: 'cross-site-4',
-        }
-      ],
-    },
-    {
-      id: 'cross-origin-5',
-      redirect: 'client',
-      window_open: true,
-      children: [
-        {
-          id: 'same-origin-6',
-        },
-        {
-          id: 'cross-origin-7',
-        },
-        {
-          id: 'cross-site-8',
-        }
-      ],
-    },
-  ]);
-  const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows));
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-        iframes['cross-origin-1'].src,
-      ],
-      required: [
-        window.location.href,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory does not leak client redirected URL.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.https.window.js
new file mode 100644
index 0000000..6506730
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.https.window.js
@@ -0,0 +1,67 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'cross-origin-1',
+      redirect: 'server',
+      children: [
+        {
+          id: 'same-origin-2',
+        },
+        {
+          id: 'cross-origin-3',
+        },
+        {
+          id: 'cross-site-4',
+        }
+      ],
+    },
+    {
+      id: 'cross-origin-5',
+      redirect: 'server',
+      window_open: true,
+      children: [
+        {
+          id: 'same-origin-6',
+        },
+        {
+          id: 'cross-origin-7',
+        },
+        {
+          id: 'cross-site-8',
+        }
+      ],
+    },
+  ]);
+  const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows));
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: 'cross-origin-url',
+      scope: 'cross-origin-aggregated',
+      container: {
+        id: 'cross-origin-1',
+        src: frames['cross-origin-1'].src,
+      },
+    },
+    {
+      url: windows['same-origin-2'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'cross-origin-1',
+        src: iframes['cross-origin-1'].src,
+      },
+    },
+  ]);
+}, 'performance.measureMemory does not leak server redirected URL.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.window.js
deleted file mode 100644
index 740abca..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/redirect.server.tentative.window.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {iframes, windows} = await build([
-    {
-      id: 'cross-origin-1',
-      redirect: 'server',
-      children: [
-        {
-          id: 'same-origin-2',
-        },
-        {
-          id: 'cross-origin-3',
-        },
-        {
-          id: 'cross-site-4',
-        }
-      ],
-    },
-    {
-      id: 'cross-origin-5',
-      redirect: 'server',
-      window_open: true,
-      children: [
-        {
-          id: 'same-origin-6',
-        },
-        {
-          id: 'cross-origin-7',
-        },
-        {
-          id: 'cross-site-8',
-        }
-      ],
-    },
-  ]);
-  const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows));
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-        iframes['cross-origin-1'].src,
-      ],
-      required: [
-        window.location.href,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory does not leak server redirected URL.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/common.js b/third_party/blink/web_tests/external/wpt/measure-memory/resources/common.js
index 3b246719..11b40d7d 100644
--- a/third_party/blink/web_tests/external/wpt/measure-memory/resources/common.js
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/common.js
@@ -1,11 +1,32 @@
 const ORIGINS = {
-  'same-origin': get_host_info().HTTP_ORIGIN,
-  'cross-origin': get_host_info().HTTP_REMOTE_ORIGIN,
-  'cross-site': get_host_info().HTTP_NOTSAMESITE_ORIGIN,
+  'same-origin': get_host_info().HTTPS_ORIGIN,
+  'cross-origin': get_host_info().HTTPS_REMOTE_ORIGIN,
+  'cross-site': get_host_info().HTTPS_NOTSAMESITE_ORIGIN,
 }
 
-function checkMeasureMemoryBreakdown(breakdown, options, required) {
-  const allowed = new Set(options.allowed);
+function checkContainer(actual, expected) {
+  if (!actual) return true;
+  if (!expected) return false;
+  return actual.id == expected.id && actual.src == expected.src;
+}
+
+function checkAttribuiton(attribution, expected) {
+  assert_own_property(attribution, 'url');
+  assert_own_property(attribution, 'scope');
+  let found = false;
+  for (const e of expected) {
+    if (attribution.url === e.url &&
+        attribution.scope === e.scope &&
+        checkContainer(attribution.container, e.container)) {
+      found = true;
+      e.found = true;
+    }
+  }
+  assert_true(found, JSON.stringify(attribution) +
+      ' is not found in ' + JSON.stringify(expected) + '.');
+}
+
+function checkBreakdown(breakdown, expected) {
   assert_own_property(breakdown, 'bytes');
   assert_greater_than_equal(breakdown.bytes, 0);
   assert_own_property(breakdown, 'userAgentSpecificTypes');
@@ -14,28 +35,25 @@
   }
   assert_own_property(breakdown, 'attribution');
   for (const attribution of breakdown.attribution) {
-    assert_equals(typeof attribution, 'string');
-    assert_true(
-        allowed.has(attribution),
-        `${attribution} must be in ${JSON.stringify(options.allowed)}`);
-    if (required.has(attribution)) {
-      required.delete(attribution);
-    }
+    checkAttribuiton(attribution, expected);
   }
 }
 
-function checkMeasureMemory(result, options) {
-    assert_own_property(result, 'bytes');
-    assert_own_property(result, 'breakdown');
-    const required = new Set(options.required);
-    let bytes = 0;
-    for (let breakdown of result.breakdown) {
-      checkMeasureMemoryBreakdown(breakdown, options, required);
-      bytes += breakdown.bytes;
+function checkMeasureMemory(result, expected) {
+  assert_own_property(result, 'bytes');
+  assert_own_property(result, 'breakdown');
+  let bytes = 0;
+  for (let breakdown of result.breakdown) {
+    checkBreakdown(breakdown, expected);
+    bytes += breakdown.bytes;
+  }
+  assert_equals(bytes, result.bytes);
+  for (const e of expected) {
+    if (e.required) {
+      assert_true(e.found,
+          JSON.stringify(e) + ' did not appear in the result.');
     }
-    assert_equals(bytes, result.bytes);
-    assert_equals(required.size, 0, JSON.stringify(result.breakdown) +
-        ' does not include ' + JSON.stringify(required.values()));
+  }
 }
 
 function url(params) {
@@ -52,7 +70,8 @@
   }
   let url = `${origin}/${file}?id=${params.id}`;
   if (params.redirect === 'server') {
-    url = `${origin}/common/redirect.py?location=${encodeURIComponent(url)}`;
+    url = (`${origin}/measure-memory/resources/redirect.py?` +
+           `location=${encodeURIComponent(url)}`);
   }
   return url;
 }
@@ -95,31 +114,7 @@
   }
 })();
 
-// Constructs iframes based on their descriptoin.
-async function build(children) {
-  window.accessible_children = {iframes: {}, windows: {}};
-  await Promise.all(children.map(buildChild));
-  const result = window.accessible_children;
-  delete window.accessible_children;
-  return result;
-}
-
-async function buildChild(params) {
-  let child = null;
-  function target() {
-    return params.window_open ? child : child.contentWindow;
-  }
-  if (params.window_open) {
-    child = window.open(url(params));
-  } else {
-    child = document.createElement('iframe');
-    child.src = url(params);
-    child.id = params.id;
-    document.body.appendChild(child);
-  }
-  const ready = await waitForMessage(params.id);
-  target().postMessage({id: 'parent', payload: params.children}, '*');
-  const done = await waitForMessage(params.id);
+function getMainWindow() {
   let main = window;
   while (true) {
     if (main === main.parent) {
@@ -132,17 +127,17 @@
       main = main.parent;
     }
   }
+  return main;
+}
+
+function isSameOrigin(other) {
   try {
-    main.accessible_children;
+    other.descendants;
   } catch (e) {
     // Cross-origin iframe that cannot access the main frame.
-    return;
+    return false;
   }
-  if (params.window_open) {
-    main.accessible_children.windows[params.id] = child;
-  } else  {
-    main.accessible_children.iframes[params.id] = child;
-  }
+  return !!other.descendants;
 }
 
 function getId() {
@@ -157,15 +152,57 @@
   return window.parent;
 }
 
+// Constructs iframes based on their descriptoin.
+async function build(children) {
+  window.descendants = {iframes: {}, windows: {}};
+  await Promise.all(children.map(buildChild));
+  const result = window.descendants;
+  return result;
+}
+
+async function buildChild(params) {
+  let child = null;
+  function target() {
+    return params.window_open ? child : child.contentWindow;
+  }
+  if (params.window_open) {
+    child = window.open(url(params));
+    if (!params.id.startsWith('same-origin')) {
+      // Cross-origin windows gets their own browsing context groups with COOP.
+      // The postMessage calls before would not work for them, so we do not
+      // wait for them to load.
+      return;
+    }
+  } else {
+    child = document.createElement('iframe');
+    child.src = url(params);
+    child.id = params.id;
+    document.body.appendChild(child);
+  }
+  const ready = await waitForMessage(params.id);
+  target().postMessage({id: 'parent', payload: params.children}, '*');
+  const done = await waitForMessage(params.id);
+  if (!params.window_open) {
+    const main = getMainWindow();
+    if (isSameOrigin(main)) {
+      main.descendants.iframes[params.id] = child;
+    }
+  }
+}
+
 // This function runs within an iframe.
 // It gets the children descriptions from the parent and constructs them.
 async function setupChild() {
   const id = getId();
+  const main = getMainWindow();
+  if (isSameOrigin(main)) {
+    main.descendants.windows[id] = window;
+  }
   document.getElementById('title').textContent = id;
   getParent().postMessage({id : id, payload: 'ready'}, '*');
   const children = await waitForMessage('parent');
   if (children) {
-    await build(children);
+    await Promise.all(children.map(buildChild));
   }
   getParent().postMessage({id: id, payload: 'done'}, '*');
 }
@@ -186,8 +223,7 @@
   let resolve_promise;
   const promise = new Promise(resolve => resolve_promise = resolve);
   worker.onmessage = function (message) {
-    assert_equals(message.data, 'ready');
-    resolve_promise();
+    resolve_promise(message.data);
   }
   worker.postMessage({bytes});
   return promise;
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.redirect.sub.html.headers b/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.redirect.sub.html.headers
new file mode 100644
index 0000000..4e798cd9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.redirect.sub.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Resource-Policy: cross-origin
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.secret.sub.html.headers b/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.secret.sub.html.headers
new file mode 100644
index 0000000..b227e84
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.secret.sub.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Resource-Policy: cross-origin
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.sub.html.headers b/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.sub.html.headers
new file mode 100644
index 0000000..b227e84
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/iframe.sub.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Resource-Policy: cross-origin
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/redirect.py b/third_party/blink/web_tests/external/wpt/measure-memory/resources/redirect.py
new file mode 100644
index 0000000..1e6dbff8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/redirect.py
@@ -0,0 +1,21 @@
+def main(request, response):
+    """Simple handler that causes redirection.
+
+    The request should typically have two query parameters:
+    status - The status to use for the redirection. Defaults to 302.
+    location - The resource to redirect to.
+    """
+    status = 302
+    if b"status" in request.GET:
+        try:
+            status = int(request.GET.first(b"status"))
+        except ValueError:
+            pass
+
+    response.status = status
+
+    location = request.GET.first(b"location")
+
+    response.headers.set(b"Location", location)
+    response.headers.set(b"Cross-Origin-Embedder-Policy", b"require-corp")
+    response.headers.set(b"Cross-Origin-Resource-Policy", b"cross-origin")
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.redirect.sub.html.headers b/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.redirect.sub.html.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.redirect.sub.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.secret.sub.html.headers b/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.secret.sub.html.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.secret.sub.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.sub.html.headers b/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.sub.html.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/window.sub.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/worker.js b/third_party/blink/web_tests/external/wpt/measure-memory/resources/worker.js
index bc194a8..000df12 100644
--- a/third_party/blink/web_tests/external/wpt/measure-memory/resources/worker.js
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/worker.js
@@ -5,5 +5,5 @@
   for (let i = 0; i < length; i += 256) {
     self.root[i] = 1;
   }
-  postMessage('ready');
+  postMessage(self.location.href);
 }
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/resources/worker.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/resources/worker.js.headers
new file mode 100644
index 0000000..a271409
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/resources/worker.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Resource-Policy: same-origin
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.js
new file mode 100644
index 0000000..2e6561a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.js
@@ -0,0 +1,35 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'cross-origin-1',
+      window_open: true,
+      children: [
+        {
+          id: 'same-origin-2',
+          window_open: true,
+        },
+        {
+          id: 'same-origin-3',
+        },
+        {
+          id: 'cross-origin-4',
+        },
+      ]
+    },
+  ]);
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+  ]);
+}, 'performance.measureMemory does not leak URL of cross-origin window.open.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.window.js
deleted file mode 100644
index d067b2c1..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-origin.tentative.window.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {windows, iframes} = await build([
-    {
-      id: 'cross-origin-1',
-      window_open: true,
-      children: [
-        {
-          id: 'same-origin-2',
-          window_open: true,
-        },
-        {
-          id: 'same-origin-3',
-        },
-        {
-          id: 'cross-origin-4',
-        },
-      ]
-    },
-  ]);
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-      ],
-      required: [
-        window.location.href,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory does not leak URL of cross-origin window.open.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.https.window.js
new file mode 100644
index 0000000..f70ad9df
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.https.window.js
@@ -0,0 +1,35 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'cross-site-1',
+      window_open: true,
+      children: [
+        {
+          id: 'same-origin-2',
+          window_open: true,
+        },
+        {
+          id: 'same-origin-3',
+        },
+        {
+          id: 'cross-origin-4',
+        },
+      ]
+    },
+  ]);
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+  ]);
+}, 'performance.measureMemory does not leak URL of cross-site window.open.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.window.js
deleted file mode 100644
index 7fa49f5..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.cross-site.tentative.window.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {windows, iframes} = await build([
-    {
-      id: 'cross-site-1',
-      window_open: true,
-      children: [
-        {
-          id: 'same-origin-2',
-          window_open: true,
-        },
-        {
-          id: 'same-origin-3',
-        },
-        {
-          id: 'cross-origin-4',
-        },
-      ]
-    },
-  ]);
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-      ],
-      required: [
-        window.location.href,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory does not leak URL of cross-site window.open.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.https.window.js
new file mode 100644
index 0000000..6a913a8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.https.window.js
@@ -0,0 +1,135 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'same-origin-1',
+      children: [
+        {
+          id: 'same-origin-2',
+          window_open: true,
+          children: [
+            {
+              id: 'same-origin-3',
+              window_open: true,
+            },
+          ],
+        },
+        {
+          id: 'cross-origin-4',
+          children: [
+            {
+              id: 'same-origin-5',
+              window_open: true,
+            },
+          ],
+        },
+        {
+          id: 'cross-site-6',
+          children: [
+            {
+              id: 'same-origin-7',
+              window_open: true,
+            },
+          ],
+        },
+        {
+          id: 'same-origin-8',
+          children: [
+            {
+              id: 'cross-origin-9',
+              window_open: true,
+              children: [
+                {
+                  id: 'same-origin-10',
+                },
+                {
+                  id: 'same-origin-11',
+                  window_open: true,
+                },
+              ],
+            },
+            {
+              id: 'cross-site-12',
+              window_open: true,
+              children: [
+                {
+                  id: 'same-origin-13',
+                },
+                {
+                  id: 'same-origin-14',
+                  window_open: true,
+                },
+              ],
+            },
+          ],
+        },
+      ]
+    },
+  ]);
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-1'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-1',
+        src: iframes['same-origin-1'].src,
+      },
+    },
+    {
+      url: windows['same-origin-2'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-3'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: 'cross-origin-url',
+      scope: 'cross-origin-aggregated',
+      container: {
+        id: 'cross-origin-4',
+        src: iframes['cross-origin-4'].src,
+      },
+    },
+    {
+      url: windows['same-origin-5'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: 'cross-origin-url',
+      scope: 'cross-origin-aggregated',
+      container: {
+        id: 'cross-site-6',
+        src: iframes['cross-site-6'].src,
+      },
+    },
+    {
+      url: windows['same-origin-7'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-8'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-8',
+        src: iframes['same-origin-8'].src,
+      },
+    },
+  ]);
+}, 'performance.measureMemory does not leak URLs in cross-origin iframes and windows.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.window.js
deleted file mode 100644
index 5bb9d29..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.mix.tentative.window.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {windows, iframes} = await build([
-    {
-      id: 'same-origin-1',
-      children: [
-        {
-          id: 'same-origin-2',
-          window_open: true,
-          children: [
-            {
-              id: 'same-origin-3',
-              window_open: true,
-            },
-          ],
-        },
-        {
-          id: 'cross-origin-4',
-          children: [
-            {
-              id: 'same-origin-5',
-              window_open: true,
-            },
-          ],
-        },
-        {
-          id: 'cross-site-6',
-          children: [
-            {
-              id: 'same-origin-7',
-              window_open: true,
-            },
-          ],
-        },
-        {
-          id: 'same-origin-8',
-          children: [
-            {
-              id: 'cross-origin-9',
-              window_open: true,
-              children: [
-                {
-                  id: 'same-origin-10',
-                },
-                {
-                  id: 'same-origin-11',
-                  window_open: true,
-                },
-              ],
-            },
-            {
-              id: 'cross-site-12',
-              window_open: true,
-              children: [
-                {
-                  id: 'same-origin-13',
-                },
-                {
-                  id: 'same-origin-14',
-                  window_open: true,
-                },
-              ],
-            },
-          ],
-        },
-      ]
-    },
-  ]);
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-        iframes['same-origin-1'].src,
-        windows['same-origin-2'].location.href,
-        windows['same-origin-3'].location.href,
-        iframes['cross-origin-4'].src,
-        iframes['cross-site-6'].src,
-        iframes['same-origin-8'].src,
-      ],
-      required: [
-        window.location.href,
-        iframes['same-origin-1'].src,
-        windows['same-origin-2'].location.href,
-        windows['same-origin-3'].location.href,
-        iframes['same-origin-8'].src,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'performance.measureMemory does not leak URLs in cross-origin iframes and windows.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.https.window.js
new file mode 100644
index 0000000..5223a97b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.https.window.js
@@ -0,0 +1,50 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=./resources/common.js
+// META: timeout=long
+'use strict';
+
+assert_true(self.crossOriginIsolated);
+
+promise_test(async testCase => {
+  const {iframes, windows} = await build([
+    {
+      id: 'same-origin-1',
+      window_open: true,
+      children: [
+        {
+          id: 'same-origin-2',
+          window_open: true,
+        },
+        {
+          id: 'same-origin-3',
+        },
+      ]
+    },
+  ]);
+  const result = await performance.measureMemory();
+  checkMeasureMemory(result, [
+    {
+      url: window.location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-1'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-2'].location.href,
+      scope: 'Window',
+      container: null,
+    },
+    {
+      url: windows['same-origin-3'].location.href,
+      scope: 'Window',
+      container: {
+        id: 'same-origin-3',
+        src: iframes['same-origin-3'].src,
+      },
+    },
+  ]);
+}, 'Well-formed result of performance.measureMemory with same-origin window.open.');
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.https.window.js.headers b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.https.window.js.headers
new file mode 100644
index 0000000..4fff9d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.https.window.js.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Opener-Policy: same-origin
+Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.window.js b/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.window.js
deleted file mode 100644
index 7ec3cc43..0000000
--- a/third_party/blink/web_tests/external/wpt/measure-memory/window-open.same-origin.tentative.window.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// META: script=/common/get-host-info.sub.js
-// META: script=./resources/common.js
-// META: timeout=long
-'use strict';
-
-promise_test(async testCase => {
-  const {windows, iframes} = await build([
-    {
-      id: 'same-origin-1',
-      window_open: true,
-      children: [
-        {
-          id: 'same-origin-2',
-          window_open: true,
-        },
-        {
-          id: 'same-origin-3',
-        },
-      ]
-    },
-  ]);
-  try {
-    const result = await performance.measureMemory();
-    checkMeasureMemory(result, {
-      allowed: [
-        window.location.href,
-        windows['same-origin-1'].location.href,
-        windows['same-origin-2'].location.href,
-        iframes['same-origin-3'].src,
-      ],
-      required: [
-        window.location.href,
-        windows['same-origin-1'].location.href,
-        windows['same-origin-2'].location.href,
-        iframes['same-origin-3'].src,
-      ],
-    });
-  } catch (error) {
-    if (!(error instanceof DOMException)) {
-      throw error;
-    }
-    assert_equals(error.name, 'SecurityError');
-  }
-}, 'Well-formed result of performance.measureMemory with same-origin window.open.');
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-attachment.tentative.html b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-attachment.tentative.html
index c4a35d34..b9033f5 100644
--- a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-attachment.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-attachment.tentative.html
@@ -5,6 +5,7 @@
 <script src='/resources/testharness.js'></script>
 <script src='/resources/testharnessreport.js'></script>
 <script src='../resources/shadow-dom-utils.js'></script>
+<script src="support/helpers.js"></script>
 
 <script>
 const shadowContent = '<span>Shadow tree</span><slot></slot>';
@@ -18,7 +19,7 @@
   const declarativeString = `<${elementType} id=theelement>${getDeclarativeContent(mode, delegatesFocus)}
      <span class='lightdom'>${lightDomTextContent}</span></${elementType}>`;
   const wrapper = document.createElement('div');
-  wrapper.setInnerHTML(declarativeString, {includeShadowRoots: true});
+  setInnerHTML(wrapper, declarativeString);
   const element = wrapper.querySelector('#theelement');
   return {wrapper: wrapper, element: element};
 }
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-basic.tentative.html b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-basic.tentative.html
index 6e3c16a..a03743e4 100644
--- a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-basic.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-basic.tentative.html
@@ -5,6 +5,7 @@
 <link rel="help" href="https://github.com/whatwg/dom/issues/831">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="support/helpers.js"></script>
 
 <div id="host" style="display:none">
   <template shadowroot="open">
@@ -32,14 +33,14 @@
 
 test(() => {
   const div = document.createElement('div');
-  div.setInnerHTML(`
+  setInnerHTML(div,`
     <div id="host">
       <template shadowroot="open">
         <slot id="s1" name="slot1"></slot>
       </template>
       <div id="c1" slot="slot1"></div>
     </div>
-    `, {includeShadowRoots: true});
+    `);
   const host = div.querySelector('#host');
   const c1 = host.querySelector('#c1');
   assert_true(!!c1);
@@ -53,12 +54,12 @@
 
 test(() => {
   const div = document.createElement('div');
-  div.setInnerHTML(`
+  setInnerHTML(div,`
     <div id="host">
       <template shadowroot="invalid">
       </template>
     </div>
-    `, {includeShadowRoots: true});
+    `);
   const host = div.querySelector('#host');
   assert_equals(host.shadowRoot, null, "Shadow root was found");
   const tmpl = host.querySelector('template');
@@ -69,12 +70,12 @@
 
 test(() => {
   const div = document.createElement('div');
-  div.setInnerHTML(`
+  setInnerHTML(div,`
     <div id="host">
       <template shadowroot="closed">
       </template>
     </div>
-    `, {includeShadowRoots: true});
+    `);
   const host = div.querySelector('#host');
   assert_equals(host.shadowRoot, null, "Closed shadow root");
   assert_equals(host.querySelector('template'), null, "No template - converted to shadow root");
@@ -82,12 +83,12 @@
 
 test(() => {
   const div = document.createElement('div');
-  div.setInnerHTML(`
+  setInnerHTML(div,`
     <div id="host">
       <template shadowroot="open">
         <slot id="s1" name="slot1"></slot>
     </div>
-    `, {includeShadowRoots: true});
+    `);
   const host = div.querySelector('#host');
   assert_equals(host.querySelector('#s1'), null, "Should be inside shadow root");
   assert_equals(host.querySelector('template'), null, "No leftover template node");
@@ -98,35 +99,25 @@
 
 test(() => {
   const div = document.createElement('div');
-  div.setInnerHTML(`
+  setInnerHTML(div,`
     <div id="host">
       <template shadowroot="open" shadowrootdelegatesfocus>
       </template>
     </div>
-    `, {includeShadowRoots: true});
+    `);
   var host = div.querySelector('#host');
   assert_true(!!host.shadowRoot,"No shadow root found");
   assert_true(host.shadowRoot.delegatesFocus,"delegatesFocus should be true");
-  div.setInnerHTML(`
+  setInnerHTML(div,`
     <div id="host">
       <template shadowroot="open">
       </template>
     </div>
-    `, {includeShadowRoots: true});
+    `);
   host = div.querySelector('#host');
   assert_true(!!host.shadowRoot,"No shadow root found");
   assert_false(host.shadowRoot.delegatesFocus,"delegatesFocus should be false without the shadowrootdelegatesfocus attribute");
 }, 'Declarative Shadow DOM: delegates focus attribute');
-
-test(() => {
-  const host = document.createElement('div');
-  // Root element of setInnerHTML is a <template shadowroot>:
-  host.setInnerHTML('<template shadowroot=open></template>', {allowShadowRoot: true});
-  assert_equals(host.shadowRoot, null, "Shadow root should not be present");
-  const tmpl = host.querySelector('template');
-  assert_true(!!tmpl,"Template should still be present");
-  assert_equals(tmpl.getAttribute('shadowroot'),"open","'shadowroot' attribute should still be present");
-}, 'Declarative Shadow DOM: setInnerHTML root element');
 </script>
 
 <div id="multi-host" style="display:none">
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-opt-in.tentative.html b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-opt-in.tentative.html
index 2d6bf5f..d1fd9fc 100644
--- a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-opt-in.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/declarative-shadow-dom-opt-in.tentative.html
@@ -5,6 +5,7 @@
 <link rel="help" href="https://github.com/whatwg/dom/issues/831">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src='../resources/shadow-dom-utils.js'></script>
 
 <body>
 <style>
@@ -58,56 +59,40 @@
   assert_dsd(div,true);
 }, 'Non-fragment parsing needs no opt-in');
 
-test(() => {
-  const div = document.createElement('div');
-  div.innerHTML = content;
-  assert_dsd(div,false);
-}, 'innerHTML on element - disallowed');
+const noChildElements = ['iframe','noscript','script','select','style','textarea','title','colgroup'];
+const elements = HTML5_ELEMENT_NAMES.filter(el => !noChildElements.includes(el));
+for (let elementName of elements) {
+  var t = test(function() {
+    const el1 = document.createElement(elementName);
+    el1.innerHTML = content;
+    assert_dsd(el1,false);
 
-test(() => {
-  const div = document.createElement('div');
-  div.setInnerHTML(content);
-  assert_dsd(div,false);
-  div.setInnerHTML(content, {includeShadowRoots: false});
-  assert_dsd(div,false);
-  div.setInnerHTML(content, {includeShadowRoots: true});
-  assert_dsd(div,true);
-}, 'setInnerHTML on element');
-
-test(() => {
-  const templateContent = `<template id=tmpl>${content}</template>`;
-  const div = document.createElement('div');
-  div.innerHTML = templateContent;
-  assert_dsd(div.querySelector('#tmpl').content,false);
-  div.setInnerHTML(templateContent, {includeShadowRoots: true});
-  assert_dsd(div.querySelector('#tmpl').content,true);
-}, 'setInnerHTML on element, with nested template content');
+    const templateContent = `<template id=tmpl>${content}</template>`;
+    const el2 = document.createElement('div');
+    el2.innerHTML = templateContent;
+    assert_dsd(el2.querySelector('#tmpl').content,false);
+  }, `innerHTML on a <${elementName}>`);
+}
 
 test(() => {
   const temp = document.createElement('template');
   temp.innerHTML = content;
   assert_dsd(temp.content,false, 'innerHTML should not allow declarative shadow content');
-  temp.setInnerHTML(content, {includeShadowRoots: true});
-  assert_dsd(temp.content,true, 'setInnerHTML should allow declarative shadow content if enabled');
-}, 'setInnerHTML on template');
+}, 'innerHTML on template');
 
 test(() => {
   const templateContent = `<template id=tmpl>${content}</template>`;
   const temp = document.createElement('template');
   temp.innerHTML = templateContent;
   assert_dsd(temp.content.querySelector('#tmpl').content,false);
-  temp.setInnerHTML(templateContent, {includeShadowRoots: true});
-  assert_dsd(temp.content.querySelector('#tmpl').content,true);
-}, 'setInnerHTML on template, with nested template content');
+}, 'innerHTML on template, with nested template content');
 
 test(() => {
   const div = document.createElement('div');
   const shadow = div.attachShadow({mode: 'open'});
   shadow.innerHTML = content;
   assert_dsd(shadow,false);
-  shadow.setInnerHTML(content, {includeShadowRoots: true});
-  assert_dsd(shadow,true);
-}, 'setInnerHTML on shadowRoot');
+}, 'innerHTML on shadowRoot');
 
 test(() => {
   const parser = new DOMParser();
@@ -123,9 +108,7 @@
   const doc = document.implementation.createHTMLDocument('');
   doc.body.innerHTML = content;
   assert_dsd(doc.body,false);
-  doc.body.setInnerHTML(content, {includeShadowRoots: true});
-  assert_dsd(doc.body,true);
-}, 'createHTMLDocument with setInnerHTML');
+}, 'createHTMLDocument with innerHTML - not supported');
 
 test(() => {
   const doc = document.implementation.createHTMLDocument('');
@@ -145,7 +128,7 @@
   client.open("GET", `data:text/html,${content}`);
   client.responseType = 'document';
   client.send();
-}, 'XMLHttpRequest, disabled');
+}, 'XMLHttpRequest - not supported');
 
 test(() => {
   const div = document.createElement('div');
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/setinnerhtml.tentative.html b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/setinnerhtml.tentative.html
deleted file mode 100644
index c65bf04..0000000
--- a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/setinnerhtml.tentative.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<title>getInnerHTML </title>
-<link rel='author' title='Mason Freed' href='mailto:masonfreed@chromium.org'>
-<link rel='help' href='https://github.com/whatwg/dom/issues/831'>
-<script src='/resources/testharness.js'></script>
-<script src='/resources/testharnessreport.js'></script>
-<script src='../resources/shadow-dom-utils.js'></script>
-
-<body>
-<script>
-function testElementType(allowsShadowDom, elementType, applyToShadow) {
-  const t = test(t => {
-    // Create and attach element
-    let wrapper;
-    if (applyToShadow) {
-      const host = document.createElement('div');
-      t.add_cleanup(function() { host.remove(); });
-      document.body.appendChild(host);
-      wrapper = host.attachShadow({mode: 'open'});
-    } else {
-      wrapper = document.createElement('div');
-      t.add_cleanup(function() { wrapper.remove(); });
-      document.body.appendChild(wrapper);
-    }
-    const html = `<${elementType}><template shadowroot="open"><slot></slot></template><span></span></${elementType}>`;
-    wrapper.setInnerHTML(html, {includeShadowRoots: true});
-    if (allowsShadowDom) {
-      // Retrieve shadow root
-      assert_true(!!wrapper.firstElementChild.shadowRoot,'No shadow root found');
-    } else {
-      const leftover = wrapper.firstElementChild.firstElementChild;
-      assert_true(wrapper.firstElementChild.childElementCount == 0 || leftover instanceof HTMLTemplateElement,'Template should be left over (or no children)');
-    }
-  }, `${applyToShadow ? 'ShadowRoot' : 'Element'}.setInnerHTML() on <${elementType}>${allowsShadowDom ? `, with declarative Shadow DOM.` : ''}`);
-}
-
-function runAllTests() {
-  const allElements = [...HTML5_ELEMENT_NAMES, 'htmlunknown'].filter(item => item !== 'body');
-  const safelisted = ATTACHSHADOW_SAFELISTED_ELEMENTS;
-  for (const elementName of allElements) {
-    for (const applyToShadow of [false, true]) {
-      testElementType(safelisted.includes(elementName), elementName, applyToShadow);
-    }
-  }
-}
-
-runAllTests();
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/support/helpers.js b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/support/helpers.js
new file mode 100644
index 0000000..70808e8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/support/helpers.js
@@ -0,0 +1,4 @@
+function setInnerHTML(el,content) {
+  const fragment = (new DOMParser()).parseFromString(`<pre>${content}</pre>`, 'text/html', {includeShadowRoots: true});
+  el.replaceChildren(...fragment.body.firstChild.childNodes);
+}
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnectionIceErrorEvent.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnectionIceErrorEvent.html
new file mode 100644
index 0000000..4434cfd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnectionIceErrorEvent.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+test(() => {
+  init = {
+    address: "168.3.4.5",
+    port: 4711,
+    url: "turn:turn.example.org",
+    errorCode: 703,
+    errorText: "Test error"
+  };
+  event = new RTCPeerConnectionIceErrorEvent('type', init);
+  assert_equals(event.type, 'type');
+  assert_equals(event.address, '168.3.4.5');
+  assert_equals(event.port, 4711);
+  assert_equals(event.url, "turn:turn.example.org");
+  assert_equals(event.errorCode, 703);
+  assert_equals(event.errorText, "Test error");
+}, 'RTCPeerConnectionIceErrorEvent constructed from init parameters');
+
+</script>
+</html>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/text/vertical-upright-oblique-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/text/vertical-upright-oblique-expected.png
new file mode 100644
index 0000000..a5e51ff
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/text/vertical-upright-oblique-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-will-be-sent-extra-info-client-security-state-multiclient-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-will-be-sent-extra-info-client-security-state-multiclient-expected.txt
new file mode 100644
index 0000000..8944d6a9
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-will-be-sent-extra-info-client-security-state-multiclient-expected.txt
@@ -0,0 +1,13 @@
+Tests that client security state is reported on requestWillBeSentExtraInfo.
+Two sessions established and Network enabled on both
+{
+    initiatorIPAddressSpace : Local
+    initiatorIsSecureContext : true
+    privateNetworkRequestPolicy : Allow
+}
+{
+    initiatorIPAddressSpace : Local
+    initiatorIsSecureContext : true
+    privateNetworkRequestPolicy : Allow
+}
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-will-be-sent-extra-info-client-security-state-multiclient.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-will-be-sent-extra-info-client-security-state-multiclient.js
new file mode 100644
index 0000000..6243b38a
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-will-be-sent-extra-info-client-security-state-multiclient.js
@@ -0,0 +1,21 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startBlank(
+      `Tests that client security state is reported on requestWillBeSentExtraInfo.`);
+
+  await dp.Network.enable();
+  const dp2 = (await page.createSession()).protocol;
+  await dp2.Network.enable();
+  testRunner.log('Two sessions established and Network enabled on both');
+
+  const promise1 = dp.Network.onceRequestWillBeSentExtraInfo();
+  const promise2 = dp2.Network.onceRequestWillBeSentExtraInfo();
+
+  await session.evaluate(`fetch('index.html');`);
+
+  const [event1, event2] = await Promise.all([promise1, promise2]);
+  testRunner.log(event1.params.clientSecurityState)
+  testRunner.log(event2.params.clientSecurityState)
+
+
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/loading/sxg/resources/generate-test-sxgs.sh b/third_party/blink/web_tests/http/tests/loading/sxg/resources/generate-test-sxgs.sh
index 048eaae..a04c8b3 100755
--- a/third_party/blink/web_tests/http/tests/loading/sxg/resources/generate-test-sxgs.sh
+++ b/third_party/blink/web_tests/http/tests/loading/sxg/resources/generate-test-sxgs.sh
@@ -10,6 +10,7 @@
     if ! command -v $cmd > /dev/null 2>&1; then
         echo "$cmd is not installed. Please run:"
         echo "  go get -u github.com/WICG/webpackage/go/signedexchange/cmd/..."
+        echo '  export PATH=$PATH:$(go env GOPATH)/bin'
         exit 1
     fi
 done
@@ -81,7 +82,7 @@
   -content sxg-location.html \
   -certificate $certs_dir/127.0.0.1.sxg.pem \
   -certUrl https://127.0.0.1:8443/loading/sxg/resources/127.0.0.1.sxg.pem.cbor \
-  -validityUrl https://www2.127.0.0.1/loading/sxg/resources/resource.validity.msg \
+  -validityUrl https://127.0.0.1:8444/loading/sxg/resources/resource.validity.msg \
   -privateKey $certs_dir/127.0.0.1.sxg.key \
   -date 2018-04-01T00:00:00Z \
   -expire 168h \
diff --git a/third_party/blink/web_tests/http/tests/loading/sxg/resources/sxg-invalid-validity-url.sxg b/third_party/blink/web_tests/http/tests/loading/sxg/resources/sxg-invalid-validity-url.sxg
index 2b14938..d649572d 100644
--- a/third_party/blink/web_tests/http/tests/loading/sxg/resources/sxg-invalid-validity-url.sxg
+++ b/third_party/blink/web_tests/http/tests/loading/sxg/resources/sxg-invalid-validity-url.sxg
Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/declarative-shadow-dom-origin-trial-interfaces.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/declarative-shadow-dom-origin-trial-interfaces.html
index 41c410a..aa8028b7 100644
--- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/declarative-shadow-dom-origin-trial-interfaces.html
+++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/declarative-shadow-dom-origin-trial-interfaces.html
@@ -9,12 +9,18 @@
 <script src="/resources/testharnessreport.js"></script>
 <script>
 test(t => {
-  // Basic feature detection
   assert_true(HTMLTemplateElement.prototype.hasOwnProperty("shadowRoot"),'Unable to feature detect');
-  // Basic feature use
-  const div = document.createElement('div');
-  div.setInnerHTML('<div id="host"><template shadowroot="open"></template></div>', {includeShadowRoots: true});
-  const host = div.querySelector('#host');
+}, 'Declarative Shadow DOM feature detection for origin-trial enabled document.');
+</script>
+
+<div id=host>
+	<template shadowroot="open"></template>
+</div>
+
+<script>
+test(t => {
+  const host = document.querySelector('#host');
+  assert_true(!!host,"Unable to locate host");
   assert_true(!!host.shadowRoot,"No shadow root found");
 }, 'Declarative Shadow DOM enabled for origin-trial enabled document.');
 </script>
diff --git a/third_party/blink/web_tests/navigator_webdriver/navigator_webdriver_enabled.html b/third_party/blink/web_tests/navigator_webdriver/navigator_webdriver_enabled.html
index 6099382..0ab4451 100644
--- a/third_party/blink/web_tests/navigator_webdriver/navigator_webdriver_enabled.html
+++ b/third_party/blink/web_tests/navigator_webdriver/navigator_webdriver_enabled.html
@@ -20,9 +20,9 @@
 
 
 test(function() {
-  var descriptor = Object.getOwnPropertyDescriptor(navigator, "webdriver");
+  const descriptor = Object.getOwnPropertyDescriptor(Navigator.prototype, "webdriver");
   assert_true(descriptor !== undefined);
-  assert_false(descriptor.configurable);
+  assert_true(descriptor.configurable);
   assert_true(descriptor.enumerable);
   assert_true(descriptor.set === undefined);
 }, "Test that the navigator.webdriver descriptor has expected properties");
diff --git a/third_party/blink/web_tests/paint/text/vertical-upright-oblique.html b/third_party/blink/web_tests/paint/text/vertical-upright-oblique.html
new file mode 100644
index 0000000..ad012c40
--- /dev/null
+++ b/third_party/blink/web_tests/paint/text/vertical-upright-oblique.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<style>
+.o { font-style: oblique -15deg; }
+
+.s {
+    transform: skew(0deg, -15deg);
+    writing-mode: vertical-rl;
+}
+
+.u { text-orientation: upright; }
+
+.v { writing-mode: vertical-rl; }
+
+table {
+  font-size: 30px;
+  margin: 10px;
+}
+
+td {
+  border: solid 1px red;
+  padding: 5px;
+}
+</style>
+<table lang="ja"><tr>
+<td>
+<div style="writing-mode: vertical-rl">
+<div class="v o" id="target">これは斜体です。■□</div>
+<div class="v">これは直体です。■□</div>
+<div class="v o">oblique</div>
+<div class="v">normal.</div>
+<div class="v o u">upright+oblique</div>
+<div class="v u">upright.</div>
+</div>
+</td>
+<td>
+<div xstyle="writing-mode: vertical-rl">
+<span class="s">これは斜体です。■□ CSS</span>
+</div>
+</td>
+</tr></table>
+<script>
+const selection = window.getSelection();
+selection.collapse(target.firstChild, 1);
+selection.extend(target.firstChild, 3);
+</script>
diff --git a/third_party/blink/web_tests/platform/linux/paint/text/vertical-upright-oblique-expected.png b/third_party/blink/web_tests/platform/linux/paint/text/vertical-upright-oblique-expected.png
new file mode 100644
index 0000000..cbadaf4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/paint/text/vertical-upright-oblique-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/paint/text/vertical-upright-oblique-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/paint/text/vertical-upright-oblique-expected.png
new file mode 100644
index 0000000..5feedc3
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/paint/text/vertical-upright-oblique-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/paint/text/vertical-upright-oblique-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/paint/text/vertical-upright-oblique-expected.png
new file mode 100644
index 0000000..5feedc3
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/paint/text/vertical-upright-oblique-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/text/vertical-upright-oblique-expected.png b/third_party/blink/web_tests/platform/mac/paint/text/vertical-upright-oblique-expected.png
new file mode 100644
index 0000000..6efac87
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/paint/text/vertical-upright-oblique-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/text/vertical-upright-oblique-expected.png b/third_party/blink/web_tests/platform/win/paint/text/vertical-upright-oblique-expected.png
new file mode 100644
index 0000000..1c4a104
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/paint/text/vertical-upright-oblique-expected.png
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
new file mode 100644
index 0000000..8d2da91
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win7/paint/text/vertical-upright-oblique-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
index ae00245..efca04c1 100644
--- a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
@@ -308,7 +308,6 @@
     property setAttributeNS
     property setAttributeNode
     property setAttributeNodeNS
-    property setInnerHTML
     property setPointerCapture
     property shadowRoot
     property slot
@@ -1494,7 +1493,6 @@
     property setAttributeNS
     property setAttributeNode
     property setAttributeNodeNS
-    property setInnerHTML
     property setPointerCapture
     property shadowRoot
     property slot
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 43a230b..0df2bdc 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -2140,7 +2140,6 @@
     method setAttributeNS
     method setAttributeNode
     method setAttributeNodeNS
-    method setInnerHTML
     method setPointerCapture
     method toggleAttribute
     method webkitMatchesSelector
@@ -8066,7 +8065,6 @@
     method getAnimations
     method getInnerHTML
     method getSelection
-    method setInnerHTML
     setter adoptedStyleSheets
     setter fullscreenElement
     setter innerHTML
diff --git a/tools/idl_parser/idl_parser.py b/tools/idl_parser/idl_parser.py
index 5dfacf3..7954edb 100755
--- a/tools/idl_parser/idl_parser.py
+++ b/tools/idl_parser/idl_parser.py
@@ -1230,7 +1230,7 @@
 #
 # BuildError
 #
-# Build and Errror node as part of the recovery process.
+# Build and Error node as part of the recovery process.
 #
 #
   def BuildError(self, p, prod):
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index a17e0b8..74d9f15 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -17174,7 +17174,8 @@
   <int value="101" label="App Uninstall"/>
   <int value="102" label="Print Job Confirmation"/>
   <int value="103" label="Crostini Recovery Dialog"/>
-  <int value="104" label="Signin Reauth Dialog"/>
+  <int value="104" label="Parent Permission ChromeOS"/>
+  <int value="105" label="Signin Reauth Dialog"/>
 </enum>
 
 <enum name="DialogOriginRelationship">
@@ -64497,6 +64498,7 @@
   <int value="6" label="QUOTA_LIMIT"/>
   <int value="7" label="FAILED"/>
   <int value="8" label="FEATURE_UNAVAILABLE"/>
+  <int value="9" label="WEAK_PASSWORDS_EXIST"/>
 </enum>
 
 <enum name="SafetyCheckSafeBrowsingStatus">
diff --git a/tools/metrics/histograms/histograms_xml/power/histograms.xml b/tools/metrics/histograms/histograms_xml/power/histograms.xml
index 6af0b48..2cbd4a5 100644
--- a/tools/metrics/histograms/histograms_xml/power/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/power/histograms.xml
@@ -517,6 +517,24 @@
   </token>
 </histogram>
 
+<histogram name="Power.ForegroundRadio.Wakeups.Cell.30Seconds"
+    enum="RadioSignalLevel" expires_after="2021-07-03">
+  <owner>eseckler@chromium.org</owner>
+  <owner>khokhlov@chromium.org</owner>
+  <owner>skyostil@chromium.org</owner>
+  <summary>
+    Counts the number of radio wakeups while Chrome is the foreground app, the
+    device is on battery power and connection type is cellular. Values are
+    distributed across buckets according to the radio signal quality.
+
+    Caveat: signal quality is measured at the end of 30-sec period, so it might
+    not reflect the quality during the entire period.
+
+    Only supported on Android. Disabled by default. Please supply the
+    ForegroundRadioStateCountWakeups feature flag to turn this metric on.
+  </summary>
+</histogram>
+
 <histogram name="Power.ForegroundRadio.{Direction}KiB.{NetworkType}.30Seconds"
     enum="RadioSignalLevel" expires_after="2021-07-03">
   <owner>eseckler@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/signin/histograms.xml b/tools/metrics/histograms/histograms_xml/signin/histograms.xml
index 58d47d1..deb8e369 100644
--- a/tools/metrics/histograms/histograms_xml/signin/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/signin/histograms.xml
@@ -417,6 +417,17 @@
   </summary>
 </histogram>
 
+<histogram name="Signin.Intercept.SessionStartupReconcileError"
+    enum="BooleanPresent" expires_after="2021-08-12">
+  <owner>alexilin@chromium.org</owner>
+  <owner>droger@chromium.org</owner>
+  <summary>
+    Records whether a reconciliation errors happens while an account is moved to
+    another profile after signin interception, specifically when the cookie is
+    being generated by the account reconcilor.
+  </summary>
+</histogram>
+
 <histogram base="true" name="Signin.InterceptResult"
     enum="SigninInterceptResult" expires_after="2021-08-12">
 <!-- Name completed by histogram_suffixes name="SigninInterceptType" -->
diff --git a/tools/metrics/histograms/histograms_xml/web_core/histograms.xml b/tools/metrics/histograms/histograms_xml/web_core/histograms.xml
index a6bfbde..ad0af26 100644
--- a/tools/metrics/histograms/histograms_xml/web_core/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_core/histograms.xml
@@ -39,8 +39,9 @@
 </histogram>
 
 <histogram name="WebCore.Document.execCommand" enum="MappedEditingCommands"
-    expires_after="2021-04-25">
-  <owner>yoichio@chromium.org</owner>
+    expires_after="2021-12-31">
+  <owner>yosin@chromium.org</owner>
+  <owner>kojii@chromium.org</owner>
   <summary>
     Counts the number of times each document.execCommand is executed. This
     doesn't count commands not supported by Blink.
@@ -48,8 +49,9 @@
 </histogram>
 
 <histogram name="WebCore.Editing.Commands" enum="MappedEditingCommands"
-    expires_after="2020-12-31">
-  <owner>yoichio@chromium.org</owner>
+    expires_after="2021-12-31">
+  <owner>yosin@chromium.org</owner>
+  <owner>kojii@chromium.org</owner>
   <summary>
     Counts the number of times each Editor::Command::execute is called. This
     doesn't count commands not supported by Blink.
diff --git a/tools/perf/contrib/power_mobile/power_mobile.py b/tools/perf/contrib/power_mobile/power_mobile.py
index 9918566..7c24ceb 100644
--- a/tools/perf/contrib/power_mobile/power_mobile.py
+++ b/tools/perf/contrib/power_mobile/power_mobile.py
@@ -27,6 +27,8 @@
   def CreateCoreTimelineBasedMeasurementOptions(self):
     options = timeline_based_measurement.Options()
     options.config.enable_experimental_system_tracing = True
+    options.config.system_trace_config.EnableChrome(
+        chrome_trace_config=options.config.chrome_trace_config)
     options.config.system_trace_config.EnablePower()
     options.config.system_trace_config.EnableFtraceCpu()
     options.config.system_trace_config.EnableFtraceSched()
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc
index 95aa14f..d8e116b 100644
--- a/ui/accessibility/ax_node_position_unittest.cc
+++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -1815,7 +1815,7 @@
   EXPECT_FALSE(text_position->AtEndOfParagraph());
 
   // The end of |inline_box2_| is the end of paragraph since it's
-  // followed by the end of document.
+  // followed by the end of the whole content.
   text_position = AXNodePosition::CreateTextPosition(
       GetTreeID(), inline_box2_.id, 6 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
@@ -2351,7 +2351,7 @@
 }
 
 TEST_F(AXPositionTest,
-       AtStartOrEndOfParagraphWithLeadingAndTrailingDocumentWhitespace) {
+       AtStartOrEndOfParagraphWithLeadingAndTrailingWhitespace) {
   // This test ensures that "At{Start|End}OfParagraph" work correctly when a
   // text position is on a preserved newline character.
   //
@@ -3758,7 +3758,7 @@
   EXPECT_EQ(0, test_position->child_index());
 }
 
-TEST_F(AXPositionTest, CreatePositionAtTextBoundaryDocumentStartEndIsIgnored) {
+TEST_F(AXPositionTest, CreatePositionAtTextBoundaryContentStartEndIsIgnored) {
   // +-root_data
   //   +-static_text_data_1
   //   | +-inline_box_data_1 IGNORED
@@ -4107,8 +4107,8 @@
   EXPECT_EQ(button_.id, test_position->anchor_id());
   EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index());
 
-  // StopAtLastAnchorBoundary should stop at the start of the document while
-  // CrossBoundary should return a null position when crossing it.
+  // StopAtLastAnchorBoundary should stop at the start of the whole content
+  // while CrossBoundary should return a null position when crossing it.
   test_position = test_position->CreatePreviousFormatStartPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4160,8 +4160,8 @@
   EXPECT_EQ(button_.id, test_position->anchor_id());
   EXPECT_EQ(0, test_position->text_offset());
 
-  // StopAtLastAnchorBoundary should stop at the start of the document while
-  // CrossBoundary should return a null position when crossing it.
+  // StopAtLastAnchorBoundary should stop at the start of the whole content
+  // while CrossBoundary should return a null position when crossing it.
   test_position = test_position->CreatePreviousFormatStartPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4230,7 +4230,7 @@
   EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
   EXPECT_EQ(0, test_position->child_index());
 
-  // StopAtLastAnchorBoundary should stop at the end of the document while
+  // StopAtLastAnchorBoundary should stop at the end of the whole content while
   // CrossBoundary should return a null position when crossing it.
   test_position = test_position->CreateNextFormatEndPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
@@ -4288,7 +4288,7 @@
   EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
   EXPECT_EQ(6, test_position->text_offset());
 
-  // StopAtLastAnchorBoundary should stop at the end of the document while
+  // StopAtLastAnchorBoundary should stop at the end of the whole content while
   // CrossBoundary should return a null position when crossing it.
   test_position = test_position->CreateNextFormatEndPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
@@ -4325,7 +4325,7 @@
 
   SetTree(CreateAXTree({root_data, text_data, more_text_data}));
 
-  // Test CreatePreviousFormatStartPosition at the start of the document.
+  // Test CreatePreviousFormatStartPosition at the start of the whole content.
   TestPositionType text_position = AXNodePosition::CreateTextPosition(
       GetTreeID(), text_data.id, 8 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
@@ -4338,7 +4338,7 @@
   EXPECT_EQ(text_data.id, test_position->anchor_id());
   EXPECT_EQ(0, test_position->text_offset());
 
-  // Test CreateNextFormatEndPosition at the end of the document.
+  // Test CreateNextFormatEndPosition at the end of the whole content.
   text_position = AXNodePosition::CreateTextPosition(
       GetTreeID(), more_text_data.id, 0 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
@@ -4626,7 +4626,7 @@
                                   page_2_data, page_2_text_data, page_3_data,
                                   page_3_text_data));
 
-  // Test CreateNextPageStartPosition at the start of the document.
+  // Test CreateNextPageStartPosition at the start of the whole content.
   TestPositionType text_position = AXNodePosition::CreateTextPosition(
       GetTreeID(), page_1_text_data.id, 0 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
@@ -4655,7 +4655,7 @@
   EXPECT_EQ(page_2_text_data.id, test_position->anchor_id());
   EXPECT_EQ(0, test_position->text_offset());
 
-  // Test CreateNextPageEndPosition until the end of document is reached.
+  // Test CreateNextPageEndPosition until the end of content is reached.
   test_position = test_position->CreateNextPageEndPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4677,7 +4677,7 @@
   EXPECT_EQ(page_3_text_data.id, test_position->anchor_id());
   EXPECT_EQ(24, test_position->text_offset());
 
-  // StopAtLastAnchorBoundary shouldn't move past the end of the document.
+  // StopAtLastAnchorBoundary shouldn't move past the end of the whole content.
   test_position = test_position->CreateNextPageStartPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4703,7 +4703,7 @@
   EXPECT_NE(nullptr, null_position);
   EXPECT_TRUE(null_position->IsNullPosition());
 
-  // Now move backward through the document.
+  // Now move backward through the accessibility tree.
   text_position = test_position->CreatePreviousPageEndPosition(
       AXBoundaryBehavior::StopIfAlreadyAtBoundary);
   EXPECT_NE(nullptr, text_position);
@@ -4746,7 +4746,8 @@
   EXPECT_EQ(page_1_text_data.id, test_position->anchor_id());
   EXPECT_EQ(0, test_position->text_offset());
 
-  // StopAtLastAnchorBoundary shouldn't move past the start of the document.
+  // StopAtLastAnchorBoundary shouldn't move past the start of the whole
+  // content.
   test_position = test_position->CreatePreviousPageStartPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4780,7 +4781,7 @@
                                   page_2_data, page_2_text_data, page_3_data,
                                   page_3_text_data));
 
-  // Test CreateNextPageStartPosition at the start of the document.
+  // Test CreateNextPageStartPosition at the start of the whole content.
   TestPositionType tree_position = AXNodePosition::CreateTreePosition(
       GetTreeID(), page_1_data.id, 0 /* child_index */);
   ASSERT_NE(nullptr, tree_position);
@@ -4808,7 +4809,7 @@
   EXPECT_EQ(page_2_text_data.id, test_position->anchor_id());
   EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index());
 
-  // Test CreateNextPageEndPosition until the end of document is reached.
+  // Test CreateNextPageEndPosition until the end of content is reached.
   test_position = tree_position->CreateNextPageEndPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4830,7 +4831,7 @@
   EXPECT_EQ(page_2_text_data.id, test_position->anchor_id());
   EXPECT_EQ(0, test_position->child_index());
 
-  // StopAtLastAnchorBoundary shouldn't move past the end of the document.
+  // StopAtLastAnchorBoundary shouldn't move past the end of the whole content.
   test_position = test_position->CreateNextPageStartPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4856,7 +4857,7 @@
   EXPECT_NE(nullptr, null_position);
   EXPECT_TRUE(null_position->IsNullPosition());
 
-  // Now move backward through the document.
+  // Now move backward through the accessibility tree.
   tree_position = test_position->CreatePreviousPageEndPosition(
       AXBoundaryBehavior::StopIfAlreadyAtBoundary);
   EXPECT_NE(nullptr, tree_position);
@@ -4899,7 +4900,8 @@
   EXPECT_EQ(page_1_text_data.id, test_position->anchor_id());
   EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index());
 
-  // StopAtLastAnchorBoundary shouldn't move past the start of the document.
+  // StopAtLastAnchorBoundary shouldn't move past the start of the whole
+  // content.
   test_position = test_position->CreatePreviousPageStartPosition(
       AXBoundaryBehavior::StopAtLastAnchorBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -4951,11 +4953,11 @@
   EXPECT_TRUE(test_position->IsNullPosition());
 }
 
-TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithNullPosition) {
+TEST_F(AXPositionTest, CreatePositionAtStartOfContentWithNullPosition) {
   TestPositionType null_position = AXNodePosition::CreateNullPosition();
   ASSERT_NE(nullptr, null_position);
   TestPositionType test_position =
-      null_position->CreatePositionAtStartOfDocument();
+      null_position->CreatePositionAtStartOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_TRUE(test_position->IsNullPosition());
 }
@@ -4966,7 +4968,7 @@
       ax::mojom::TextAffinity::kDownstream);
   ASSERT_NE(nullptr, text_position);
 
-  // Non-paginated documents should move to the start of the document for
+  // Non-paginated documents should move to the start of the whole content for
   // CreatePreviousPageStartPosition (treating the entire document as a single
   // page)
   TestPositionType test_position =
@@ -4992,7 +4994,7 @@
   EXPECT_TRUE(test_position->IsNullPosition());
 
   // Since there are no distinct pages, CreateNextPageEndPosition should move
-  // to the end of the document, as if it's one large page.
+  // to the end of the whole content, as if it's one large page.
   test_position = text_position->CreateNextPageEndPosition(
       AXBoundaryBehavior::StopIfAlreadyAtBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -5001,7 +5003,7 @@
   EXPECT_EQ(6, test_position->text_offset());
 
   // CreatePreviousPageStartPosition should move back to the beginning of the
-  // document
+  // whole content.
   test_position = test_position->CreatePreviousPageStartPosition(
       AXBoundaryBehavior::CrossBoundary);
   EXPECT_NE(nullptr, test_position);
@@ -5031,37 +5033,37 @@
   EXPECT_TRUE(test_position->IsNullPosition());
 }
 
-TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithTreePosition) {
+TEST_F(AXPositionTest, CreatePositionAtStartOfContentWithTreePosition) {
   TestPositionType tree_position = AXNodePosition::CreateTreePosition(
       GetTreeID(), root_.id, 0 /* child_index */);
   ASSERT_NE(nullptr, tree_position);
   TestPositionType test_position =
-      tree_position->CreatePositionAtStartOfDocument();
+      tree_position->CreatePositionAtStartOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(root_.id, test_position->anchor_id());
 
   tree_position = AXNodePosition::CreateTreePosition(GetTreeID(), root_.id,
                                                      1 /* child_index */);
   ASSERT_NE(nullptr, tree_position);
-  test_position = tree_position->CreatePositionAtStartOfDocument();
+  test_position = tree_position->CreatePositionAtStartOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(root_.id, test_position->anchor_id());
 
   tree_position = AXNodePosition::CreateTreePosition(
       GetTreeID(), inline_box1_.id, 0 /* child_index */);
   ASSERT_NE(nullptr, tree_position);
-  test_position = tree_position->CreatePositionAtStartOfDocument();
+  test_position = tree_position->CreatePositionAtStartOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(root_.id, test_position->anchor_id());
 }
 
-TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithTextPosition) {
+TEST_F(AXPositionTest, CreatePositionAtStartOfContenttPosition) {
   TestPositionType text_position = AXNodePosition::CreateTextPosition(
       GetTreeID(), inline_box1_.id, 0 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
   ASSERT_NE(nullptr, text_position);
   TestPositionType test_position =
-      text_position->CreatePositionAtStartOfDocument();
+      text_position->CreatePositionAtStartOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(root_.id, test_position->anchor_id());
 
@@ -5069,53 +5071,53 @@
       GetTreeID(), inline_box1_.id, 1 /* text_offset */,
       ax::mojom::TextAffinity::kUpstream);
   ASSERT_NE(nullptr, text_position);
-  test_position = text_position->CreatePositionAtStartOfDocument();
+  test_position = text_position->CreatePositionAtStartOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(root_.id, test_position->anchor_id());
   // Affinity should have been reset to the default value.
   EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
 }
 
-TEST_F(AXPositionTest, CreatePositionAtEndOfDocumentWithNullPosition) {
+TEST_F(AXPositionTest, CreatePositionAtEndOfContentlPosition) {
   TestPositionType null_position = AXNodePosition::CreateNullPosition();
   ASSERT_NE(nullptr, null_position);
   TestPositionType test_position =
-      null_position->CreatePositionAtEndOfDocument();
+      null_position->CreatePositionAtEndOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_TRUE(test_position->IsNullPosition());
 }
 
-TEST_F(AXPositionTest, CreatePositionAtEndOfDocumentWithTreePosition) {
+TEST_F(AXPositionTest, CreatePositionAtEndOfContentePosition) {
   TestPositionType tree_position = AXNodePosition::CreateTreePosition(
       GetTreeID(), root_.id, 3 /* child_index */);
   ASSERT_NE(nullptr, tree_position);
   TestPositionType test_position =
-      tree_position->CreatePositionAtEndOfDocument();
+      tree_position->CreatePositionAtEndOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
 
   tree_position = AXNodePosition::CreateTreePosition(GetTreeID(), root_.id,
                                                      1 /* child_index */);
   ASSERT_NE(nullptr, tree_position);
-  test_position = tree_position->CreatePositionAtEndOfDocument();
+  test_position = tree_position->CreatePositionAtEndOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
 
   tree_position = AXNodePosition::CreateTreePosition(
       GetTreeID(), inline_box1_.id, 0 /* child_index */);
   ASSERT_NE(nullptr, tree_position);
-  test_position = tree_position->CreatePositionAtEndOfDocument();
+  test_position = tree_position->CreatePositionAtEndOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
 }
 
-TEST_F(AXPositionTest, CreatePositionAtEndOfDocumentWithTextPosition) {
+TEST_F(AXPositionTest, CreatePositionAtEndOfContenttPosition) {
   TestPositionType text_position = AXNodePosition::CreateTextPosition(
       GetTreeID(), inline_box1_.id, 6 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
   ASSERT_NE(nullptr, text_position);
   TestPositionType test_position =
-      text_position->CreatePositionAtEndOfDocument();
+      text_position->CreatePositionAtEndOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
 
@@ -5123,7 +5125,7 @@
       GetTreeID(), inline_box1_.id, 5 /* text_offset */,
       ax::mojom::TextAffinity::kUpstream);
   ASSERT_NE(nullptr, text_position);
-  test_position = text_position->CreatePositionAtEndOfDocument();
+  test_position = text_position->CreatePositionAtEndOfContent();
   EXPECT_NE(nullptr, test_position);
   EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
   // Affinity should have been reset to the default value.
@@ -5139,7 +5141,7 @@
   EXPECT_FALSE(text_position->AsTreePosition()->AtLastNodeInTree());
 
   TestPositionType test_position =
-      text_position->CreatePositionAtEndOfDocument();
+      text_position->CreatePositionAtEndOfContent();
   ASSERT_NE(nullptr, test_position);
   EXPECT_TRUE(test_position->AtLastNodeInTree());
   EXPECT_TRUE(test_position->AsTreePosition()->AtLastNodeInTree());
@@ -7108,8 +7110,8 @@
       ax::mojom::TextAffinity::kDownstream);
   ASSERT_NE(nullptr, text_position2);
   ASSERT_TRUE(text_position2->IsTextPosition());
-  // Validate that we're actually at the end of the document by normalizing to
-  // the equivalent "before character" position.
+  // Validate that we're actually at the end of the whole content by normalizing
+  // to the equivalent "before character" position.
   EXPECT_TRUE(
       text_position1->AsLeafTextPositionBeforeCharacter()->IsNullPosition());
   EXPECT_TRUE(
@@ -7291,17 +7293,17 @@
   EXPECT_GT(*text_position1, *text_position2);
   EXPECT_LT(*text_position2, *text_position1);
 
-  // A text position at the end of the document versus one that isn't.
+  // A text position at the end of the whole content versus one that isn't.
   text_position1 = AXNodePosition::CreateTextPosition(
       GetTreeID(), inline_box2_.id, 6 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
   ASSERT_NE(nullptr, text_position1);
   ASSERT_TRUE(text_position1->IsTextPosition());
-  // Validate that we're actually at the end of the document by normalizing to
-  // the equivalent "before character" position.
+  // Validate that we're actually at the end of the whole content by normalizing
+  // to the equivalent "before character" position.
   EXPECT_TRUE(
       text_position1->AsLeafTextPositionBeforeCharacter()->IsNullPosition());
-  // Now create the not-at-end-of-document position and compare.
+  // Now create the not-at-end-of-content position and compare.
   text_position2 = AXNodePosition::CreateTextPosition(
       GetTreeID(), static_text2_.id, 0 /* text_offset */,
       ax::mojom::TextAffinity::kDownstream);
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h
index 209fdcd4..ba0e8ee2 100644
--- a/ui/accessibility/ax_position.h
+++ b/ui/accessibility/ax_position.h
@@ -53,6 +53,7 @@
 };
 
 // Describes in further detail what type of boundary a current position is on.
+//
 // For complex boundaries such as format boundaries, it can be useful to know
 // why a particular boundary was chosen.
 enum class AXBoundaryType {
@@ -60,10 +61,12 @@
   kNone,
   // At a unit boundary (e.g. a format boundary).
   kUnitBoundary,
-  // At the start of a document.
-  kDocumentStart,
-  // At the end of a document.
-  kDocumentEnd
+  // At the start of the whole content, possibly spanning multiple accessibility
+  // trees.
+  kContentStart,
+  // At the end of the whole content, possibly spanning multiple accessibility
+  // trees.
+  kContentEnd
 };
 
 // When converting to an unignored position, determines how to adjust the new
@@ -615,16 +618,16 @@
   // |AtStartOfParagraph| is asymmetric from |AtEndOfParagraph| because of
   // trailing whitespace collapse rules.
   // The start of a paragraph should be a leaf text position (or equivalent),
-  // either at the start of the document, or at the start of the next leaf text
-  // position from the one representing the end of the previous paragraph.
+  // either at the start of the whole content, or at the start of the next leaf
+  // text position from the one representing the end of the previous paragraph.
   // A position |AsLeafTextPosition| is the start of a paragraph if all of the
   // following are true :
   // 1. The current leaf text position must be an unignored position at
   //    the start of an anchor.
   // 2. The current position is not whitespace only, unless it is also
-  //    the first leaf text position within the document.
+  //    the first leaf text position within the whole content.
   // 3. Either (a) the current leaf text position is the first leaf text
-  //    position in the document, or (b) there are no line breaking
+  //    position in the whole content, or (b) there are no line breaking
   //    objects between it and the previous non-whitespace leaf text
   //    position.
   bool AtStartOfParagraph() const {
@@ -642,14 +645,14 @@
           return false;
 
         // 2. The current position is not whitespace only, unless it is also
-        //    the first leaf text position within the document.
+        //    the first leaf text position within the whole content.
         if (text_position->IsInWhiteSpace()) {
           return text_position->CreatePreviousLeafTextPosition()
               ->IsNullPosition();
         }
 
         // 3. Either (a) the current leaf text position is the first leaf text
-        //    position in the document, or (b) there are no line breaking
+        //    position in the whole content, or (b) there are no line breaking
         //    objects between it and the previous non-whitespace leaf text
         //    position.
         //
@@ -658,7 +661,7 @@
         // If a valid position was found, then this position cannot be
         // the start of a paragraph.
         // This will return a null position when an anchor movement would
-        // cross a paragraph boundary, or the start of document was reached.
+        // cross a paragraph boundary, or the start of content was reached.
         bool crossed_line_breaking_object_token = false;
         const AbortMovePredicate abort_move_predicate =
             base::BindRepeating(&AbortMoveAtParagraphBoundary,
@@ -685,14 +688,14 @@
   // |AtEndOfParagraph| is asymmetric from |AtStartOfParagraph| because of
   // trailing whitespace collapse rules.
   // The end of a paragraph should be a leaf text position (or equivalent),
-  // either at the end of the document, or at the end of the previous leaf text
-  // position from the one representing the start of the next paragraph.
-  // A position |AsLeafTextPosition| is the end of a paragraph if all of the
+  // either at the end of the whole content, or at the end of the previous leaf
+  // text position from the one representing the start of the next paragraph. A
+  // position |AsLeafTextPosition| is the end of a paragraph if all of the
   // following are true :
   // 1. The current leaf text position must be an unignored position at
   //    the end of an anchor.
   // 2. Either (a) the current leaf text position is the last leaf text
-  //    position in the document, or (b) there are no line breaking
+  //    position in the whole content, or (b) there are no line breaking
   //    objects between it and the next leaf text position except when
   //    the next leaf text position is whitespace only since whitespace
   //    must be collapsed.
@@ -716,7 +719,7 @@
           return false;
 
         // 2. Either (a) the current leaf text position is the last leaf text
-        //    position in the document, or (b) there are no line breaking
+        //    position in the whole content, or (b) there are no line breaking
         //    objects between it and the next leaf text position except when
         //    the next leaf text position is whitespace only since whitespace
         //    must be collapsed.
@@ -728,7 +731,7 @@
         // |CreateNextTextAnchorPosition| + |AbortMoveAtParagraphBoundary|
         // will return a null position when an anchor movement would
         // cross a paragraph boundary and there is no doubt that it is the end
-        // of a paragraph, or the end of document was reached.
+        // of a paragraph, or the end of content was reached.
         // There are some fringe cases related to whitespace collapse that
         // cannot be handled easily with only |AbortMoveAtParagraphBoundary|.
         bool crossed_line_breaking_object_token = false;
@@ -769,6 +772,8 @@
     }
   }
 
+  // Page boundaries are only supported in certain content types, e.g. PDF
+  // documents.
   bool AtStartOfPage() const {
     AXPositionInstance text_position = AsLeafTextPosition();
     switch (text_position->kind_) {
@@ -786,7 +791,7 @@
         // If a valid position was found, then this position cannot be
         // the start of a page.
         // This will return a null position when an anchor movement would
-        // cross a page boundary, or the start of document was reached.
+        // cross a page boundary, or the start of content was reached.
         AXPositionInstance previous_text_position =
             text_position->CreatePreviousTextAnchorPosition(
                 base::BindRepeating(&AbortMoveAtPageBoundary));
@@ -795,6 +800,8 @@
     }
   }
 
+  // Page boundaries are only supported in certain content types, e.g. PDF
+  // documents.
   bool AtEndOfPage() const {
     AXPositionInstance text_position = AsLeafTextPosition();
     switch (text_position->kind_) {
@@ -812,7 +819,7 @@
         // If a valid position was found, then this position cannot be
         // the end of a page.
         // This will return a null position when an anchor movement would
-        // cross a page boundary, or the end of document was reached.
+        // cross a page boundary, or the end of content was reached.
         AXPositionInstance next_text_position =
             text_position->CreateNextTextAnchorPosition(
                 base::BindRepeating(&AbortMoveAtPageBoundary));
@@ -821,24 +828,24 @@
     }
   }
 
+  // Returns true if this position is at the start of the current accessibility
+  // tree, as indicated by its |tree_id_|. Note that the current webpage could
+  // be made up of multiple accessibility trees stitched together, e.g. an
+  // out-of-process iframe will be in its own accessibility tree.
   bool AtStartOfAXTree() const {
-    if (IsNullPosition())
+    if (IsNullPosition() || !AtStartOfAnchor())
       return false;
 
-    if (AtStartOfAnchor()) {
-      AXPositionInstance previous_anchor = CreatePreviousAnchorPosition();
+    AXPositionInstance previous_anchor = CreatePreviousAnchorPosition();
+    // The start of the whole content should also be the start of an AXTree.
+    if (previous_anchor->IsNullPosition())
+      return true;
 
-      // Consider the start of the document as the start of an AXTree.
-      if (previous_anchor->IsNullPosition())
-        return true;
-      else
-        return previous_anchor->tree_id() != tree_id();
-    }
-    return false;
+    return previous_anchor->tree_id() != tree_id();
   }
 
   // Returns true if this position is at the end of the current accessibility
-  // tree, as indicated by its |tree_id_|. Note that the current document could
+  // tree, as indicated by its |tree_id_|. Note that the current webpage could
   // be made up of multiple accessibility trees stitched together, e.g. an
   // out-of-process iframe will be in its own accessibility tree.
   bool AtEndOfAXTree() const {
@@ -846,8 +853,7 @@
       return false;
 
     AXPositionInstance next_anchor = CreateNextAnchorPosition();
-    // Consider the end of the document to also signify the end of the current
-    // accessibility tree.
+    // The end of the whole content should also be the end of an AXTree.
     if (next_anchor->IsNullPosition())
       return true;
 
@@ -862,7 +868,7 @@
 
     // Treat the first iterable node as a format boundary.
     if (CreatePreviousLeafTreePosition()->IsNullPosition())
-      return AXBoundaryType::kDocumentStart;
+      return AXBoundaryType::kContentStart;
 
     // Ignored positions cannot be format boundaries.
     if (IsIgnored())
@@ -895,7 +901,7 @@
 
     // Treat the last iterable node as a format boundary
     if (CreateNextLeafTreePosition()->IsNullPosition())
-      return AXBoundaryType::kDocumentEnd;
+      return AXBoundaryType::kContentEnd;
 
     // Ignored positions cannot be format boundaries.
     if (IsIgnored())
@@ -964,19 +970,26 @@
     }
   }
 
-  bool AtStartOfDocument() const {
+  // Returns true if this position is at the start of all content. This might
+  // refer to e.g. a single webpage (made up of multiple iframes), or a PDF
+  // document. Note that the current webpage could be made up of multiple
+  // accessibility trees stitched together, so even though a position could be
+  // at the start of a specific accessibility tree, it might not be at the start
+  // of the whole content.
+  bool AtStartOfContent() const {
     if (IsNullPosition())
       return false;
-    return IsDocument(GetAnchorRole()) && AtStartOfAnchor();
+    return GetAnchorRole() == ax::mojom::Role::kRootWebArea &&
+           AtStartOfAnchor();
   }
 
-  // Returns true if this position is at the end of the current document. A
-  // document represents a single webpage (made up of multiple iframes), or a
-  // PDF, for example. Note that the current document could be made up of
-  // multiple accessibility trees stitched together, so even though a position
-  // could be at the end of a specific accessibility tree, it might not be at
-  // the end of the whole document yet.
-  bool AtEndOfDocument() const {
+  // Returns true if this position is at the end of all content. This might
+  // refer to e.g. a single webpage (made up of multiple iframes), or a PDF
+  // document. Note that the current webpage could be made up of multiple
+  // accessibility trees stitched together, so even though a position could be
+  // at the end of a specific accessibility tree, it might not be at the end of
+  // the whole content.
+  bool AtEndOfContent() const {
     if (IsNullPosition())
       return false;
     return AtLastNodeInTree() && AtEndOfAnchor();
@@ -988,7 +1001,8 @@
 
     // Avoid a potentionally expensive MaxTextOffset call by only using tree
     // positions. The only thing that matters is whether our anchor_id_ is at
-    // the last anchor of the document, so we're free to ignore text_offset_.
+    // the last anchor of the whole content, so we're free to ignore
+    // |text_offset_|.
     AXPositionInstance tree_position =
         CreateTreePosition(tree_id_, anchor_id_, 0);
     return tree_position->CreateNextAnchorPosition()->IsNullPosition();
@@ -1667,17 +1681,17 @@
 
       case ax::mojom::TextBoundary::kWebPage:
         DCHECK_EQ(boundary_behavior, AXBoundaryBehavior::CrossBoundary)
-            << "We can't reach the start of the document if we are disallowed "
-               "from crossing boundaries.";
+            << "We can't reach the start of the whole contents if we are "
+               "disallowed from crossing boundaries.";
         switch (direction) {
           case ax::mojom::MoveDirection::kNone:
             NOTREACHED();
             break;
           case ax::mojom::MoveDirection::kBackward:
-            resulting_position = CreatePositionAtStartOfDocument();
+            resulting_position = CreatePositionAtStartOfContent();
             break;
           case ax::mojom::MoveDirection::kForward:
-            resulting_position = CreatePositionAtEndOfDocument();
+            resulting_position = CreatePositionAtEndOfContent();
             break;
         }
         break;
@@ -1808,19 +1822,15 @@
     return next_position->CreatePositionAtEndOfAnchor();
   }
 
-  // "document" is defined here as a single, top-level, navigatable unit from
-  //  a user's perspective. This means that all iframes are part of a single
-  // "document" that contains the top-level navigatable page. So this method
-  // will break out of an iframe and return a position at the start of the
-  // top-level document.
+  // Creates a position at the start of all content, e.g. at the start of the
+  // whole webpage or PDF document.
   //
-  // Note that this definition is different than HTML's definition of
-  // "document", where each iframe has its own document object. For a similar
-  // method that stops at iframe boundaries, see
-  // CreatePositionAtStartOfAXTree().
-  AXPositionInstance CreatePositionAtStartOfDocument() const {
+  // Note that this method will break out of an iframe and return a position at
+  // the start of the top-level document. For a similar method that stops at
+  // iframe boundaries, see "CreatePositionAtStartOfAXTree()".
+  AXPositionInstance CreatePositionAtStartOfContent() const {
     AXPositionInstance position =
-        AsTreePosition()->CreateDocumentAncestorPosition();
+        AsTreePosition()->CreateRootWebAreaAncestorPosition();
     if (!position->IsNullPosition()) {
       position = position->CreatePositionAtStartOfAnchor();
       if (IsTextPosition())
@@ -1829,18 +1839,15 @@
     return position;
   }
 
-  // "document" is defined here as a single, top-level, navigatable unit from
-  //  a user's perspective. This means that all iframes are part of a single
-  // "document" that contains the top-level navigatable page. So this method
-  // will break out of an iframe and return a position at the end of the
-  // top-level document.
+  // Creates a position at the end of all content, e.g. at the end of the whole
+  // webpage or PDF document.
   //
-  // Note that this definition is different than HTML's definition of
-  // "document", where each iframe has its own document object. For a similar
-  // method that stops at iframe boundaries, see CreatePositionAtEndOfAXTree().
-  AXPositionInstance CreatePositionAtEndOfDocument() const {
+  // Note that this method will break out of an iframe and return a position at
+  // the end of the top-level document. For a similar method that stops at
+  // iframe boundaries, see "CreatePositionAtEndOfAXTree()".
+  AXPositionInstance CreatePositionAtEndOfContent() const {
     AXPositionInstance position =
-        AsTreePosition()->CreateDocumentAncestorPosition();
+        AsTreePosition()->CreateRootWebAreaAncestorPosition();
     if (!position->IsNullPosition()) {
       while (!position->IsLeaf()) {
         position =
@@ -2466,7 +2473,7 @@
     if (boundary_type != AXBoundaryType::kNone) {
       if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary ||
           (boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary &&
-           boundary_type == AXBoundaryType::kDocumentStart)) {
+           boundary_type == AXBoundaryType::kContentStart)) {
         AXPositionInstance clone = Clone();
         // In order to make equality checks simpler, affinity should be reset so
         // that we would get consistent output from this function regardless of
@@ -2474,7 +2481,7 @@
         clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
         return clone;
       } else if (boundary_behavior == AXBoundaryBehavior::CrossBoundary &&
-                 boundary_type == AXBoundaryType::kDocumentStart) {
+                 boundary_type == AXBoundaryType::kContentStart) {
         // If we're at a format boundary and there are no more text positions
         // to traverse, return a null position for cross-boundary moves.
         return CreateNullPosition();
@@ -2495,9 +2502,10 @@
       previous_tree_position = tree_position->CreatePreviousLeafTreePosition();
     }
 
-    // The first position in the document is also a format start boundary, so we
-    // should not return NullPosition unless we started from that location.
-    while (boundary_type != AXBoundaryType::kDocumentStart &&
+    // The first position in the whole content is also a format start boundary,
+    // so we should not return NullPosition unless we started from that
+    // location.
+    while (boundary_type != AXBoundaryType::kContentStart &&
            !previous_tree_position->IsNullPosition() &&
            !tree_position->AtStartOfFormat()) {
       tree_position = std::move(previous_tree_position);
@@ -2530,7 +2538,7 @@
     if (boundary_type != AXBoundaryType::kNone) {
       if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary ||
           (boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary &&
-           boundary_type == AXBoundaryType::kDocumentEnd)) {
+           boundary_type == AXBoundaryType::kContentEnd)) {
         AXPositionInstance clone = Clone();
         // In order to make equality checks simpler, affinity should be reset so
         // that we would get consistent output from this function regardless of
@@ -2538,7 +2546,7 @@
         clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
         return clone;
       } else if (boundary_behavior == AXBoundaryBehavior::CrossBoundary &&
-                 boundary_type == AXBoundaryType::kDocumentEnd) {
+                 boundary_type == AXBoundaryType::kContentEnd) {
         // If we're at a format boundary and there are no more text positions
         // to traverse, return a null position for cross-boundary moves.
         return CreateNullPosition();
@@ -2560,9 +2568,9 @@
                                ->CreatePositionAtEndOfAnchor();
     }
 
-    // The last position in the document is also a format end boundary, so we
-    // should not return NullPosition unless we started from that location.
-    while (boundary_type != AXBoundaryType::kDocumentEnd &&
+    // The last position in the whole content is also a format end boundary, so
+    // we should not return NullPosition unless we started from that location.
+    while (boundary_type != AXBoundaryType::kContentEnd &&
            !next_tree_position->IsNullPosition() &&
            !tree_position->AtEndOfFormat()) {
       tree_position = std::move(next_tree_position);
@@ -2830,9 +2838,9 @@
         AdjustmentBehaviorFromBoundaryDirection(move_direction));
     // If there are no unignored positions in |move_direction| then
     // |text_position| is anchored in ignored content at the start or end
-    // of the document.
+    // of the whole content.
     // For StopAtLastAnchorBoundary, try to adjust in the opposite direction
-    // to return a position within the document just before crossing into
+    // to return a position within the whole content just before crossing into
     // the ignored content. This will be the last unignored anchor boundary.
     if (unignored_position->IsNullPosition() &&
         boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary) {
@@ -2982,9 +2990,9 @@
         AdjustmentBehaviorFromBoundaryDirection(move_direction));
     // If there are no unignored positions in |move_direction| then
     // |text_position| is anchored in ignored content at the start or end
-    // of the document.
+    // of the whole content.
     // For StopAtLastAnchorBoundary, try to adjust in the opposite direction
-    // to return a position within the document just before crossing into
+    // to return a position within the whole content just before crossing into
     // the ignored content. This will be the last unignored anchor boundary.
     if (unignored_position->IsNullPosition() &&
         boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary) {
@@ -3070,16 +3078,17 @@
 
     if (normalized_this_position->IsNullPosition()) {
       if (normalized_other_position->IsNullPosition()) {
-        // Both positions normalized to a position past the end of the document.
+        // Both positions normalized to a position past the end of the whole
+        // content.
         DCHECK_EQ(SlowCompareTo(other).value(), 0);
         return 0;
       }
-      // |this| normalized to a position past the end of the document.
+      // |this| normalized to a position past the end of the whole content.
       DCHECK_GT(SlowCompareTo(other).value(), 0);
       return 1;
     }
     if (normalized_other_position->IsNullPosition()) {
-      // |other| normalized to a position past the end of the document.
+      // |other| normalized to a position past the end of the whole content.
       DCHECK_LT(SlowCompareTo(other).value(), 0);
       return -1;
     }
@@ -3436,7 +3445,7 @@
       return false;
     }
 
-    // All unignored leaf nodes in the AXTree except document and text
+    // All unignored leaf nodes in the AXTree except web area and text
     // nodes should be replaced by the embedded object character. Also, nodes
     // that only have ignored children (e.g., a button that contains only an
     // empty div) need to be treated as leaf nodes.
@@ -3445,7 +3454,7 @@
     // infinite loop. However, GetAnchor()->IsIgnored() is sufficient here
     // because we know that the anchor at this position doesn't have an
     // unignored child, making this a leaf tree or text position.
-    return !GetAnchor()->IsIgnored() && !IsDocument(GetAnchorRole()) &&
+    return !GetAnchor()->IsIgnored() && !IsPlatformDocument(GetAnchorRole()) &&
            !IsInTextObject() && !IsIframe(GetAnchorRole());
   }
 
@@ -4048,6 +4057,9 @@
   }
 
   // AbortMovePredicate function used to detect page boundaries.
+  //
+  // Depending on the type of content, it might be separated into a number of
+  // pages. For example, a PDF document may expose multiple pages.
   static bool AbortMoveAtPageBoundary(const AXPosition& move_from,
                                       const AXPosition& move_to,
                                       const AXMoveType move_type,
@@ -4144,10 +4156,10 @@
     return position->GetWordEndOffsets();
   }
 
-  AXPositionInstance CreateDocumentAncestorPosition() const {
+  AXPositionInstance CreateRootWebAreaAncestorPosition() const {
     AXPositionInstance iterator = Clone();
     while (!iterator->IsNullPosition()) {
-      if (IsDocument(iterator->GetAnchorRole()) &&
+      if (iterator->GetAnchorRole() == ax::mojom::Role::kRootWebArea &&
           iterator->CreateParentPosition()->IsNullPosition()) {
         break;
       }
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc
index 8a4c27c..76fd98c6 100644
--- a/ui/accessibility/ax_role_properties.cc
+++ b/ui/accessibility/ax_role_properties.cc
@@ -204,17 +204,6 @@
   }
 }
 
-bool IsDocument(const ax::mojom::Role role) {
-  switch (role) {
-    case ax::mojom::Role::kDocument:
-    case ax::mojom::Role::kRootWebArea:
-    case ax::mojom::Role::kWebArea:
-      return true;
-    default:
-      return false;
-  }
-}
-
 bool IsDialog(const ax::mojom::Role role) {
   switch (role) {
     case ax::mojom::Role::kAlertDialog:
@@ -393,6 +382,19 @@
   }
 }
 
+bool IsPlatformDocument(const ax::mojom::Role role) {
+  // "ax::mojom::Role::kDocument" is excluded because it refers to nodes with
+  // the ARIA document role. These are not at the root of an HTML document. They
+  // can appear anywhere within an HTML document, but never at its root.
+  switch (role) {
+    case ax::mojom::Role::kRootWebArea:
+    case ax::mojom::Role::kWebArea:
+      return true;
+    default:
+      return false;
+  }
+}
+
 bool IsPresentational(const ax::mojom::Role role) {
   switch (role) {
     case ax::mojom::Role::kNone:
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h
index c4207f55..a5a88e1 100644
--- a/ui/accessibility/ax_role_properties.h
+++ b/ui/accessibility/ax_role_properties.h
@@ -57,9 +57,6 @@
 AX_BASE_EXPORT bool IsControlOnAndroid(const ax::mojom::Role role,
                                        bool isFocusable);
 
-// Returns true if the provided role belongs to a document.
-AX_BASE_EXPORT bool IsDocument(const ax::mojom::Role role);
-
 // Returns true if the provided role represents a dialog.
 AX_BASE_EXPORT bool IsDialog(const ax::mojom::Role role);
 
@@ -108,6 +105,11 @@
 // Returns true if the provided role belongs to a menu or related control.
 AX_BASE_EXPORT bool IsMenuRelated(const ax::mojom::Role role);
 
+// Returns true if the provided role belongs to a node that is at the root of
+// what most accessibility APIs consider to be a document, such as the root of a
+// webpage, an iframe, or a PDF.
+AX_BASE_EXPORT bool IsPlatformDocument(const ax::mojom::Role role);
+
 // Returns true if the provided role is presentational in nature, i.e. a node
 // whose implicit native role semantics will not be mapped to the accessibility
 // API.
diff --git a/ui/accessibility/extensions/chromevoxclassic/BUILD.gn b/ui/accessibility/extensions/chromevoxclassic/BUILD.gn
index dfecb666..e2f5a1e 100644
--- a/ui/accessibility/extensions/chromevoxclassic/BUILD.gn
+++ b/ui/accessibility/extensions/chromevoxclassic/BUILD.gn
@@ -522,6 +522,7 @@
     "//base",
     "//base:i18n",
     "//base/test:test_support",
+    "//build:chromeos_buildflags",
     "//chrome:browser_tests_pak",
     "//chrome:packed_resources",
     "//chrome:resources",
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index ec590e2..540a135 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -2380,7 +2380,7 @@
   if (data.IsRangeValueSupported())
     interface_mask.Add(ImplementedAtkInterfaces::Value::kValue);
 
-  if (ui::IsDocument(data.role))
+  if (ui::IsPlatformDocument(data.role))
     interface_mask.Add(ImplementedAtkInterfaces::Value::kDocument);
 
   if (IsImage(data.role))
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc
index 6270e75c..c2ea10b 100644
--- a/ui/accessibility/platform/ax_platform_node_base.cc
+++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -161,6 +161,14 @@
   if (!parent)
     return base::nullopt;
 
+  // If this is the webview, it is not in the child in the list of its parent's
+  // child.
+  // TODO(jkim): Check if we could remove this after making WebView ignored.
+  if (delegate_ &&
+      delegate_->GetNativeViewAccessible() != GetNativeViewAccessible()) {
+    return base::nullopt;
+  }
+
   int child_count = parent->GetChildCount();
   if (child_count == 0) {
     // |child_count| could be 0 if the parent is IsLeaf.
@@ -591,8 +599,8 @@
   return delegate_->SetHypertextSelection(start_offset, end_offset);
 }
 
-bool AXPlatformNodeBase::IsDocument() const {
-  return ui::IsDocument(GetData().role);
+bool AXPlatformNodeBase::IsPlatformDocument() const {
+  return ui::IsPlatformDocument(GetData().role);
 }
 
 bool AXPlatformNodeBase::IsSelectionItemSupported() const {
diff --git a/ui/accessibility/platform/ax_platform_node_base.h b/ui/accessibility/platform/ax_platform_node_base.h
index 5ccdfa6..fb8650d 100644
--- a/ui/accessibility/platform/ax_platform_node_base.h
+++ b/ui/accessibility/platform/ax_platform_node_base.h
@@ -372,7 +372,10 @@
   // Uses the delegate to calculate this node's SetSize.
   base::Optional<int> GetSetSize() const;
 
-  bool IsDocument() const;
+  // Returns true if this object is at the root of what most accessibility APIs
+  // consider to be a document, such as the root of a webpage, an iframe, or a
+  // PDF.
+  bool IsPlatformDocument() const;
 
  protected:
   bool IsSelectionItemSupported() const;
diff --git a/ui/accessibility/platform/ax_platform_node_textprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textprovider_win.cc
index f5ecd97..b5177168 100644
--- a/ui/accessibility/platform/ax_platform_node_textprovider_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_textprovider_win.cc
@@ -300,9 +300,9 @@
       descendant->GetDelegate()->CreateTextPositionAt(0)->AsLeafTextPosition();
 
   AXNodePosition::AXPositionInstance end;
-  if (descendant->IsDocument()) {
+  if (descendant->IsPlatformDocument()) {
     // Fast path for getting the range of the web root.
-    end = start->CreatePositionAtEndOfDocument();
+    end = start->CreatePositionAtEndOfContent();
   } else if (descendant->GetChildCount() == 0) {
     end = descendant->GetDelegate()
               ->CreateTextPositionAt(0)
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
index 1291087..2bcbb22a 100644
--- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -242,7 +242,7 @@
       // no word boundaries, like whitespaces and punctuation. When it happens,
       // move the position back to the start of the document.
       if (start()->IsNullPosition())
-        SetStart(start_backup->CreatePositionAtStartOfDocument());
+        SetStart(start_backup->CreatePositionAtStartOfContent());
 
       // Since start_ is already located at a word boundary, we need to cross it
       // in order to move to the next one. Because Windows ATs behave
@@ -284,9 +284,8 @@
     }
       FALLTHROUGH;
     case TextUnit_Document:
-      SetStart(
-          start()->CreatePositionAtStartOfDocument()->AsLeafTextPosition());
-      SetEnd(start()->CreatePositionAtEndOfDocument());
+      SetStart(start()->CreatePositionAtStartOfContent()->AsLeafTextPosition());
+      SetEnd(start()->CreatePositionAtEndOfContent());
       break;
     default:
       return UIA_E_NOTSUPPORTED;
@@ -681,7 +680,7 @@
     SetEnd(start()->Clone());
     if (!is_degenerate_range) {
       bool forwards = count > 0;
-      if (forwards && start()->AtEndOfDocument()) {
+      if (forwards && start()->AtEndOfContent()) {
         // The start is at the end of the document, so move the start backward
         // by one text unit to expand the text range from the degenerate range
         // state.
@@ -1174,11 +1173,11 @@
   DCHECK_NE(count, 0);
 
   if (count < 0) {
-    *units_moved = !endpoint->AtStartOfDocument() ? -1 : 0;
-    return endpoint->CreatePositionAtStartOfDocument();
+    *units_moved = !endpoint->AtStartOfContent() ? -1 : 0;
+    return endpoint->CreatePositionAtStartOfContent();
   }
-  *units_moved = !endpoint->AtEndOfDocument() ? 1 : 0;
-  return endpoint->CreatePositionAtEndOfDocument();
+  *units_moved = !endpoint->AtEndOfContent() ? 1 : 0;
+  return endpoint->CreatePositionAtEndOfContent();
 }
 
 AXPlatformNodeTextRangeProviderWin::AXPositionInstance
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
index 1606e1e..82ece35f 100644
--- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -1932,7 +1932,8 @@
                   /*expected_count*/ -2);
 }
 
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMovePage) {
+TEST_F(AXPlatformNodeTextRangeProviderTest,
+       DISABLED_TestITextRangeProviderMovePage) {
   Init(BuildAXTreeForMoveByPage());
   AXNode* root_node = GetRootAsAXNode();
 
@@ -3449,7 +3450,8 @@
   EXPECT_EQ(*GetEnd(text_range.Get()), *GetEnd(more_text_range.Get()));
 }
 
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderGetChildren) {
+TEST_F(AXPlatformNodeTextRangeProviderTest,
+       DISABLED_TestITextRangeProviderGetChildren) {
   // Set up ax tree with the following structure:
   //
   // ++1 kRootWebArea
@@ -5161,7 +5163,7 @@
 }
 
 TEST_F(AXPlatformNodeTextRangeProviderTest,
-       TestITextRangeProviderIgnoredNodes) {
+       DISABLED_TestITextRangeProviderIgnoredNodes) {
   // Parent Tree
   // 1
   // |
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 654cbbb8..e8f8cda 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -7585,7 +7585,7 @@
 
 // static
 BSTR AXPlatformNodeWin::GetValueAttributeAsBstr(AXPlatformNodeWin* target) {
-  if (target->IsDocument()) {
+  if (target->IsPlatformDocument()) {
     base::string16 url =
         base::UTF8ToUTF16(target->GetDelegate()->GetTreeData().url);
     BSTR value = SysAllocString(url.c_str());
@@ -7916,9 +7916,8 @@
 
     case UIA_TextEditPatternId:
     case UIA_TextPatternId:
-      if (IsDocument() || IsTextField() || IsText()) {
+      if (IsPlatformDocument() || IsTextField() || IsText())
         return &AXPlatformNodeTextProviderWin::CreateIUnknown;
-      }
       break;
 
     case UIA_TogglePatternId:
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn
index e2735b3..af99fdd 100644
--- a/weblayer/BUILD.gn
+++ b/weblayer/BUILD.gn
@@ -257,6 +257,8 @@
     "browser/ssl_error_controller_client.h",
     "browser/stateful_ssl_host_state_delegate_factory.cc",
     "browser/stateful_ssl_host_state_delegate_factory.h",
+    "browser/subresource_filter_client_impl.cc",
+    "browser/subresource_filter_client_impl.h",
     "browser/system_network_context_manager.cc",
     "browser/system_network_context_manager.h",
     "browser/tab_impl.cc",
@@ -414,6 +416,7 @@
     "//components/safe_browsing/content/renderer:throttles",
     "//components/safe_browsing/content/renderer/phishing_classifier",
     "//components/safe_browsing/core:features",
+    "//components/safe_browsing/core/db:database_manager",
     "//components/security_interstitials/content:security_interstitial_page",
     "//components/security_interstitials/content/renderer:security_interstitial_page_controller",
     "//components/security_interstitials/core",
@@ -427,7 +430,10 @@
     "//components/startup_metric_utils/browser",
     "//components/strings",
     "//components/subresource_filter/content/browser",
+    "//components/subresource_filter/content/renderer",
     "//components/subresource_filter/core/browser",
+    "//components/subresource_filter/core/browser",
+    "//components/subresource_filter/core/common",
     "//components/translate/content/browser",
     "//components/translate/content/renderer",
     "//components/translate/core/browser",
diff --git a/weblayer/browser/DEPS b/weblayer/browser/DEPS
index aa6cb6c6..3e1706b7 100644
--- a/weblayer/browser/DEPS
+++ b/weblayer/browser/DEPS
@@ -44,6 +44,7 @@
   "+components/no_state_prefetch/browser",
   "+components/no_state_prefetch/common",
   "+components/resources/android",
+  "+components/safe_browsing/android",
   "+components/safe_browsing/core",
   "+components/safe_browsing/core/common",
   "+components/safe_browsing/core/features.h",
@@ -60,6 +61,8 @@
   "+components/strings",
   "+components/subresource_filter/content/browser",
   "+components/subresource_filter/core/browser",
+  "+components/subresource_filter/core/common",
+  "+components/subresource_filter/core/mojom",
   "+components/translate/content/android",
   "+components/translate/content/browser",
   "+components/translate/core/browser",
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/SiteSettingsTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/SiteSettingsTest.java
index b6849c73..6b40abc 100644
--- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/SiteSettingsTest.java
+++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/SiteSettingsTest.java
@@ -79,6 +79,7 @@
     @Test
     @SmallTest
     @MinWebLayerVersion(84)
+    @DisabledTest(message = "TODO(crbug.com/1150676): Fix flakiness.")
     public void testSingleSiteSoundPopupLaunches() throws InterruptedException {
         mSiteSettingsTestRule.launchSingleSiteSettingsWithProfile(PROFILE_NAME, GOOGLE_URL);
 
@@ -90,6 +91,7 @@
     @Test
     @SmallTest
     @MinWebLayerVersion(84)
+    @DisabledTest(message = "TODO(crbug.com/1150676): Fix flakiness.")
     public void testSingleSiteClearPopupLaunches() throws InterruptedException {
         mSiteSettingsTestRule.launchSingleSiteSettingsWithProfile(PROFILE_NAME, GOOGLE_URL);
 
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc
index 136f363..88b6164 100644
--- a/weblayer/browser/content_browser_client_impl.cc
+++ b/weblayer/browser/content_browser_client_impl.cc
@@ -39,6 +39,7 @@
 #include "components/site_isolation/preloaded_isolated_origins.h"
 #include "components/site_isolation/site_isolation_policy.h"
 #include "components/strings/grit/components_locale_settings.h"
+#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
 #include "components/subresource_filter/content/browser/ruleset_version.h"
 #include "components/user_prefs/user_prefs.h"
 #include "components/variations/service/variations_service.h"
@@ -706,6 +707,12 @@
     throttles.push_back(std::move(insecure_form_throttle));
   }
 
+  if (auto* throttle_manager =
+          subresource_filter::ContentSubresourceFilterThrottleManager::
+              FromWebContents(handle->GetWebContents())) {
+    throttle_manager->MaybeAppendNavigationThrottles(handle, &throttles);
+  }
+
 #if defined(OS_ANDROID)
   if (handle->IsInMainFrame()) {
     if (base::FeatureList::IsEnabled(features::kWebLayerSafeBrowsing) &&
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java
index fdf5a8e..5119c15 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java
@@ -14,7 +14,7 @@
 import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.components.external_intents.ExternalNavigationDelegate;
 import org.chromium.components.external_intents.ExternalNavigationDelegate.StartActivityIfNeededResult;
-import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
+import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType;
 import org.chromium.components.external_intents.ExternalNavigationParams;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
@@ -89,10 +89,10 @@
 
     // This method should never be invoked as WebLayer does not handle incoming intents.
     @Override
-    public @OverrideUrlLoadingResult int handleIncognitoIntentTargetingSelf(
+    public @OverrideUrlLoadingResultType int handleIncognitoIntentTargetingSelf(
             final Intent intent, final String referrerUrl, final String fallbackUrl) {
         assert false;
-        return OverrideUrlLoadingResult.NO_OVERRIDE;
+        return OverrideUrlLoadingResultType.NO_OVERRIDE;
     }
 
     @Override
diff --git a/weblayer/browser/subresource_filter_browsertest.cc b/weblayer/browser/subresource_filter_browsertest.cc
index b894881..6b05c9b 100644
--- a/weblayer/browser/subresource_filter_browsertest.cc
+++ b/weblayer/browser/subresource_filter_browsertest.cc
@@ -3,15 +3,42 @@
 // found in the LICENSE file.
 
 #include "base/json/json_reader.h"
+#include "build/build_config.h"
+#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
+#include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h"
 #include "components/subresource_filter/content/browser/ruleset_service.h"
+#include "components/subresource_filter/content/browser/subresource_filter_observer_test_utils.h"
+#include "components/subresource_filter/content/browser/test_ruleset_publisher.h"
+#include "components/subresource_filter/core/browser/subresource_filter_constants.h"
+#include "components/subresource_filter/core/common/test_ruleset_creator.h"
+#include "content/public/test/browser_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "weblayer/browser/browser_process.h"
+#include "weblayer/browser/subresource_filter_client_impl.h"
+#include "weblayer/browser/tab_impl.h"
 #include "weblayer/grit/weblayer_resources.h"
+#include "weblayer/shell/browser/shell.h"
 #include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
 
 namespace weblayer {
 
+namespace {
+
+// Returns whether a script resource that sets document.scriptExecuted to true
+// on load was loaded.
+bool WasParsedScriptElementLoaded(content::RenderFrameHost* rfh) {
+  DCHECK(rfh);
+  bool script_resource_was_loaded = false;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      rfh, "domAutomationController.send(!!document.scriptExecuted)",
+      &script_resource_was_loaded));
+  return script_resource_was_loaded;
+}
+
+}  // namespace
+
 class SubresourceFilterBrowserTest : public WebLayerBrowserTest {
  public:
   SubresourceFilterBrowserTest() = default;
@@ -19,6 +46,23 @@
   SubresourceFilterBrowserTest(const SubresourceFilterBrowserTest&) = delete;
   SubresourceFilterBrowserTest& operator=(const SubresourceFilterBrowserTest&) =
       delete;
+
+  void SetUpOnMainThread() override {
+    ASSERT_TRUE(embedded_test_server()->Start());
+  }
+
+ protected:
+  void SetRulesetToDisallowURLsWithPathSuffix(const std::string& suffix) {
+    subresource_filter::testing::TestRulesetPair test_ruleset_pair;
+    subresource_filter::testing::TestRulesetCreator test_ruleset_creator;
+    test_ruleset_creator.CreateRulesetToDisallowURLsWithPathSuffix(
+        suffix, &test_ruleset_pair);
+
+    subresource_filter::testing::TestRulesetPublisher test_ruleset_publisher(
+        BrowserProcess::GetInstance()->subresource_filter_ruleset_service());
+    ASSERT_NO_FATAL_FAILURE(
+        test_ruleset_publisher.SetRuleset(test_ruleset_pair.unindexed));
+  }
 };
 
 // Tests that the ruleset service is available.
@@ -59,4 +103,153 @@
   EXPECT_EQ(most_recently_indexed_content_version, *packaged_content_version);
 }
 
+// The below test is restricted to Android as it tests activation of the
+// subresource filter in its default production configuration and WebLayer
+// currently has a safe browsing database available in production only on
+// Android; the safe browsing database being non-null is a prerequisite for
+// subresource filter operation.
+#if defined(OS_ANDROID)
+
+// Tests that page activation state is computed as part of a pageload.
+IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest,
+                       PageActivationStateComputed) {
+  // Set up prereqs.
+  auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
+
+  content::WebContentsConsoleObserver console_observer(web_contents);
+  console_observer.SetPattern(subresource_filter::kActivationConsoleMessage);
+
+  GURL test_url(embedded_test_server()->GetURL("/simple_page.html"));
+
+  subresource_filter::TestSubresourceFilterObserver observer(web_contents);
+  base::Optional<subresource_filter::mojom::ActivationLevel> page_activation =
+      observer.GetPageActivation(test_url);
+  EXPECT_FALSE(page_activation);
+
+  // Verify that a navigation results in both (a) the page activation level
+  // being computed, and (b) the result of that computation being the default
+  // level of "dry run" due to AdTagging.
+  NavigateAndWaitForCompletion(test_url, shell());
+
+  page_activation = observer.GetPageActivation(test_url);
+
+  EXPECT_TRUE(page_activation);
+  EXPECT_EQ(subresource_filter::mojom::ActivationLevel::kDryRun,
+            page_activation.value());
+
+  EXPECT_TRUE(console_observer.messages().empty());
+}
+
+#endif  // (OS_ANDROID)
+
+// Verifies that subframes that are flagged by the subresource filter ruleset
+// are blocked from loading on activated URLs.
+// Flaky on Windows. See https://crbug.com/1152429
+#if defined(OS_WIN)
+#define MAYBE_DisallowedSubframeURLBlockedOnActivatedURL \
+  DISABLED_DisallowedSubframeURLBlockedOnActivatedURL
+#else
+#define MAYBE_DisallowedSubframeURLBlockedOnActivatedURL \
+  DisallowedSubframeURLBlockedOnActivatedURL
+#endif
+IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest,
+                       MAYBE_DisallowedSubframeURLBlockedOnActivatedURL) {
+  auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
+
+  content::WebContentsConsoleObserver console_observer(web_contents);
+  console_observer.SetPattern(subresource_filter::kActivationConsoleMessage);
+
+  GURL test_url(
+      embedded_test_server()->GetURL("/frame_with_included_script.html"));
+
+  subresource_filter::TestSubresourceFilterObserver observer(web_contents);
+  base::Optional<subresource_filter::mojom::ActivationLevel> page_activation =
+      observer.GetPageActivation(test_url);
+  EXPECT_FALSE(page_activation);
+
+  // Configure the database manager to activate on this URL.
+  scoped_refptr<FakeSafeBrowsingDatabaseManager> database_manager =
+      base::MakeRefCounted<FakeSafeBrowsingDatabaseManager>();
+  database_manager->AddBlocklistedUrl(
+      test_url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING);
+  auto* client_impl = static_cast<SubresourceFilterClientImpl*>(
+      subresource_filter::ContentSubresourceFilterThrottleManager::
+          FromWebContents(web_contents)
+              ->client());
+  client_impl->set_database_manager_for_testing(database_manager);
+
+  // Verify that the "ad" subframe is loaded if it is not flagged by the
+  // ruleset.
+  ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix(
+      "suffix-that-does-not-match-anything"));
+
+  NavigateAndWaitForCompletion(test_url, shell());
+
+  // The subresource filter should have been activated on this navigation...
+  page_activation = observer.GetPageActivation(test_url);
+  EXPECT_TRUE(page_activation);
+  EXPECT_EQ(subresource_filter::mojom::ActivationLevel::kEnabled,
+            page_activation.value());
+  EXPECT_FALSE(console_observer.messages().empty());
+
+  // ... but it should not have blocked the subframe from being loaded.
+  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+
+  // Do a different-document navigation to ensure that that the next navigation
+  // to |test_url| executes as desired (e.g., to avoid any optimizations from
+  // being made due to it being a same-document navigation that would interfere
+  // with the logic of the test). Without this intervening navigation, we have
+  // seen flake on the Windows trybot that indicates that such optimizations are
+  // occurring.
+  NavigateAndWaitForCompletion(GURL("about:blank"), shell());
+  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+
+  // Verify that the "ad" subframe is blocked if it is flagged by the
+  // ruleset.
+  ASSERT_NO_FATAL_FAILURE(
+      SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
+
+  NavigateAndWaitForCompletion(test_url, shell());
+  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+
+  // Do a different-document navigation to ensure that that the next navigation
+  // to |test_url| executes as desired (e.g., to avoid any optimizations from
+  // being made due to it being a same-document navigation that would interfere
+  // with the logic of the test). Without this intervening navigation, we have
+  // seen flake on the Windows trybot that indicates that such optimizations are
+  // occurring.
+  NavigateAndWaitForCompletion(GURL("about:blank"), shell());
+  EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+
+  // The main frame document should never be filtered.
+  SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html");
+  NavigateAndWaitForCompletion(test_url, shell());
+  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+}
+
+// Verifies that subframes are not blocked on non-activated URLs.
+IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest,
+                       DisallowedSubframeURLNotBlockedOnNonActivatedURL) {
+  auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
+
+  GURL test_url(
+      embedded_test_server()->GetURL("/frame_with_included_script.html"));
+
+  // Verify that the "ad" subframe is loaded if it is not flagged by the
+  // ruleset.
+  ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix(
+      "suffix-that-does-not-match-anything"));
+
+  NavigateAndWaitForCompletion(test_url, shell());
+  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+
+  // Verify that the "ad" subframe is loaded if even it is flagged by the
+  // ruleset as the URL is not activated.
+  ASSERT_NO_FATAL_FAILURE(
+      SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
+
+  NavigateAndWaitForCompletion(test_url, shell());
+  EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame()));
+}
+
 }  // namespace weblayer
diff --git a/weblayer/browser/subresource_filter_client_impl.cc b/weblayer/browser/subresource_filter_client_impl.cc
new file mode 100644
index 0000000..511e0922
--- /dev/null
+++ b/weblayer/browser/subresource_filter_client_impl.cc
@@ -0,0 +1,96 @@
+// 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 "weblayer/browser/subresource_filter_client_impl.h"
+
+#include <string>
+#include <utility>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
+#include "components/subresource_filter/content/browser/ruleset_service.h"
+#include "components/subresource_filter/core/browser/subresource_filter_features.h"
+#include "components/subresource_filter/core/common/activation_decision.h"
+#include "components/subresource_filter/core/common/activation_scope.h"
+#include "components/subresource_filter/core/mojom/subresource_filter.mojom.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/render_frame_host.h"
+#include "weblayer/browser/browser_process.h"
+#include "weblayer/browser/safe_browsing/safe_browsing_service.h"
+
+#if defined(OS_ANDROID)
+#include "components/safe_browsing/android/remote_database_manager.h"
+#endif
+
+namespace weblayer {
+
+namespace {
+
+// Returns a scoped refptr to the SafeBrowsingService's database manager, if
+// available. Otherwise returns nullptr.
+const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+GetDatabaseManagerFromSafeBrowsingService() {
+#if defined(OS_ANDROID)
+  SafeBrowsingService* safe_browsing_service =
+      BrowserProcess::GetInstance()->GetSafeBrowsingService();
+  return safe_browsing_service
+             ? scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>(
+                   safe_browsing_service->GetSafeBrowsingDBManager())
+             : nullptr;
+#else
+  return nullptr;
+#endif
+}
+
+}  // namespace
+
+SubresourceFilterClientImpl::SubresourceFilterClientImpl()
+    : database_manager_(GetDatabaseManagerFromSafeBrowsingService()) {}
+
+SubresourceFilterClientImpl::~SubresourceFilterClientImpl() = default;
+
+// static
+void SubresourceFilterClientImpl::CreateThrottleManagerWithClientForWebContents(
+    content::WebContents* web_contents) {
+  subresource_filter::RulesetService* ruleset_service =
+      BrowserProcess::GetInstance()->subresource_filter_ruleset_service();
+  subresource_filter::VerifiedRulesetDealer::Handle* dealer =
+      ruleset_service ? ruleset_service->GetRulesetDealer() : nullptr;
+  subresource_filter::ContentSubresourceFilterThrottleManager::
+      CreateForWebContents(web_contents,
+                           std::make_unique<SubresourceFilterClientImpl>(),
+                           dealer);
+}
+
+void SubresourceFilterClientImpl::OnReloadRequested() {
+  // TODO(crbug.com/1116095): Bring up this flow on Android when user requests
+  // it via the infobar.
+  NOTREACHED();
+}
+
+void SubresourceFilterClientImpl::ShowNotification() {
+  // TODO(crbug.com/1116095): Show infobar on Android.
+}
+
+subresource_filter::mojom::ActivationLevel
+SubresourceFilterClientImpl::OnPageActivationComputed(
+    content::NavigationHandle* navigation_handle,
+    subresource_filter::mojom::ActivationLevel initial_activation_level,
+    subresource_filter::ActivationDecision* decision) {
+  DCHECK(navigation_handle->IsInMainFrame());
+
+  return initial_activation_level;
+}
+
+void SubresourceFilterClientImpl::OnAdsViolationTriggered(
+    content::RenderFrameHost* rfh,
+    subresource_filter::mojom::AdsViolation triggered_violation) {}
+
+const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+SubresourceFilterClientImpl::GetSafeBrowsingDatabaseManager() {
+  return database_manager_;
+}
+
+}  // namespace weblayer
diff --git a/weblayer/browser/subresource_filter_client_impl.h b/weblayer/browser/subresource_filter_client_impl.h
new file mode 100644
index 0000000..894ea6a4
--- /dev/null
+++ b/weblayer/browser/subresource_filter_client_impl.h
@@ -0,0 +1,70 @@
+// 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 WEBLAYER_BROWSER_SUBRESOURCE_FILTER_CLIENT_IMPL_H_
+#define WEBLAYER_BROWSER_SUBRESOURCE_FILTER_CLIENT_IMPL_H_
+
+#include <memory>
+
+#include "components/safe_browsing/core/db/database_manager.h"
+#include "components/subresource_filter/content/browser/subresource_filter_client.h"
+#include "url/gurl.h"
+
+namespace content {
+class WebContents;
+}  // namespace content
+
+namespace subresource_filter {
+class ContentSubresourceFilterThrottleManager;
+}  // namespace subresource_filter
+
+namespace weblayer {
+
+// WebLayer implementation of SubresourceFilterClient. Instances are associated
+// with and owned by ContentSubresourceFilterThrottleManager instances.
+class SubresourceFilterClientImpl
+    : public subresource_filter::SubresourceFilterClient {
+ public:
+  SubresourceFilterClientImpl();
+  ~SubresourceFilterClientImpl() override;
+
+  SubresourceFilterClientImpl(const SubresourceFilterClientImpl&) = delete;
+  SubresourceFilterClientImpl& operator=(const SubresourceFilterClientImpl&) =
+      delete;
+
+  // Creates a ContentSubresourceFilterThrottleManager and attaches it to
+  // |web_contents|, passing it an instance of this client and other
+  // embedder-level state.
+  static void CreateThrottleManagerWithClientForWebContents(
+      content::WebContents* web_contents);
+
+  // SubresourceFilterClient:
+  void ShowNotification() override;
+  subresource_filter::mojom::ActivationLevel OnPageActivationComputed(
+      content::NavigationHandle* navigation_handle,
+      subresource_filter::mojom::ActivationLevel initial_activation_level,
+      subresource_filter::ActivationDecision* decision) override;
+  void OnAdsViolationTriggered(
+      content::RenderFrameHost* rfh,
+      subresource_filter::mojom::AdsViolation triggered_violation) override;
+  const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+  GetSafeBrowsingDatabaseManager() override;
+  void OnReloadRequested() override;
+
+  // Sets the SafeBrowsingDatabaseManager instance used to |database_manager|.
+  void set_database_manager_for_testing(
+      scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+          database_manager) {
+    database_manager_ = database_manager;
+  }
+
+ private:
+  std::unique_ptr<subresource_filter::ContentSubresourceFilterThrottleManager>
+      throttle_manager_;
+  scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
+};
+
+}  // namespace weblayer
+
+#endif  // WEBLAYER_BROWSER_SUBRESOURCE_FILTER_CLIENT_IMPL_H_
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc
index de0400e..0bafc3d 100644
--- a/weblayer/browser/tab_impl.cc
+++ b/weblayer/browser/tab_impl.cc
@@ -74,6 +74,7 @@
 #include "weblayer/browser/persistence/browser_persister.h"
 #include "weblayer/browser/popup_navigation_delegate_impl.h"
 #include "weblayer/browser/profile_impl.h"
+#include "weblayer/browser/subresource_filter_client_impl.h"
 #include "weblayer/browser/translate_client_impl.h"
 #include "weblayer/browser/user_agent.h"
 #include "weblayer/browser/weblayer_features.h"
@@ -305,6 +306,9 @@
 
   TranslateClientImpl::CreateForWebContents(web_contents_.get());
 
+  SubresourceFilterClientImpl::CreateThrottleManagerWithClientForWebContents(
+      web_contents_.get());
+
   sessions::SessionTabHelper::CreateForWebContents(
       web_contents_.get(),
       base::BindRepeating(&TabImpl::GetSessionServiceTabHelperDelegate));
diff --git a/weblayer/renderer/DEPS b/weblayer/renderer/DEPS
index bbe17ada..e4bdf723 100644
--- a/weblayer/renderer/DEPS
+++ b/weblayer/renderer/DEPS
@@ -15,6 +15,8 @@
   "+components/security_interstitials/content/renderer",
   "+components/security_interstitials/core/common",
   "+components/spellcheck/renderer",
+  "+components/subresource_filter/content/renderer",
+  "+components/subresource_filter/core/common",
   "+components/translate/content/renderer",
   "+components/translate/core/common",
   "+content/public/common",
diff --git a/weblayer/renderer/content_renderer_client_impl.cc b/weblayer/renderer/content_renderer_client_impl.cc
index f6bbf0e..90cbd198 100644
--- a/weblayer/renderer/content_renderer_client_impl.cc
+++ b/weblayer/renderer/content_renderer_client_impl.cc
@@ -19,6 +19,9 @@
 #include "components/no_state_prefetch/renderer/prerender_utils.h"
 #include "components/no_state_prefetch/renderer/prerenderer_client.h"
 #include "components/page_load_metrics/renderer/metrics_render_frame_observer.h"
+#include "components/subresource_filter/content/renderer/subresource_filter_agent.h"
+#include "components/subresource_filter/content/renderer/unverified_ruleset_dealer.h"
+#include "components/subresource_filter/core/common/common_features.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
@@ -85,6 +88,10 @@
 
   browser_interface_broker_ =
       blink::Platform::Current()->GetBrowserInterfaceBroker();
+
+  subresource_filter_ruleset_dealer_ =
+      std::make_unique<subresource_filter::UnverifiedRulesetDealer>();
+  thread->AddObserver(subresource_filter_ruleset_dealer_.get());
 }
 
 void ContentRendererClientImpl::RenderFrameCreated(
@@ -108,6 +115,11 @@
 
   new page_load_metrics::MetricsRenderFrameObserver(render_frame);
 
+  // TODO(crbug.com/1116095): Bring up AdResourceTracker?
+  new subresource_filter::SubresourceFilterAgent(
+      render_frame, subresource_filter_ruleset_dealer_.get(),
+      /*ad_resource_tracker=*/nullptr);
+
 #if defined(OS_ANDROID)
   // |SpellCheckProvider| manages its own lifetime (and destroys itself when the
   // RenderFrame is destroyed).
diff --git a/weblayer/renderer/content_renderer_client_impl.h b/weblayer/renderer/content_renderer_client_impl.h
index db74185..bec5c28 100644
--- a/weblayer/renderer/content_renderer_client_impl.h
+++ b/weblayer/renderer/content_renderer_client_impl.h
@@ -16,6 +16,10 @@
 class LocalInterfaceProvider;
 }  // namespace service_manager
 
+namespace subresource_filter {
+class UnverifiedRulesetDealer;
+}
+
 namespace weblayer {
 class WebLayerRenderThreadObserver;
 
@@ -54,6 +58,9 @@
   std::unique_ptr<SpellCheck> spellcheck_;
 #endif
 
+  std::unique_ptr<subresource_filter::UnverifiedRulesetDealer>
+      subresource_filter_ruleset_dealer_;
+
   std::unique_ptr<WebLayerRenderThreadObserver> weblayer_observer_;
 
   scoped_refptr<blink::ThreadSafeBrowserInterfaceBrokerProxy>
diff --git a/weblayer/test/BUILD.gn b/weblayer/test/BUILD.gn
index a0bc636..68bea7a 100644
--- a/weblayer/test/BUILD.gn
+++ b/weblayer/test/BUILD.gn
@@ -112,6 +112,9 @@
     "//components/site_isolation",
     "//components/strings",
     "//components/subresource_filter/content/browser",
+    "//components/subresource_filter/content/browser:test_support",
+    "//components/subresource_filter/core/browser",
+    "//components/subresource_filter/core/common:test_support",
     "//components/translate/content/browser",
     "//components/translate/content/browser:test_support",
     "//components/ukm:test_support",
diff --git a/weblayer/test/data/frame_with_included_script.html b/weblayer/test/data/frame_with_included_script.html
new file mode 100644
index 0000000..a55b28c
--- /dev/null
+++ b/weblayer/test/data/frame_with_included_script.html
@@ -0,0 +1,5 @@
+<html>
+  <head>
+    <script src="included_script.js"></script>
+  </head>
+</html>
diff --git a/third_party/blink/renderer/core/dom/set_inner_html_options.idl b/weblayer/test/data/included_script.js
similarity index 68%
rename from third_party/blink/renderer/core/dom/set_inner_html_options.idl
rename to weblayer/test/data/included_script.js
index 6e6d596..96c7c5e 100644
--- a/third_party/blink/renderer/core/dom/set_inner_html_options.idl
+++ b/weblayer/test/data/included_script.js
@@ -2,6 +2,4 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-dictionary SetInnerHTMLOptions {
-  boolean includeShadowRoots = false;
-};
+document.scriptExecuted = true;