diff --git a/DEPS b/DEPS
index 2307441..f9b6d42 100644
--- a/DEPS
+++ b/DEPS
@@ -199,7 +199,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': '05e5446145a6c104e156b4a6c78940fb19db4b62',
+  'skia_revision': '1bb49a8700888547637835aabf2f9475000aef28',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -211,7 +211,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': 'ff170c6f508d45a48e573dcbf2a3001200dde61b',
+  'angle_revision': 'bd2954a9c499381ddaf10bd5ca3d93dd7b0b9bed',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -266,7 +266,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'f46e9e72306f00405741ac4abd146cf904aabe3e',
+  'catapult_revision': 'cf567b6b961687e00cdc2ded7bcb4fc72379fa59',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -274,7 +274,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'ff5c7857d90c41e20f2823396e4fb70c447bdb30',
+  'devtools_frontend_revision': 'a9f40de95873c3da991d36cc064e4ddaa5b59c79',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -553,7 +553,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '738a505dacefbb2371b5e0ae04989192eaa56370',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '8da92053bd494128be6f659dd04c24f95ffa8b74',
       'condition': 'checkout_ios',
   },
 
@@ -1508,7 +1508,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3c2fe3888658d82b47ca831d59a2e07579619c2d',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '7acc2d9fe3a6e3c4d8881d2bdfc9b8968a724cd5',
+    Var('webrtc_git') + '/src.git' + '@' + '12971a22d265c7ba1c3c388f5d487580939a1162',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1599,7 +1599,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'xO6b6gm3QxUDRY3PGCD_ON0uPe2bjwP9ftauSv0ar3cC',
+        'version': 'alcm_LiO62roi1ezYRwFxRVtvZggBQWdZ5rfXIxetisC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc
index 45b97610..da60e04 100644
--- a/ash/app_list/views/app_list_folder_view.cc
+++ b/ash/app_list/views/app_list_folder_view.cc
@@ -41,6 +41,7 @@
 #include "ui/views/animation/animation_delegate_views.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/painter.h"
 #include "ui/views/view_model.h"
 #include "ui/views/view_model_utils.h"
@@ -569,10 +570,6 @@
   return false;
 }
 
-const char* AppListFolderView::GetClassName() const {
-  return "AppListFolderView";
-}
-
 void AppListFolderView::OnAppListItemWillBeDeleted(AppListItem* item) {
   if (item == folder_item_) {
     items_grid_view_->OnFolderItemRemoved();
@@ -898,4 +895,7 @@
   announcement_view->NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
 }
 
+BEGIN_METADATA(AppListFolderView, views::View)
+END_METADATA
+
 }  // namespace ash
diff --git a/ash/app_list/views/app_list_folder_view.h b/ash/app_list/views/app_list_folder_view.h
index 18971e3..96c02ce 100644
--- a/ash/app_list/views/app_list_folder_view.h
+++ b/ash/app_list/views/app_list_folder_view.h
@@ -13,10 +13,10 @@
 #include "ash/app_list/views/apps_grid_view_folder_delegate.h"
 #include "ash/app_list/views/folder_header_view.h"
 #include "ash/app_list/views/folder_header_view_delegate.h"
-#include "base/macros.h"
 #include "base/optional.h"
 #include "ui/compositor/throughput_tracker.h"
 #include "ui/views/controls/button/button.h"
+#include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/view.h"
 #include "ui/views/view_model.h"
 
@@ -35,9 +35,13 @@
                                           public AppListModelObserver,
                                           public AppsGridViewFolderDelegate {
  public:
+  METADATA_HEADER(AppListFolderView);
+
   AppListFolderView(AppsContainerView* container_view,
                     AppListModel* model,
                     ContentsView* contents_view);
+  AppListFolderView(const AppListFolderView&) = delete;
+  AppListFolderView& operator=(const AppListFolderView&) = delete;
   ~AppListFolderView() override;
 
   // An interface for the folder opening and closing animations.
@@ -69,7 +73,6 @@
   gfx::Size CalculatePreferredSize() const override;
   void Layout() override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
-  const char* GetClassName() const override;
 
   // AppListModelObserver
   void OnAppListItemWillBeDeleted(AppListItem* item) override;
@@ -193,8 +196,6 @@
 
   // Records smoothness of the folder show/hide animation.
   base::Optional<ui::ThroughputTracker> show_hide_metrics_tracker_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppListFolderView);
 };
 
 }  // namespace ash
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc
index 4b08f5d..d793517003 100644
--- a/ash/app_list/views/app_list_item_view.cc
+++ b/ash/app_list/views/app_list_item_view.cc
@@ -49,6 +49,7 @@
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/drag_controller.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 
 namespace ash {
 
@@ -281,9 +282,6 @@
   DISALLOW_COPY_AND_ASSIGN(IconImageView);
 };
 
-// static
-const char AppListItemView::kViewClassName[] = "ui/app_list/AppListItemView";
-
 AppListItemView::AppListItemView(AppsGridView* apps_grid_view,
                                  AppListItem* item,
                                  AppListViewDelegate* delegate,
@@ -735,10 +733,6 @@
   return true;
 }
 
-const char* AppListItemView::GetClassName() const {
-  return kViewClassName;
-}
-
 void AppListItemView::Layout() {
   gfx::Rect rect(GetContentsBounds());
   if (rect.IsEmpty())
@@ -1131,4 +1125,7 @@
   bounds->Inset(gfx::Insets(kFocusRingWidth / 2));
 }
 
+BEGIN_METADATA(AppListItemView, views::Button)
+END_METADATA
+
 }  // namespace ash
diff --git a/ash/app_list/views/app_list_item_view.h b/ash/app_list/views/app_list_item_view.h
index 0a37b2f..542e02b 100644
--- a/ash/app_list/views/app_list_item_view.h
+++ b/ash/app_list/views/app_list_item_view.h
@@ -12,7 +12,6 @@
 
 #include "ash/app_list/app_list_export.h"
 #include "ash/app_list/model/app_list_item_observer.h"
-#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/string16.h"
 #include "base/timer/timer.h"
@@ -41,13 +40,14 @@
                                         public AppListItemObserver,
                                         public ui::ImplicitAnimationObserver {
  public:
-  // Internal class name.
-  static const char kViewClassName[];
+  METADATA_HEADER(AppListItemView);
 
   AppListItemView(AppsGridView* apps_grid_view,
                   AppListItem* item,
                   AppListViewDelegate* delegate,
                   bool is_in_folder);
+  AppListItemView(const AppListItemView&) = delete;
+  AppListItemView& operator=(const AppListItemView&) = delete;
   ~AppListItemView() override;
 
   // Sets the icon of this image.
@@ -214,7 +214,6 @@
   void PaintButtonContents(gfx::Canvas* canvas) override;
 
   // views::View overrides:
-  const char* GetClassName() const override;
   void Layout() override;
   gfx::Size CalculatePreferredSize() const override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
@@ -312,8 +311,6 @@
   const bool is_notification_indicator_enabled_;
 
   base::WeakPtrFactory<AppListItemView> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(AppListItemView);
 };
 
 }  // namespace ash
diff --git a/ash/frame/non_client_frame_view_ash.cc b/ash/frame/non_client_frame_view_ash.cc
index 4bacc34..a10bed7 100644
--- a/ash/frame/non_client_frame_view_ash.cc
+++ b/ash/frame/non_client_frame_view_ash.cc
@@ -32,6 +32,7 @@
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image_skia.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/view.h"
 #include "ui/views/view_targeter.h"
 #include "ui/views/widget/widget.h"
@@ -71,6 +72,10 @@
     custom_frame_view->InitImmersiveFullscreenControllerForView(
         immersive_fullscreen_controller_.get());
   }
+  NonClientFrameViewAshImmersiveHelper(
+      const NonClientFrameViewAshImmersiveHelper&) = delete;
+  NonClientFrameViewAshImmersiveHelper& operator=(
+      const NonClientFrameViewAshImmersiveHelper&) = delete;
 
   ~NonClientFrameViewAshImmersiveHelper() override {
     if (Shell::Get()->tablet_mode_controller())
@@ -143,8 +148,6 @@
   WindowState* window_state_;
   std::unique_ptr<ImmersiveFullscreenController>
       immersive_fullscreen_controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(NonClientFrameViewAshImmersiveHelper);
 };
 
 // View which takes up the entire widget and contains the HeaderView. HeaderView
@@ -154,6 +157,8 @@
                                            public views::ViewTargeterDelegate {
  public:
   explicit OverlayView(HeaderView* header_view);
+  OverlayView(const OverlayView&) = delete;
+  OverlayView& operator=(const OverlayView&) = delete;
   ~OverlayView() override;
 
   // views::View:
@@ -166,8 +171,6 @@
                          const gfx::Rect& rect) const override;
 
   HeaderView* header_view_;
-
-  DISALLOW_COPY_AND_ASSIGN(OverlayView);
 };
 
 NonClientFrameViewAsh::OverlayView::OverlayView(HeaderView* header_view)
@@ -205,9 +208,6 @@
   return header_view_->HitTestRect(rect);
 }
 
-// static
-const char NonClientFrameViewAsh::kViewClassName[] = "NonClientFrameViewAsh";
-
 NonClientFrameViewAsh::NonClientFrameViewAsh(views::Widget* frame)
     : frame_(frame),
       header_view_(new HeaderView(frame, this)),
@@ -331,10 +331,6 @@
                             NonClientTopBorderHeight());
 }
 
-const char* NonClientFrameViewAsh::GetClassName() const {
-  return kViewClassName;
-}
-
 gfx::Size NonClientFrameViewAsh::GetMinimumSize() const {
   if (!GetEnabled())
     return gfx::Size();
@@ -425,4 +421,7 @@
   frame_->non_client_view()->Layout();
 }
 
+BEGIN_METADATA(NonClientFrameViewAsh, views::NonClientFrameView)
+END_METADATA
+
 }  // namespace ash
diff --git a/ash/frame/non_client_frame_view_ash.h b/ash/frame/non_client_frame_view_ash.h
index 069c104..ac2633a 100644
--- a/ash/frame/non_client_frame_view_ash.h
+++ b/ash/frame/non_client_frame_view_ash.h
@@ -14,6 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/non_client_view.h"
 
@@ -38,14 +39,15 @@
 // BrowserNonClientFrameViewAsh.
 class ASH_EXPORT NonClientFrameViewAsh : public views::NonClientFrameView {
  public:
-  // Internal class name.
-  static const char kViewClassName[];
+  METADATA_HEADER(NonClientFrameViewAsh);
 
   // |control_immersive| controls whether ImmersiveFullscreenController is
   // created for the NonClientFrameViewAsh; if true and a WindowStateDelegate
   // has not been set on the WindowState associated with |frame|, then an
   // ImmersiveFullscreenController is created.
   explicit NonClientFrameViewAsh(views::Widget* frame);
+  NonClientFrameViewAsh(const NonClientFrameViewAsh&) = delete;
+  NonClientFrameViewAsh& operator=(const NonClientFrameViewAsh&) = delete;
   ~NonClientFrameViewAsh() override;
 
   static NonClientFrameViewAsh* Get(aura::Window* window);
@@ -86,7 +88,6 @@
   // views::View:
   gfx::Size CalculatePreferredSize() const override;
   void Layout() override;
-  const char* GetClassName() const override;
   gfx::Size GetMinimumSize() const override;
   gfx::Size GetMaximumSize() const override;
   void SetVisible(bool visible) override;
@@ -148,8 +149,6 @@
                               base::Unretained(this)));
 
   base::WeakPtrFactory<NonClientFrameViewAsh> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(NonClientFrameViewAsh);
 };
 
 }  // namespace ash
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index 04e7b42..9535bf7 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -1223,20 +1223,26 @@
   EXPECT_EQ(0, slot_span->num_allocated_slots);
 
   size_t very_small_size = (kExtraAllocSize <= 32) ? (32 - kExtraAllocSize) : 0;
-  bucket_index = SizeToIndex(very_small_size + kExtraAllocSize);
+  size_t very_small_size_raw_size = very_small_size;
+#if ENABLE_REF_COUNT_FOR_BACKUP_REF_PTR
+  // Zero-sized allocations are adjusted to a size of 1.
+  if (very_small_size == 0)
+    very_small_size_raw_size = 1;
+#endif
+  bucket_index = SizeToIndex(very_small_size_raw_size + kExtraAllocSize);
   bucket = &allocator.root()->buckets[bucket_index];
   EXPECT_EQ(nullptr, bucket->empty_slot_spans_head);
 
-  ptr = allocator.root()->Alloc(very_small_size, type_name);
+  ptr = allocator.root()->Alloc(very_small_size_raw_size, type_name);
   EXPECT_TRUE(ptr);
   slot_span = SlotSpan::FromPointer(
       allocator.root()->AdjustPointerForExtrasSubtract(ptr));
   EXPECT_EQ(1, slot_span->num_allocated_slots);
   total_slots =
       (slot_span->bucket->num_system_pages_per_slot_span * SystemPageSize()) /
-      (very_small_size + kExtraAllocSize);
+      (very_small_size_raw_size + kExtraAllocSize);
   first_slot_span_slots =
-      SystemPageSize() / (very_small_size + kExtraAllocSize);
+      SystemPageSize() / (very_small_size_raw_size + kExtraAllocSize);
   EXPECT_EQ(total_slots - first_slot_span_slots,
             slot_span->num_unprovisioned_slots);
 
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 165ec37..a76f83f 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -291,9 +291,9 @@
 // Compare the lower-case form of the given string against the given
 // previously-lower-cased ASCII string (typically a constant).
 BASE_EXPORT bool LowerCaseEqualsASCII(StringPiece str,
-                                      StringPiece lowecase_ascii);
+                                      StringPiece lowercase_ascii);
 BASE_EXPORT bool LowerCaseEqualsASCII(StringPiece16 str,
-                                      StringPiece lowecase_ascii);
+                                      StringPiece lowercase_ascii);
 
 // Performs a case-sensitive string compare of the given 16-bit string against
 // the given 8-bit ASCII string (typically a constant). The behavior is
diff --git a/base/strings/string_util_win.h b/base/strings/string_util_win.h
index 53aa0b73..8e86917 100644
--- a/base/strings/string_util_win.h
+++ b/base/strings/string_util_win.h
@@ -167,7 +167,7 @@
 BASE_EXPORT bool ContainsOnlyChars(WStringPiece input, WStringPiece characters);
 
 BASE_EXPORT bool LowerCaseEqualsASCII(WStringPiece str,
-                                      StringPiece lowecase_ascii);
+                                      StringPiece lowercase_ascii);
 
 BASE_EXPORT bool EqualsASCII(StringPiece16 str, StringPiece ascii);
 
diff --git a/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.cc b/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.cc
index 4ab7424..8a6f5c2e 100644
--- a/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.cc
+++ b/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.cc
@@ -65,10 +65,17 @@
     case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
       // By convention no notifications are sent when returning to NONE level.
       SendCurrentVote(false);
+      send_current_vote_timer_.Stop();
       break;
     case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
     case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
       SendCurrentVote(true);
+      // This will reset the timer if already running.
+      send_current_vote_timer_.Start(
+          FROM_HERE, base::MemoryPressureMonitor::kUMAMemoryPressureLevelPeriod,
+          base::BindRepeating(
+              &SystemMemoryPressureEvaluatorFuchsia::SendCurrentVote,
+              base::Unretained(this), true));
       break;
   }
 
diff --git a/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.h b/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.h
index 84c3dcec..4ff35697 100644
--- a/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.h
+++ b/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia.h
@@ -9,17 +9,23 @@
 #include <lib/fidl/cpp/binding.h>
 
 #include "base/sequence_checker.h"
+#include "base/timer/timer.h"
 #include "base/util/memory_pressure/system_memory_pressure_evaluator.h"
 
 namespace util {
 class MemoryPressureVoter;
 
 // Registers with the fuchsia.memorypressure.Provider to be notified of changes
-// to the system memory pressure level.
+// to the system memory pressure level. Votes are sent immediately when
+// memory pressure becomes MODERATE or CRITICAL, and periodically until
+// memory pressure drops back down to NONE. No notifications are sent at NONE
+// level.
 class SystemMemoryPressureEvaluatorFuchsia
     : public SystemMemoryPressureEvaluator,
       public fuchsia::memorypressure::Watcher {
  public:
+  using SystemMemoryPressureEvaluator::SendCurrentVote;
+
   explicit SystemMemoryPressureEvaluatorFuchsia(
       std::unique_ptr<util::MemoryPressureVoter> voter);
 
@@ -37,6 +43,8 @@
 
   fidl::Binding<fuchsia::memorypressure::Watcher> binding_;
 
+  base::RepeatingTimer send_current_vote_timer_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 };
 
diff --git a/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia_unittest.cc b/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia_unittest.cc
index 3cd3aae6..3a3b47d7 100644
--- a/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia_unittest.cc
+++ b/base/util/memory_pressure/system_memory_pressure_evaluator_fuchsia_unittest.cc
@@ -11,17 +11,35 @@
 #include "base/fuchsia/test_component_context_for_process.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
+#include "base/util/memory_pressure/multi_source_memory_pressure_monitor.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace util {
 
 namespace {
+
 class MockMemoryPressureVoter : public MemoryPressureVoter {
  public:
   MOCK_METHOD2(SetVote,
                void(base::MemoryPressureListener::MemoryPressureLevel, bool));
 };
+
+class TestSystemMemoryPressureEvaluator
+    : public SystemMemoryPressureEvaluatorFuchsia {
+ public:
+  TestSystemMemoryPressureEvaluator(std::unique_ptr<MemoryPressureVoter> voter)
+      : SystemMemoryPressureEvaluatorFuchsia(std::move(voter)) {}
+
+  TestSystemMemoryPressureEvaluator(const TestSystemMemoryPressureEvaluator&) =
+      delete;
+  TestSystemMemoryPressureEvaluator& operator=(
+      const TestSystemMemoryPressureEvaluator&) = delete;
+
+  MOCK_METHOD1(OnMemoryPressure,
+               void(base::MemoryPressureListener::MemoryPressureLevel level));
+};
+
 }  // namespace
 
 class SystemMemoryPressureEvaluatorFuchsiaTest
@@ -29,7 +47,8 @@
       public fuchsia::memorypressure::testing::Provider_TestBase {
  public:
   SystemMemoryPressureEvaluatorFuchsiaTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
+                          base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
 
   void SendPressureLevel(fuchsia::memorypressure::Level level) {
     base::RunLoop wait_loop;
@@ -53,7 +72,7 @@
     ADD_FAILURE() << "Unexpected call to method: " << name;
   }
 
-  const base::test::SingleThreadTaskEnvironment task_environment_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
 
   base::TestComponentContextForProcess test_context_;
 
@@ -65,7 +84,7 @@
 
 TEST_F(SystemMemoryPressureEvaluatorFuchsiaDeathTest, ProviderUnavailable) {
   auto voter = std::make_unique<MockMemoryPressureVoter>();
-  SystemMemoryPressureEvaluatorFuchsia evaluator(std::move(voter));
+  TestSystemMemoryPressureEvaluator evaluator(std::move(voter));
 
   // Spin the loop to allow the evaluator to notice that the Provider is not
   // available and verify that this causes a fatal failure.
@@ -94,7 +113,7 @@
       SetVote(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
               true));
 
-  SystemMemoryPressureEvaluatorFuchsia evaluator(std::move(voter));
+  TestSystemMemoryPressureEvaluator evaluator(std::move(voter));
 
   // Spin the loop to ensure that RegisterWatcher() is processed.
   base::RunLoop().RunUntilIdle();
@@ -113,4 +132,69 @@
             base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
 }
 
+TEST_F(SystemMemoryPressureEvaluatorFuchsiaTest, Periodic) {
+  base::fuchsia::ScopedServiceBinding<::fuchsia::memorypressure::Provider>
+      publish_provider(test_context_.additional_services(), this);
+
+  MultiSourceMemoryPressureMonitor monitor;
+  monitor.ResetSystemEvaluatorForTesting();
+
+  testing::StrictMock<TestSystemMemoryPressureEvaluator> evaluator(
+      monitor.CreateVoter());
+
+  // Spin the loop to ensure that RegisterWatcher() is processed.
+  base::RunLoop().RunUntilIdle();
+  ASSERT_TRUE(have_watcher());
+
+  base::MemoryPressureListener listener(
+      FROM_HERE,
+      base::BindRepeating(&TestSystemMemoryPressureEvaluator::OnMemoryPressure,
+                          base::Unretained(&evaluator)));
+
+  EXPECT_CALL(
+      evaluator,
+      OnMemoryPressure(
+          base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE));
+  SendPressureLevel(fuchsia::memorypressure::Level::WARNING);
+  EXPECT_EQ(evaluator.current_vote(),
+            base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
+  testing::Mock::VerifyAndClearExpectations(&evaluator);
+
+  // Verify that MODERATE pressure level is reported periodically.
+  EXPECT_CALL(
+      evaluator,
+      OnMemoryPressure(
+          base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE));
+  task_environment_.FastForwardBy(
+      base::MemoryPressureMonitor::kUMAMemoryPressureLevelPeriod);
+  testing::Mock::VerifyAndClearExpectations(&evaluator);
+
+  EXPECT_CALL(
+      evaluator,
+      OnMemoryPressure(
+          base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL));
+  SendPressureLevel(fuchsia::memorypressure::Level::CRITICAL);
+  EXPECT_EQ(evaluator.current_vote(),
+            base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+  testing::Mock::VerifyAndClearExpectations(&evaluator);
+
+  // Verify that CRITICAL pressure level is reported periodically.
+  EXPECT_CALL(
+      evaluator,
+      OnMemoryPressure(
+          base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL));
+  task_environment_.FastForwardBy(
+      base::MemoryPressureMonitor::kUMAMemoryPressureLevelPeriod);
+  testing::Mock::VerifyAndClearExpectations(&evaluator);
+
+  SendPressureLevel(fuchsia::memorypressure::Level::NORMAL);
+  EXPECT_EQ(evaluator.current_vote(),
+            base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
+
+  // Verify that NONE pressure level is not reported periodically.
+  task_environment_.FastForwardBy(
+      base::MemoryPressureMonitor::kUMAMemoryPressureLevelPeriod);
+  testing::Mock::VerifyAndClearExpectations(&evaluator);
+}
+
 }  // namespace util
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 3aaadda6..e06838e 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-0.20210115.2.1
+0.20210117.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 3aaadda6..e06838e 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-0.20210115.2.1
+0.20210117.3.1
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index 0dd26d06..1e14205 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -264,17 +264,28 @@
 
     tool("alink") {
       rspfile = "{{output}}.rsp"
-      rspfile_content = "{{inputs}}"
 
       if (!use_lld) {
+        # Note about -filelist: Apple's linker reads the file list file and
+        # interprets each newline-separated chunk of text as a file name. It
+        # doesn't do the things one would expect from the shell like unescaping
+        # or handling quotes. In contrast, when Ninja finds a file name with
+        # spaces, it single-quotes them in $inputs_newline as it would normally
+        # do for command-line arguments. Thus any source names with spaces, or
+        # label names with spaces (which GN bases the output paths on) will be
+        # corrupted by this process. Don't use spaces for source files or
+        # labels.
+        rspfile_content = "{{inputs_newline}}"
+
         script = rebase_path("//build/toolchain/mac/filter_libtool.py",
                              root_build_dir)
 
         # Specify explicit path for libtool.
         libtool = mac_bin_path + "libtool"
-        command = "rm -f {{output}} && TOOL_VERSION=${tool_versions.filter_libtool} python $script $libtool -static -D {{arflags}} -o {{output}} \"@$rspfile\""
+        command = "rm -f {{output}} && TOOL_VERSION=${tool_versions.filter_libtool} python $script $libtool -static -D {{arflags}} -o {{output}} -filelist $rspfile"
         description = "LIBTOOL-STATIC {{output}}"
       } else {
+        rspfile_content = "{{inputs}}"
         ar = "${prefix}llvm-ar"
         command = "\"$ar\" {{arflags}} -r -c -s -D {{output}} \"@$rspfile\""
 
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc
index 84a794c3..10c5307c 100644
--- a/cc/paint/oop_pixeltest.cc
+++ b/cc/paint/oop_pixeltest.cc
@@ -683,6 +683,10 @@
   sk_sp<PaintShader> paint_record_shader = PaintShader::MakePaintRecord(
       shader_buffer, tile_rect, SkTileMode::kRepeat, SkTileMode::kRepeat,
       nullptr, PaintShader::ScalingBehavior::kRasterAtScale);
+  // Force paint_flags to convert this to kFixedScale, so we can safely compare
+  // pixels between direct and oop-r modes (since oop will convert to
+  // kFixedScale no matter what.
+  paint_record_shader->set_has_animated_images(true);
 
   gfx::Size output_size(10, 10);
 
@@ -1712,7 +1716,12 @@
         BuildTextBlob(SkTypeface::MakeDefault(), UseLcdText()), 0u, 0u, flags);
     auto paint_record_shader = PaintShader::MakePaintRecord(
         paint_record, SkRect::MakeWH(25, 25), SkTileMode::kRepeat,
-        SkTileMode::kRepeat, nullptr);
+        SkTileMode::kRepeat, nullptr,
+        PaintShader::ScalingBehavior::kRasterAtScale);
+    // Force paint_flags to convert this to kFixedScale, so we can safely
+    // compare pixels between direct and oop-r modes (since oop will convert to
+    // kFixedScale no matter what.
+    paint_record_shader->set_has_animated_images(true);
 
     auto display_item_list = base::MakeRefCounted<DisplayItemList>();
     display_item_list->StartPaint();
diff --git a/chrome/VERSION b/chrome/VERSION
index 4b72267..4d18a6b 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=90
 MINOR=0
-BUILD=4391
+BUILD=4393
 PATCH=0
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 14bc79c..35c3f7f 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-89.0.4389.2_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-89.0.4389.5_rc-r1-merged.afdo.bz2
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index eb2810c9..845b4dd 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3209,10 +3209,6 @@
     {"crostini-enable-dlc", flag_descriptions::kCrostiniEnableDlcName,
      flag_descriptions::kCrostiniEnableDlcDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kCrostiniEnableDlc)},
-    {"guest-os-external-protocol",
-     flag_descriptions::kGuestOsExternalProtocolName,
-     flag_descriptions::kGuestOsExternalProtocolDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(chromeos::features::kGuestOsExternalProtocol)},
     {"pluginvm-show-camera-permissions",
      flag_descriptions::kPluginVmShowCameraPermissionsName,
      flag_descriptions::kPluginVmShowCameraPermissionsDescription, kOsCrOS,
diff --git a/chrome/browser/apps/app_service/app_launch_params.cc b/chrome/browser/apps/app_service/app_launch_params.cc
index 742db7f..27673e79 100644
--- a/chrome/browser/apps/app_service/app_launch_params.cc
+++ b/chrome/browser/apps/app_service/app_launch_params.cc
@@ -21,6 +21,7 @@
 AppLaunchParams::AppLaunchParams(const std::string& app_id,
                                  apps::mojom::LaunchContainer container,
                                  WindowOpenDisposition disposition,
+                                 apps::mojom::AppLaunchSource source,
                                  int64_t display_id,
                                  const std::vector<base::FilePath>& files,
                                  const apps::mojom::IntentPtr& intentPtr)
@@ -28,6 +29,7 @@
       container(container),
       disposition(disposition),
       command_line(base::CommandLine::NO_PROGRAM),
+      source(source),
       display_id(display_id),
       launch_files(files),
       intent(intentPtr ? intentPtr.Clone() : nullptr) {}
diff --git a/chrome/browser/apps/app_service/app_launch_params.h b/chrome/browser/apps/app_service/app_launch_params.h
index 49b918cb..db34870 100644
--- a/chrome/browser/apps/app_service/app_launch_params.h
+++ b/chrome/browser/apps/app_service/app_launch_params.h
@@ -28,6 +28,7 @@
   AppLaunchParams(const std::string& app_id,
                   apps::mojom::LaunchContainer container,
                   WindowOpenDisposition disposition,
+                  apps::mojom::AppLaunchSource source,
                   int64_t display_id,
                   const std::vector<base::FilePath>& files,
                   const apps::mojom::IntentPtr& intentPtr);
diff --git a/chrome/browser/apps/app_service/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/extension_apps_chromeos.cc
index ea440ea1..c028d48 100644
--- a/chrome/browser/apps/app_service/extension_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/extension_apps_chromeos.cc
@@ -694,9 +694,9 @@
 
 content::WebContents* ExtensionAppsChromeOs::LaunchImpl(
     AppLaunchParams&& params) {
-  AppLaunchParams params_for_restore(params.app_id, params.container,
-                                     params.disposition, params.display_id,
-                                     params.launch_files, params.intent);
+  AppLaunchParams params_for_restore(
+      params.app_id, params.container, params.disposition, params.source,
+      params.display_id, params.launch_files, params.intent);
 
   auto* web_contents = ExtensionAppsBase::LaunchImpl(std::move(params));
 
diff --git a/chrome/browser/apps/app_service/web_apps_chromeos.cc b/chrome/browser/apps/app_service/web_apps_chromeos.cc
index 29f9c9c..ad5c161 100644
--- a/chrome/browser/apps/app_service/web_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/web_apps_chromeos.cc
@@ -607,9 +607,9 @@
 
 content::WebContents* WebAppsChromeOs::LaunchAppWithParams(
     AppLaunchParams params) {
-  AppLaunchParams params_for_restore(params.app_id, params.container,
-                                     params.disposition, params.display_id,
-                                     params.launch_files, params.intent);
+  AppLaunchParams params_for_restore(
+      params.app_id, params.container, params.disposition, params.source,
+      params.display_id, params.launch_files, params.intent);
 
   auto* web_contents = WebAppsBase::LaunchAppWithParams(std::move(params));
 
diff --git a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
index b9053519..5856f8ae3 100644
--- a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
+++ b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/browser/web_applications/components/app_registrar.h"
@@ -209,6 +210,24 @@
     case blink::mojom::CaptureLinks::kNone:
       return base::nullopt;
 
+    case blink::mojom::CaptureLinks::kExistingClientNavigate: {
+      for (Browser* open_browser : *BrowserList::GetInstance()) {
+        if (web_app::AppBrowserController::IsForWebApp(open_browser, *app_id)) {
+          open_browser->OpenURL(
+              content::OpenURLParams::FromNavigationHandle(handle));
+
+          // If |web_contents| hasn't loaded yet or has only loaded about:blank
+          // we should remove it to avoid leaving behind a blank tab.
+          if (tab_helper && !tab_helper->HasLoadedNonAboutBlankPage())
+            web_contents->Close();
+
+          return content::NavigationThrottle::CANCEL_AND_IGNORE;
+        }
+      }
+      // Fall back to new-client if there are no existing clients to navigate.
+      FALLTHROUGH;
+    }
+
     case blink::mojom::CaptureLinks::kNewClient: {
       // If |web_contents| hasn't loaded yet or has only loaded about:blank we
       // should reparent it into the app window to avoid leaving behind a blank
@@ -228,10 +247,6 @@
           ->LaunchAppWithParams(std::move(launch_params));
       return content::NavigationThrottle::CANCEL_AND_IGNORE;
     }
-
-    case blink::mojom::CaptureLinks::kExistingClientNavigate:
-      // TODO(crbug.com/1163398): Implement.
-      return base::nullopt;
   }
 }
 
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.cc b/chrome/browser/ash/accessibility/accessibility_manager.cc
index 98843e90..6f2d61f 100644
--- a/chrome/browser/ash/accessibility/accessibility_manager.cc
+++ b/chrome/browser/ash/accessibility/accessibility_manager.cc
@@ -365,8 +365,8 @@
 
 AccessibilityManager::~AccessibilityManager() {
   CHECK(this == g_accessibility_manager);
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_MANAGER_SHUTDOWN,
-                                          false);
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kManagerShutdown, false);
   NotifyAccessibilityStatusChanged(details);
   CrasAudioHandler::Get()->RemoveAudioObserver(this);
   user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
@@ -432,8 +432,9 @@
 }
 
 void AccessibilityManager::OnLargeCursorChanged() {
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_LARGE_CURSOR,
-                                          IsLargeCursorEnabled());
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleLargeCursor,
+      IsLargeCursorEnabled());
   NotifyAccessibilityStatusChanged(details);
 }
 
@@ -457,8 +458,8 @@
 }
 
 void AccessibilityManager::OnStickyKeysChanged() {
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_STICKY_KEYS,
-                                          IsStickyKeysEnabled());
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleStickyKeys, IsStickyKeysEnabled());
   NotifyAccessibilityStatusChanged(details);
 }
 
@@ -497,8 +498,8 @@
 
   spoken_feedback_enabled_ = enabled;
 
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
-                                          enabled);
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleSpokenFeedback, enabled);
   NotifyAccessibilityStatusChanged(details);
 
   if (enabled) {
@@ -533,7 +534,8 @@
 
 void AccessibilityManager::OnHighContrastChanged() {
   AccessibilityStatusEventDetails details(
-      ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE, IsHighContrastEnabled());
+      AccessibilityNotificationType::kToggleHighContrastMode,
+      IsHighContrastEnabled());
   NotifyAccessibilityStatusChanged(details);
 }
 
@@ -751,8 +753,9 @@
 }
 
 void AccessibilityManager::OnVirtualKeyboardChanged() {
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD,
-                                          IsVirtualKeyboardEnabled());
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleVirtualKeyboard,
+      IsVirtualKeyboardEnabled());
   NotifyAccessibilityStatusChanged(details);
 }
 
@@ -771,8 +774,8 @@
 }
 
 void AccessibilityManager::OnMonoAudioChanged() {
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_MONO_AUDIO,
-                                          IsMonoAudioEnabled());
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleMonoAudio, IsMonoAudioEnabled());
   NotifyAccessibilityStatusChanged(details);
 }
 
@@ -796,8 +799,9 @@
 }
 
 void AccessibilityManager::OnCaretHighlightChanged() {
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_CARET_HIGHLIGHT,
-                                          IsCaretHighlightEnabled());
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleCaretHighlight,
+      IsCaretHighlightEnabled());
   NotifyAccessibilityStatusChanged(details);
 }
 
@@ -817,8 +821,9 @@
 }
 
 void AccessibilityManager::OnCursorHighlightChanged() {
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_CURSOR_HIGHLIGHT,
-                                          IsCursorHighlightEnabled());
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleCursorHighlight,
+      IsCursorHighlightEnabled());
   NotifyAccessibilityStatusChanged(details);
 }
 
@@ -849,8 +854,8 @@
   // ChromeVox does its own focus highlighting.
   if (IsSpokenFeedbackEnabled())
     enabled = false;
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_FOCUS_HIGHLIGHT,
-                                          enabled);
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleFocusHighlight, enabled);
   NotifyAccessibilityStatusChanged(details);
 
   // TODO(crbug.com/1096759): Load or unload the AccessibilityCommon extension
@@ -913,8 +918,8 @@
 
   select_to_speak_enabled_ = enabled;
 
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK,
-                                          enabled);
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleSelectToSpeak, enabled);
   NotifyAccessibilityStatusChanged(details);
 
   if (enabled) {
@@ -973,8 +978,8 @@
     return;
   switch_access_enabled_ = enabled;
 
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_SWITCH_ACCESS,
-                                          enabled);
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleSwitchAccess, enabled);
   NotifyAccessibilityStatusChanged(details);
 
   if (enabled) {
@@ -1241,7 +1246,8 @@
     const AccessibilityStatusEventDetails& details) {
   callback_list_.Notify(details);
 
-  if (details.notification_type == ACCESSIBILITY_TOGGLE_DICTATION) {
+  if (details.notification_type ==
+      AccessibilityNotificationType::kToggleDictation) {
     ash::AccessibilityController::Get()->SetDictationActive(details.enabled);
     ash::AccessibilityController::Get()->NotifyAccessibilityStatusChanged();
     return;
@@ -1250,8 +1256,11 @@
   // Update system tray menu visibility. Prefs tracked inside ash handle their
   // own updates to avoid race conditions (pref updates are asynchronous between
   // chrome and ash).
-  if (details.notification_type == ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER ||
-      details.notification_type == ACCESSIBILITY_TOGGLE_DICTATION) {
+  // TODO(hferreiro): repeated condition
+  if (details.notification_type ==
+          AccessibilityNotificationType::kToggleScreenMagnifier ||
+      details.notification_type ==
+          AccessibilityNotificationType::kToggleDictation) {
     ash::AccessibilityController::Get()->NotifyAccessibilityStatusChanged();
   }
 }
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.h b/chrome/browser/ash/accessibility/accessibility_manager.h
index ed5a088..5470eab 100644
--- a/chrome/browser/ash/accessibility/accessibility_manager.h
+++ b/chrome/browser/ash/accessibility/accessibility_manager.h
@@ -54,22 +54,22 @@
 class SelectToSpeakEventHandlerDelegate;
 enum class Sound;
 
-enum AccessibilityNotificationType {
-  ACCESSIBILITY_MANAGER_SHUTDOWN,
-  ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
-  ACCESSIBILITY_TOGGLE_LARGE_CURSOR,
-  ACCESSIBILITY_TOGGLE_STICKY_KEYS,
-  ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
-  ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
-  ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK,
-  ACCESSIBILITY_TOGGLE_SWITCH_ACCESS,
-  ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD,
-  ACCESSIBILITY_TOGGLE_MONO_AUDIO,
-  ACCESSIBILITY_TOGGLE_CARET_HIGHLIGHT,
-  ACCESSIBILITY_TOGGLE_CURSOR_HIGHLIGHT,
-  ACCESSIBILITY_TOGGLE_FOCUS_HIGHLIGHT,
-  ACCESSIBILITY_TOGGLE_DICTATION,
-  ACCESSIBILITY_TOGGLE_DOCKED_MAGNIFIER,
+enum class AccessibilityNotificationType {
+  kManagerShutdown,
+  kToggleHighContrastMode,
+  kToggleLargeCursor,
+  kToggleStickyKeys,
+  kToggleScreenMagnifier,
+  kToggleSpokenFeedback,
+  kToggleSelectToSpeak,
+  kToggleSwitchAccess,
+  kToggleVirtualKeyboard,
+  kToggleMonoAudio,
+  kToggleCaretHighlight,
+  kToggleCursorHighlight,
+  kToggleFocusHighlight,
+  kToggleDictation,
+  kToggleDockedMagnifier,
 };
 
 struct AccessibilityStatusEventDetails {
diff --git a/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc
index e88925a..0e1228d5 100644
--- a/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc
+++ b/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/macros.h"
+#include "base/optional.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chrome/browser/chromeos/login/test/guest_session_mixin.h"
@@ -74,14 +75,17 @@
 
   bool observed() const { return observed_; }
   bool observed_enabled() const { return observed_enabled_; }
-  int observed_type() const { return observed_type_; }
+  base::Optional<AccessibilityNotificationType> observed_type() const {
+    return observed_type_;
+  }
 
   void reset() { observed_ = false; }
 
  private:
   void OnAccessibilityStatusChanged(
       const AccessibilityStatusEventDetails& details) {
-    if (details.notification_type != ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER) {
+    if (details.notification_type !=
+        AccessibilityNotificationType::kToggleScreenMagnifier) {
       observed_type_ = details.notification_type;
       observed_enabled_ = details.enabled;
       observed_ = true;
@@ -90,7 +94,7 @@
 
   bool observed_ = false;
   bool observed_enabled_ = false;
-  int observed_type_ = -1;
+  base::Optional<AccessibilityNotificationType> observed_type_;
 
   base::CallbackListSubscription accessibility_subscription_;
 
@@ -328,70 +332,80 @@
   SetSpokenFeedbackEnabled(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSpokenFeedback);
   EXPECT_TRUE(IsSpokenFeedbackEnabled());
 
   observer.reset();
   SetSpokenFeedbackEnabled(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSpokenFeedback);
   EXPECT_FALSE(IsSpokenFeedbackEnabled());
 
   observer.reset();
   SetHighContrastEnabled(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleHighContrastMode);
   EXPECT_TRUE(IsHighContrastEnabled());
 
   observer.reset();
   SetHighContrastEnabled(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleHighContrastMode);
   EXPECT_FALSE(IsHighContrastEnabled());
 
   observer.reset();
   SetVirtualKeyboardEnabled(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleVirtualKeyboard);
   EXPECT_TRUE(IsVirtualKeyboardEnabled());
 
   observer.reset();
   SetVirtualKeyboardEnabled(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleVirtualKeyboard);
   EXPECT_FALSE(IsVirtualKeyboardEnabled());
 
   observer.reset();
   SetMonoAudioEnabled(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_MONO_AUDIO);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleMonoAudio);
   EXPECT_TRUE(IsMonoAudioEnabled());
 
   observer.reset();
   SetMonoAudioEnabled(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_MONO_AUDIO);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleMonoAudio);
   EXPECT_FALSE(IsMonoAudioEnabled());
 
   observer.reset();
   SetSelectToSpeakEnabled(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSelectToSpeak);
   EXPECT_TRUE(IsSelectToSpeakEnabled());
 
   observer.reset();
   SetSelectToSpeakEnabled(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSelectToSpeak);
   EXPECT_FALSE(IsSelectToSpeakEnabled());
 }
 
@@ -402,70 +416,80 @@
   SetSpokenFeedbackEnabledPref(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSpokenFeedback);
   EXPECT_TRUE(IsSpokenFeedbackEnabled());
 
   observer.reset();
   SetSpokenFeedbackEnabledPref(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSpokenFeedback);
   EXPECT_FALSE(IsSpokenFeedbackEnabled());
 
   observer.reset();
   SetHighContrastEnabledPref(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleHighContrastMode);
   EXPECT_TRUE(IsHighContrastEnabled());
 
   observer.reset();
   SetHighContrastEnabledPref(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleHighContrastMode);
   EXPECT_FALSE(IsHighContrastEnabled());
 
   observer.reset();
   SetVirtualKeyboardEnabledPref(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleVirtualKeyboard);
   EXPECT_TRUE(IsVirtualKeyboardEnabled());
 
   observer.reset();
   SetVirtualKeyboardEnabledPref(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleVirtualKeyboard);
   EXPECT_FALSE(IsVirtualKeyboardEnabled());
 
   observer.reset();
   SetMonoAudioEnabledPref(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_MONO_AUDIO);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleMonoAudio);
   EXPECT_TRUE(IsMonoAudioEnabled());
 
   observer.reset();
   SetMonoAudioEnabledPref(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_MONO_AUDIO);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleMonoAudio);
   EXPECT_FALSE(IsMonoAudioEnabled());
 
   observer.reset();
   SetSelectToSpeakEnabledPref(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSelectToSpeak);
   EXPECT_TRUE(IsSelectToSpeakEnabled());
 
   observer.reset();
   SetSelectToSpeakEnabledPref(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
-  EXPECT_EQ(observer.observed_type(), ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK);
+  EXPECT_EQ(observer.observed_type(),
+            AccessibilityNotificationType::kToggleSelectToSpeak);
   EXPECT_FALSE(IsSelectToSpeakEnabled());
 }
 
diff --git a/chrome/browser/ash/accessibility/dictation_chromeos.cc b/chrome/browser/ash/accessibility/dictation_chromeos.cc
index 4cadb6f..0cd842d6 100644
--- a/chrome/browser/ash/accessibility/dictation_chromeos.cc
+++ b/chrome/browser/ash/accessibility/dictation_chromeos.cc
@@ -149,7 +149,7 @@
   }
 
   chromeos::AccessibilityStatusEventDetails details(
-      chromeos::AccessibilityNotificationType::ACCESSIBILITY_TOGGLE_DICTATION,
+      chromeos::AccessibilityNotificationType::kToggleDictation,
       false /* enabled */);
   chromeos::AccessibilityManager::Get()->NotifyAccessibilityStatusChanged(
       details);
diff --git a/chrome/browser/ash/accessibility/magnification_manager.cc b/chrome/browser/ash/accessibility/magnification_manager.cc
index 40600a8..a0c67d7 100644
--- a/chrome/browser/ash/accessibility/magnification_manager.cc
+++ b/chrome/browser/ash/accessibility/magnification_manager.cc
@@ -299,8 +299,9 @@
     SetMagnifierEnabledInternal(enabled);
   }
 
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
-                                          fullscreen_magnifier_enabled_);
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleScreenMagnifier,
+      fullscreen_magnifier_enabled_);
 
   if (!AccessibilityManager::Get())
     return;
@@ -315,8 +316,8 @@
 
   PrefService* prefs = profile_->GetPrefs();
   const bool enabled = prefs->GetBoolean(ash::prefs::kDockedMagnifierEnabled);
-  AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_DOCKED_MAGNIFIER,
-                                          enabled);
+  AccessibilityStatusEventDetails details(
+      AccessibilityNotificationType::kToggleDockedMagnifier, enabled);
 
   if (!AccessibilityManager::Get())
     return;
diff --git a/chrome/browser/ash/accessibility/magnification_manager_browsertest.cc b/chrome/browser/ash/accessibility/magnification_manager_browsertest.cc
index c475d35..0923c9a 100644
--- a/chrome/browser/ash/accessibility/magnification_manager_browsertest.cc
+++ b/chrome/browser/ash/accessibility/magnification_manager_browsertest.cc
@@ -133,7 +133,8 @@
  private:
   void OnAccessibilityStatusChanged(
       const AccessibilityStatusEventDetails& details) {
-    if (details.notification_type == ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER) {
+    if (details.notification_type ==
+        AccessibilityNotificationType::kToggleScreenMagnifier) {
       observed_enabled_ = details.enabled;
       observed_ = true;
     }
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index b291630..8d9f542 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -633,7 +633,8 @@
 };
 
 // Test that autofill available state is correctly set on accessibility node.
-IN_PROC_BROWSER_TEST_F(AutofillAccessibilityTest, TestAutofillState) {
+// crbug.com/1162484
+IN_PROC_BROWSER_TEST_F(AutofillAccessibilityTest, DISABLED_TestAutofillState) {
   content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
 
   // Navigate to url.
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
index b9b9c64..b5c04ee 100644
--- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
+++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -695,17 +695,17 @@
 void ArcAccessibilityHelperBridge::OnAccessibilityStatusChanged(
     const chromeos::AccessibilityStatusEventDetails& event_details) {
   if (event_details.notification_type !=
-          chromeos::ACCESSIBILITY_TOGGLE_FOCUS_HIGHLIGHT &&
+          chromeos::AccessibilityNotificationType::kToggleFocusHighlight &&
       event_details.notification_type !=
-          chromeos::ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK &&
+          chromeos::AccessibilityNotificationType::kToggleSelectToSpeak &&
       event_details.notification_type !=
-          chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK &&
+          chromeos::AccessibilityNotificationType::kToggleSpokenFeedback &&
       event_details.notification_type !=
-          chromeos::ACCESSIBILITY_TOGGLE_SWITCH_ACCESS &&
+          chromeos::AccessibilityNotificationType::kToggleSwitchAccess &&
       event_details.notification_type !=
-          chromeos::ACCESSIBILITY_TOGGLE_DOCKED_MAGNIFIER &&
+          chromeos::AccessibilityNotificationType::kToggleDockedMagnifier &&
       event_details.notification_type !=
-          chromeos::ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER) {
+          chromeos::AccessibilityNotificationType::kToggleScreenMagnifier) {
     return;
   }
 
@@ -713,7 +713,7 @@
   UpdateWindowProperties(GetActiveWindow());
 
   if (event_details.notification_type ==
-      chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) {
+      chromeos::AccessibilityNotificationType::kToggleSpokenFeedback) {
     SetExploreByTouchEnabled(event_details.enabled);
   }
 }
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
index ae8dfd7..f341057 100644
--- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
+++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
@@ -598,7 +598,7 @@
 void ArcInputMethodManagerService::OnAccessibilityStatusChanged(
     const chromeos::AccessibilityStatusEventDetails& event_details) {
   if (event_details.notification_type !=
-      chromeos::ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD) {
+      chromeos::AccessibilityNotificationType::kToggleVirtualKeyboard) {
     // This class is not interested in a11y events except toggling virtual
     // keyboard event.
     return;
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
index 30b3d613..746a166 100644
--- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -766,7 +766,7 @@
       ash::prefs::kAccessibilityVirtualKeyboardEnabled, true);
   // Notify ArcInputMethodManagerService.
   service()->OnAccessibilityStatusChanged(
-      {chromeos::ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, true});
+      {chromeos::AccessibilityNotificationType::kToggleVirtualKeyboard, true});
 
   // ARC IME is not allowed when a11y keyboard is enabled.
   EXPECT_EQ(1u, imm()->state()->removed_input_method_extensions_.size());
@@ -785,7 +785,7 @@
       ash::prefs::kAccessibilityVirtualKeyboardEnabled, false);
   // Notify ArcInputMethodManagerService.
   service()->OnAccessibilityStatusChanged(
-      {chromeos::ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, false});
+      {chromeos::AccessibilityNotificationType::kToggleVirtualKeyboard, false});
 
   // ARC IME can be enabled.
   EXPECT_EQ(1u, imm()->state()->added_input_method_extensions_.size());
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc
index f12a4056..aeb65f5e 100644
--- a/chrome/browser/chromeos/extensions/default_app_order.cc
+++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -62,6 +62,7 @@
     web_app::kGoogleDriveAppId,
 
     extension_misc::kGoogleKeepAppId,
+    web_app::kGoogleKeepAppId,
 
     arc::kGoogleCalendarAppId,
     extension_misc::kCalendarAppId,
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc
index c92c0b7..03d5788 100644
--- a/chrome/browser/chromeos/extensions/input_method_api.cc
+++ b/chrome/browser/chromeos/extensions/input_method_api.cc
@@ -449,13 +449,6 @@
       }
       segments.push_back(segment_info);
     }
-  } else {
-    // Default to a single segment that spans the entire range.
-    InputMethodEngineBase::SegmentInfo segment_info;
-    segment_info.start = 0;
-    segment_info.end = params.selection_before + params.selection_after;
-    segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE;
-    segments.push_back(segment_info);
   }
 
   if (!engine->SetCompositionRange(params.context_id, params.selection_before,
@@ -499,13 +492,6 @@
       }
       segments.push_back(segment_info);
     }
-  } else {
-    // Default to a single segment that spans the entire composing range.
-    InputMethodEngineBase::SegmentInfo segment_info;
-    segment_info.start = 0;
-    segment_info.end = params.end - params.start;
-    segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE;
-    segments.push_back(segment_info);
   }
 
   if (!engine->SetComposingRange(params.context_id, params.start, params.end,
diff --git a/chrome/browser/chromeos/external_protocol_dialog.cc b/chrome/browser/chromeos/external_protocol_dialog.cc
index 69103b67..939fde0b 100644
--- a/chrome/browser/chromeos/external_protocol_dialog.cc
+++ b/chrome/browser/chromeos/external_protocol_dialog.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/chromeos/external_protocol_dialog.h"
 
-#include "base/feature_list.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.h"
 #include "chrome/browser/chromeos/guest_os/guest_os_external_protocol_handler.h"
@@ -15,7 +14,6 @@
 #include "chrome/browser/ui/views/external_protocol_dialog.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
-#include "chromeos/constants/chromeos_features.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
@@ -44,20 +42,16 @@
       tab_util::GetWebContentsByID(render_process_host_id, routing_id);
 
   // Display the standard ExternalProtocolDialog if Guest OS has a handler.
-  if (web_contents && base::FeatureList::IsEnabled(
-                          chromeos::features::kGuestOsExternalProtocol)) {
-    base::Optional<guest_os::GuestOsRegistryService::Registration>
-        registration = guest_os::GetHandler(
-            Profile::FromBrowserContext(web_contents->GetBrowserContext()),
-            url);
-    if (registration) {
-      new ExternalProtocolDialog(web_contents, url,
-                                 base::UTF8ToUTF16(registration->Name()),
-                                 initiating_origin);
-      return;
-    }
+  base::Optional<guest_os::GuestOsRegistryService::Registration> registration =
+      guest_os::GetHandler(
+          Profile::FromBrowserContext(web_contents->GetBrowserContext()), url);
+  if (registration) {
+    new ExternalProtocolDialog(web_contents, url,
+                               base::UTF8ToUTF16(registration->Name()),
+                               initiating_origin);
+  } else {
+    new ExternalProtocolNoHandlersDialog(web_contents, url);
   }
-  new ExternalProtocolNoHandlersDialog(web_contents, url);
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/file_manager/image_loader_jstest.cc b/chrome/browser/chromeos/file_manager/image_loader_jstest.cc
index 9152223..93c8354 100644
--- a/chrome/browser/chromeos/file_manager/image_loader_jstest.cc
+++ b/chrome/browser/chromeos/file_manager/image_loader_jstest.cc
@@ -16,13 +16,13 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ImageLoaderJsTest, CacheTest) {
-  RunTestURL("cache_unittest_gen.html");
+  RunTestURL("cache_unittest.m_gen.html");
 }
 
 IN_PROC_BROWSER_TEST_F(ImageLoaderJsTest, ImageLoaderTest) {
-  RunTestURL("image_loader_unittest_gen.html");
+  RunTestURL("image_loader_unittest.m_gen.html");
 }
 
 IN_PROC_BROWSER_TEST_F(ImageLoaderJsTest, SchedulerTest) {
-  RunTestURL("scheduler_unittest_gen.html");
+  RunTestURL("scheduler_unittest.m_gen.html");
 }
diff --git a/chrome/browser/chromeos/full_restore/app_launch_handler.cc b/chrome/browser/chromeos/full_restore/app_launch_handler.cc
index e1b693d1ff..2860858 100644
--- a/chrome/browser/chromeos/full_restore/app_launch_handler.cc
+++ b/chrome/browser/chromeos/full_restore/app_launch_handler.cc
@@ -201,6 +201,7 @@
         app_id,
         static_cast<apps::mojom::LaunchContainer>(it.second->container.value()),
         static_cast<WindowOpenDisposition>(it.second->disposition.value()),
+        apps::mojom::AppLaunchSource::kSourceChromeInternal,
         it.second->display_id.value(),
         it.second->file_paths.has_value() ? it.second->file_paths.value()
                                           : std::vector<base::FilePath>{},
diff --git a/chrome/browser/chromeos/full_restore/app_launch_handler_browsertest.cc b/chrome/browser/chromeos/full_restore/app_launch_handler_browsertest.cc
new file mode 100644
index 0000000..bc7a2e3
--- /dev/null
+++ b/chrome/browser/chromeos/full_restore/app_launch_handler_browsertest.cc
@@ -0,0 +1,300 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/full_restore/app_launch_handler.h"
+
+#include "ash/public/cpp/ash_features.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/timer/timer.h"
+#include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
+#include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/full_restore/app_launch_info.h"
+#include "components/full_restore/full_restore_read_handler.h"
+#include "components/full_restore/full_restore_save_handler.h"
+#include "components/full_restore/full_restore_utils.h"
+#include "components/services/app_service/public/mojom/types.mojom.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/test_utils.h"
+#include "ui/aura/window.h"
+#include "ui/base/window_open_disposition.h"
+#include "ui/display/types/display_constants.h"
+
+namespace chromeos {
+namespace full_restore {
+
+namespace {
+
+const char kAppId[] = "mldnpnnoiloahfhddhobgjeophloidmo";
+const int32_t kId = 100;
+
+}  // namespace
+
+class AppLaunchHandlerBrowserTest : public InProcessBrowserTest {
+ public:
+  AppLaunchHandlerBrowserTest() {
+    scoped_feature_list_.InitAndEnableFeature(ash::features::kFullRestore);
+  }
+  ~AppLaunchHandlerBrowserTest() override = default;
+
+  void WaitForAppLaunchInfoSaved() {
+    ::full_restore::FullRestoreSaveHandler* save_handler =
+        ::full_restore::FullRestoreSaveHandler::GetInstance();
+    base::OneShotTimer* timer = save_handler->GetTimerForTesting();
+    EXPECT_TRUE(timer->IsRunning());
+
+    // Simulate timeout, and the launch info is saved.
+    timer->FireNow();
+    content::RunAllTasksUntilIdle();
+  }
+
+  void CreateWebApp() {
+    auto web_application_info = std::make_unique<WebApplicationInfo>();
+    web_application_info->start_url = GURL("https://example.org");
+    web_app::AppId app_id =
+        web_app::InstallWebApp(profile(), std::move(web_application_info));
+
+    // Wait for app service to see the newly installed app.
+    auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile());
+    proxy->FlushMojoCallsForTesting();
+  }
+
+  bool FindWebAppWindow() {
+    for (auto* browser : *BrowserList::GetInstance()) {
+      aura::Window* window = browser->window()->GetNativeWindow();
+      if (window->GetProperty(::full_restore::kRestoreWindowIdKey) == kId)
+        return true;
+    }
+    return false;
+  }
+
+  Profile* profile() { return browser()->profile(); }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest, NotLaunchBrowser) {
+  // Add app launch info.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(), std::make_unique<::full_restore::AppLaunchInfo>(
+                                extension_misc::kChromeAppId, kId));
+
+  WaitForAppLaunchInfoSaved();
+
+  size_t count = BrowserList::GetInstance()->size();
+
+  // Create AppLaunchHandler, and set should restore.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+  app_launch_handler->SetShouldRestore();
+
+  content::RunAllTasksUntilIdle();
+
+  // Verify there is no new browser launched.
+  EXPECT_EQ(count, BrowserList::GetInstance()->size());
+}
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest, RestoreAndAddApp) {
+  // Add app launch info.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(),
+      std::make_unique<::full_restore::AppLaunchInfo>(
+          kAppId, kId, apps::mojom::LaunchContainer::kLaunchContainerWindow,
+          WindowOpenDisposition::NEW_WINDOW, display::kDefaultDisplayId,
+          std::vector<base::FilePath>{}, nullptr));
+
+  WaitForAppLaunchInfoSaved();
+
+  // Create AppLaunchHandler, and set should restore.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+  app_launch_handler->SetShouldRestore();
+
+  CreateWebApp();
+
+  content::RunAllTasksUntilIdle();
+
+  EXPECT_TRUE(FindWebAppWindow());
+}
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest, AddAppAndRestore) {
+  // Add app launch info.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(),
+      std::make_unique<::full_restore::AppLaunchInfo>(
+          kAppId, kId, apps::mojom::LaunchContainer::kLaunchContainerWindow,
+          WindowOpenDisposition::NEW_WINDOW, display::kDefaultDisplayId,
+          std::vector<base::FilePath>{}, nullptr));
+
+  WaitForAppLaunchInfoSaved();
+
+  // Create AppLaunchHandler.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+
+  CreateWebApp();
+
+  // Set should restore
+  app_launch_handler->SetShouldRestore();
+
+  content::RunAllTasksUntilIdle();
+
+  EXPECT_TRUE(FindWebAppWindow());
+}
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest, NotRestore) {
+  // Add app launch infos.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(), std::make_unique<::full_restore::AppLaunchInfo>(
+                                extension_misc::kChromeAppId, kId));
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(),
+      std::make_unique<::full_restore::AppLaunchInfo>(
+          kAppId, kId, apps::mojom::LaunchContainer::kLaunchContainerWindow,
+          WindowOpenDisposition::NEW_WINDOW, display::kDefaultDisplayId,
+          std::vector<base::FilePath>{}, nullptr));
+
+  WaitForAppLaunchInfoSaved();
+
+  size_t count = BrowserList::GetInstance()->size();
+
+  // Create AppLaunchHandler.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+  app_launch_handler->LauncherBrowserWhenReady();
+
+  CreateWebApp();
+
+  content::RunAllTasksUntilIdle();
+
+  // Verify there is no new browser launched.
+  EXPECT_EQ(count, BrowserList::GetInstance()->size());
+  EXPECT_FALSE(FindWebAppWindow());
+}
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest, RestoreAndLaunchBrowser) {
+  size_t count = BrowserList::GetInstance()->size();
+
+  // Add the chrome browser launch info.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(), std::make_unique<::full_restore::AppLaunchInfo>(
+                                extension_misc::kChromeAppId, kId));
+
+  WaitForAppLaunchInfoSaved();
+
+  // Create AppLaunchHandler.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+
+  // Set should restore
+  app_launch_handler->SetShouldRestore();
+  content::RunAllTasksUntilIdle();
+
+  app_launch_handler->LauncherBrowserWhenReady();
+  content::RunAllTasksUntilIdle();
+
+  // Verify there is new browser launched.
+  EXPECT_EQ(count + 1, BrowserList::GetInstance()->size());
+}
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest, LaunchBrowserAndRestore) {
+  size_t count = BrowserList::GetInstance()->size();
+
+  // Add the chrome browser launch info.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(), std::make_unique<::full_restore::AppLaunchInfo>(
+                                extension_misc::kChromeAppId, kId));
+
+  WaitForAppLaunchInfoSaved();
+
+  // Create AppLaunchHandler.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+
+  app_launch_handler->LauncherBrowserWhenReady();
+  content::RunAllTasksUntilIdle();
+
+  // Verify there is no new browser launched.
+  EXPECT_EQ(count, BrowserList::GetInstance()->size());
+
+  // Set should restore
+  app_launch_handler->SetShouldRestore();
+  content::RunAllTasksUntilIdle();
+
+  // Verify there is new browser launched.
+  EXPECT_EQ(count + 1, BrowserList::GetInstance()->size());
+}
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest,
+                       RestoreAndLaunchBrowserAndAddApp) {
+  size_t count = BrowserList::GetInstance()->size();
+
+  // Add app launch infos.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(), std::make_unique<::full_restore::AppLaunchInfo>(
+                                extension_misc::kChromeAppId, kId));
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(),
+      std::make_unique<::full_restore::AppLaunchInfo>(
+          kAppId, kId, apps::mojom::LaunchContainer::kLaunchContainerWindow,
+          WindowOpenDisposition::NEW_WINDOW, display::kDefaultDisplayId,
+          std::vector<base::FilePath>{}, nullptr));
+
+  WaitForAppLaunchInfoSaved();
+
+  // Create AppLaunchHandler, and set should restore.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+  app_launch_handler->SetShouldRestore();
+  content::RunAllTasksUntilIdle();
+
+  app_launch_handler->LauncherBrowserWhenReady();
+  content::RunAllTasksUntilIdle();
+
+  CreateWebApp();
+  content::RunAllTasksUntilIdle();
+
+  // Verify there is new browser launched.
+  EXPECT_EQ(count + 2, BrowserList::GetInstance()->size());
+  EXPECT_TRUE(FindWebAppWindow());
+}
+
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerBrowserTest,
+                       LaunchBrowserAndAddAppAndRestore) {
+  size_t count = BrowserList::GetInstance()->size();
+
+  // Add app launch infos.
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(), std::make_unique<::full_restore::AppLaunchInfo>(
+                                extension_misc::kChromeAppId, kId));
+  ::full_restore::SaveAppLaunchInfo(
+      profile()->GetPath(),
+      std::make_unique<::full_restore::AppLaunchInfo>(
+          kAppId, kId, apps::mojom::LaunchContainer::kLaunchContainerWindow,
+          WindowOpenDisposition::NEW_WINDOW, display::kDefaultDisplayId,
+          std::vector<base::FilePath>{}, nullptr));
+
+  WaitForAppLaunchInfoSaved();
+
+  // Create AppLaunchHandler.
+  auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
+
+  app_launch_handler->LauncherBrowserWhenReady();
+  content::RunAllTasksUntilIdle();
+
+  CreateWebApp();
+  content::RunAllTasksUntilIdle();
+
+  // Set should restore
+  app_launch_handler->SetShouldRestore();
+  content::RunAllTasksUntilIdle();
+
+  // Verify there is new browser launched.
+  EXPECT_EQ(count + 2, BrowserList::GetInstance()->size());
+  EXPECT_TRUE(FindWebAppWindow());
+}
+
+}  // namespace full_restore
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc b/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc
index fcf1536..af366fd3 100644
--- a/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc
+++ b/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc
@@ -67,6 +67,8 @@
 
 namespace {
 
+const test::UIPath kDemoSetupDialog = {"demo-setup", "demoSetupProgressDialog"};
+
 constexpr char kDefaultNetworkServicePath[] = "/service/eth1";
 constexpr char kDefaultNetworkName[] = "eth1";
 
@@ -1247,49 +1249,24 @@
 
 class DemoSetupProgressStepsTest : public DemoSetupTestBase {
  public:
-  DemoSetupProgressStepsTest() {
-    scoped_feature_list_.InitAndEnableFeature(
-        features::kShowStepsInDemoModeSetup);
-  }
+  DemoSetupProgressStepsTest() = default;
   ~DemoSetupProgressStepsTest() override = default;
 
   // Checks how many steps have been rendered in the demo setup screen.
   int CountNumberOfStepsInUi() {
     const std::string query =
-        "$('demo-setup').$$('oobe-dialog').querySelectorAll('progress-"
-        "list-item').length";
-
+        base::StrCat({test::GetOobeElementPath(kDemoSetupDialog),
+                      ".querySelectorAll('progress-list-item').length"});
     return test::OobeJS().GetInt(query);
   }
 
-  // Checks how many steps are marked as pending in the demo setup screen.
-  int CountPendingStepsInUi() {
-    const std::string query =
-        "Object.values($('demo-setup').$$('oobe-dialog')."
-        "querySelectorAll('progress-list-item')).filter(node => "
-        "node.shadowRoot.querySelector('#icon-pending:not([hidden])')).length";
-
-    return test::OobeJS().GetInt(query);
-  }
-
-  // Checks how many steps are marked as active in the demo setup screen.
-  int CountActiveStepsInUi() {
-    const std::string query =
-        "Object.values($('demo-setup').$$('oobe-dialog')."
-        "querySelectorAll('progress-list-item')).filter(node => "
-        "node.shadowRoot.querySelector('#icon-active:not([hidden])')).length";
-
-    return test::OobeJS().GetInt(query);
-  }
-
-  // Checks how many steps are marked as complete in the demo setup screen.
-  int CountCompletedStepsInUi() {
-    const std::string query =
-        "Object.values($('demo-setup').$$('oobe-dialog')."
-        "querySelectorAll('progress-list-item')).filter(node => "
-        "node.shadowRoot.querySelector('#icon-completed:not([hidden])'))."
-        "length";
-
+  // Checks how many steps are marked as given status in the demo setup screen.
+  int CountStepsInUi(const std::string& status) {
+    const std::string query = base::StrCat(
+        {"Object.values(", test::GetOobeElementPath(kDemoSetupDialog),
+         ".querySelectorAll('progress-list-item')).filter(node => "
+         "node.shadowRoot.querySelector('#icon-",
+         status, ":not([hidden])')).length"});
     return test::OobeJS().GetInt(query);
   }
 
@@ -1320,9 +1297,9 @@
 
   for (int i = 0; i < numSteps; i++) {
     demoSetupScreen->SetCurrentSetupStepForTest(orderedSteps[i]);
-    ASSERT_EQ(CountPendingStepsInUi(), numSteps - i - 1);
-    ASSERT_EQ(CountActiveStepsInUi(), 1);
-    ASSERT_EQ(CountCompletedStepsInUi(), i);
+    ASSERT_EQ(CountStepsInUi("pending"), numSteps - i - 1);
+    ASSERT_EQ(CountStepsInUi("active"), 1);
+    ASSERT_EQ(CountStepsInUi("completed"), i);
   }
 }
 
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index ffc0667..365f420 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -1928,10 +1928,11 @@
 void WizardController::OnAccessibilityStatusChanged(
     const AccessibilityStatusEventDetails& details) {
   enum AccessibilityNotificationType type = details.notification_type;
-  if (type == ACCESSIBILITY_MANAGER_SHUTDOWN) {
+  if (type == AccessibilityNotificationType::kManagerShutdown) {
     accessibility_subscription_ = {};
     return;
-  } else if (type != ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK || !details.enabled) {
+  } else if (type != AccessibilityNotificationType::kToggleSpokenFeedback ||
+             !details.enabled) {
     return;
   }
 
diff --git a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc
index 1bc3858..4cc8404f 100644
--- a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc
+++ b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc
@@ -19,6 +19,7 @@
 const char kOsSettingsFeature[] = "os_settings";
 const char kScanningFeature[] = "scanning";
 const char kWebStoreFeature[] = "web_store";
+const char kCanvasFeature[] = "canvas";
 
 const char kBlockedDisableMode[] = "blocked";
 const char kHiddenDisableMode[] = "hidden";
@@ -81,6 +82,8 @@
     return SystemFeature::kScanning;
   if (system_feature == kWebStoreFeature)
     return SystemFeature::kWebStore;
+  if (system_feature == kCanvasFeature)
+    return SystemFeature::kCanvas;
 
   LOG(ERROR) << "Unsupported system feature: " << system_feature;
   return kUnknownSystemFeature;
diff --git a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h
index 8708af2..36d15ef 100644
--- a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h
+++ b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h
@@ -25,7 +25,8 @@
   kOsSettings = 3,       // The settings feature on Chrome OS.
   kScanning = 4,         // The scan SWA on Chrome OS.
   kWebStore = 5,         // The web store chrome app on Chrome OS.
-  kMaxValue = kWebStore
+  kCanvas = 6,           // The canvas web app on Chrome OS.
+  kMaxValue = kCanvas
 };
 
 // A disabling mode that decides the user experience when a system feature is
@@ -42,6 +43,7 @@
 extern const char kOsSettingsFeature[];
 extern const char kScanningFeature[];
 extern const char kWebStoreFeature[];
+extern const char kCanvasFeature[];
 
 extern const char kBlockedDisableMode[];
 extern const char kHiddenDisableMode[];
diff --git a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc
index 970e308b..1ae2f96 100644
--- a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc
+++ b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc
@@ -70,6 +70,9 @@
   histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram,
                                       SystemFeature::kWebStore,
                                       /*amount*/ 0);
+  histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram,
+                                      SystemFeature::kCanvas,
+                                      /*amount*/ 0);
 
   features_list.ClearList();
   features_list.Append("camera");
@@ -77,6 +80,7 @@
   features_list.Append("scanning");
   features_list.Append("gallery");
   features_list.Append("web_store");
+  features_list.Append("canvas");
 
   policy_map.Set(policy::key::kSystemFeaturesDisableList,
                  policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
@@ -93,11 +97,12 @@
   expected_list.Append(SystemFeature::kScanning);
   expected_list.Append(SystemFeature::kUnknownSystemFeature);
   expected_list.Append(SystemFeature::kWebStore);
+  expected_list.Append(SystemFeature::kCanvas);
 
   EXPECT_TRUE(prefs.GetValue(policy_prefs::kSystemFeaturesDisableList, &value));
   EXPECT_EQ(expected_list, *value);
 
-  histogram_tester_.ExpectTotalCount(kSystemFeaturesDisableListHistogram, 6);
+  histogram_tester_.ExpectTotalCount(kSystemFeaturesDisableListHistogram, 7);
   histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram,
                                       SystemFeature::kCamera,
                                       /*amount*/ 1);
@@ -116,5 +121,8 @@
   histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram,
                                       SystemFeature::kWebStore,
                                       /*amount*/ 1);
+  histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram,
+                                      SystemFeature::kCanvas,
+                                      /*amount*/ 1);
 }
 }  // namespace policy
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 9121a8b..319464e 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2898,11 +2898,6 @@
     "expiry_milestone": 93
   },
   {
-    "name": "guest-os-external-protocol",
-    "owners": [ "joelhockey", "crostini-syd" ],
-    "expiry_milestone": 93
-  },
-  {
     "name": "h264-decoder-is-buffer-complete-frame",
     "owners": [ "jkardatzke", "mcasas" ],
     "expiry_milestone": 89
@@ -4145,7 +4140,7 @@
   },
   {
     "name": "record-snapshot-size",
-    "owners": ["eugenebut","bling-flags@google.com"],
+    "owners": ["edchin","bling-flags@google.com"],
     "expiry_milestone": 91
   },
   {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index ee7b955..06b0fc8 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -770,10 +770,6 @@
 const char kEnableGpuServiceLoggingDescription[] =
     "Enable printing the actual GL driver calls.";
 
-const char kGuestOsExternalProtocolName[] = "Guest OS External Protocol";
-const char kGuestOsExternalProtocolDescription[] =
-    "Enable Guest OS external protocol handlers";
-
 const char kEnablePreviewsCoinFlipName[] = "Enable Previews Coin Flip";
 const char kEnablePreviewsCoinFlipDescription[] =
     "Enable coin flip experimentation of Previews.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index b9e13c70..4b32da3 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -720,9 +720,6 @@
 extern const char kGpuRasterizationName[];
 extern const char kGpuRasterizationDescription[];
 
-extern const char kGuestOsExternalProtocolName[];
-extern const char kGuestOsExternalProtocolDescription[];
-
 extern const char kH264DecoderBufferIsCompleteFrameName[];
 extern const char kH264DecoderBufferIsCompleteFrameDescription[];
 
diff --git a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
index f1da695..3040123 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
+++ b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
@@ -75,10 +75,12 @@
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/js:assert.m",
   ]
+  externs_list = [ "$externs_path/chrome_send.js" ]
 }
 
 js_library("emoji_group") {
   deps = [
+    ":events",
     ":types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
   ]
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html
index 5216797..506643e 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html
+++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html
@@ -19,7 +19,7 @@
   <div class="emoji-group-heading">[[data.group]]</div>
   <div class="emoji-group-emoji">
     <template is="dom-repeat" items="[[data.emoji]]">
-      <div class$="[[_className(item.alternates)]]">
+      <div class$="[[_className(item.alternates)]]" on-click="onClickEmoji">
         [[_renderEmoji(item.base)]]
       </div>
     </template>
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js
index a80cbea..367fc18 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js
+++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js
@@ -4,6 +4,7 @@
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {EMOJI_BUTTON_EVENT, EmojiButtonEvent} from './events.js';
 import {EmojiGroup} from './types.js';
 
 class EmojiGroupComponent extends PolymerElement {
@@ -26,6 +27,16 @@
     super();
   }
 
+  onClickEmoji(ev) {
+    /** @type {EmojiButtonEvent} */
+    const event = new CustomEvent(EMOJI_BUTTON_EVENT, {
+      bubbles: true,
+      composed: true,
+      detail: {emoji: ev.path[0].textContent.trim()}
+    });
+    this.dispatchEvent(event);
+  }
+
   _renderEmoji(codepoints) {
     return String.fromCodePoint(...codepoints);
   }
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js
index c0ff15c..dd683671 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js
+++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js
@@ -9,7 +9,7 @@
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {GROUP_BUTTON_EVENT} from './events.js';
+import {EMOJI_BUTTON_EVENT, GROUP_BUTTON_EVENT} from './events.js';
 import {EmojiData, EmojiGroup} from './types.js';
 
 const EMOJI_ORDERING_JSON = '/emoji_13_1_ordering.json';
@@ -80,6 +80,8 @@
 
     this.addEventListener(
         GROUP_BUTTON_EVENT, ev => this.selectGroup(ev.detail.group));
+    this.addEventListener(
+        EMOJI_BUTTON_EVENT, ev => this.insertEmoji(ev.detail.emoji));
   }
 
   /**
@@ -101,6 +103,13 @@
         .scrollIntoView();
   }
 
+  /**
+   * @param {string} emoji
+   */
+  insertEmoji(emoji) {
+    chrome.send('insertEmoji', [emoji]);
+  }
+
   _formatEmojiData(emojiData) {
     return JSON.stringify(emojiData);
   }
diff --git a/chrome/browser/resources/chromeos/login/demo_setup.css b/chrome/browser/resources/chromeos/login/demo_setup.css
deleted file mode 100644
index f22fd0bc..0000000
--- a/chrome/browser/resources/chromeos/login/demo_setup.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright 2018 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. */
-
-/* Spinner shown on progress dialog. */
-paper-spinner-lite#spinner {
-  height: 164px;
-  width: 164px;
-}
diff --git a/chrome/browser/resources/chromeos/login/demo_setup.html b/chrome/browser/resources/chromeos/login/demo_setup.html
index b99a1aa..ce9fd95 100644
--- a/chrome/browser/resources/chromeos/login/demo_setup.html
+++ b/chrome/browser/resources/chromeos/login/demo_setup.html
@@ -1,26 +1,22 @@
 <link rel="import" href="/components/common_styles.html">
 <link rel="import" href="/components/hd_iron_icon.html">
-<link rel="import" href="/components/oobe_dialog.html">
+<link rel="import" href="/components/oobe_adaptive_dialog.html">
 <link rel="import" href="/components/oobe_i18n_behavior.html">
 <link rel="import" href="/components/progress_list_item.html">
 
 <dom-module id="demo-setup-element">
   <template>
     <style include="oobe-dialog-host"></style>
-    <link rel="stylesheet" href="demo_setup.css">
-
-    <oobe-dialog id="demoSetupProgressDialog" role="dialog" has-buttons
-      title-key="demoSetupProgressScreenTitle" for-step="progress">
-      <hd-iron-icon slot="oobe-icon"
+    <oobe-adaptive-dialog id="demoSetupProgressDialog" role="dialog"
+      aria-label$="[[i18nDynamic(locale, 'demoSetupProgressScreenTitle')]]"
+      for-step="progress">
+      <hd-iron-icon slot="icon"
           icon1x="oobe-32:computer" icon2x="oobe-64:computer">
       </hd-iron-icon>
-      <div slot="footer"
-          class="flex layout vertical center center-justified"
-          hidden$="[[showStepsInDemoModeSetup_]]">
-        <paper-spinner-lite id="spinner" dir="ltr"
-            active></paper-spinner-lite>
-      </div>
-      <div slot="footer" hidden$="[[!showStepsInDemoModeSetup_]]">
+      <h1 slot="title">
+        [[i18nDynamic(locale, 'demoSetupProgressScreenTitle')]]
+      </h1>
+      <div slot="content">
         <div id="demo-setup-steps" role="list">
           <progress-list-item text-key="demoSetupProgressStepDownload"
               hidden="[[!shouldShowStep_('downloadResources', setupSteps_)]]"
@@ -38,16 +34,19 @@
           </progress-list-item>
         </div>
       </div>
-    </oobe-dialog>
+    </oobe-adaptive-dialog>
 
-    <oobe-dialog id="demoSetupErrorDialog" role="dialog" has-buttons
+    <oobe-adaptive-dialog id="demoSetupErrorDialog" role="dialog"
         aria-label$="[[i18nDynamic(locale, 'demoSetupErrorScreenTitle')]]"
-        title-key="demoSetupErrorScreenTitle" for-step="error">
-      <hd-iron-icon slot="oobe-icon"
+        for-step="error">
+      <hd-iron-icon slot="icon"
           icon1x="oobe-32:computer" icon2x="oobe-64:computer">
       </hd-iron-icon>
+      <h1 slot="title">
+        [[i18nDynamic(locale, 'demoSetupErrorScreenTitle')]]
+      </h1>
       <div slot="subtitle">[[errorMessage_]]</div>
-      <div slot="footer" class="flex layout vertical center center-justified">
+      <div slot="content" class="flex layout vertical center center-justified">
         <img srcset="images/alert-illustration_1x.svg 1x,
             images/alert-illustration_2x.svg 2x">
       </div>
@@ -56,16 +55,15 @@
             disabled="[[isPowerwashRequired_]]"></oobe-back-button>
       </div>
       <div slot="bottom-buttons">
-        <oobe-text-button id="retryButton" on-click="onRetryClicked_"
+        <oobe-text-button id="retryButton" class="focus-on-show" inverse
             text-key="demoSetupErrorScreenRetryButtonLabel"
-            inverse hidden="[[isPowerwashRequired_]]">
+            on-click="onRetryClicked_" hidden="[[isPowerwashRequired_]]">
         </oobe-text-button>
-        <oobe-text-button id="powerwashButton" on-click="onPowerwashClicked_"
+        <oobe-text-button id="powerwashButton" class="focus-on-show" inverse
             text-key="demoSetupErrorScreenPowerwashButtonLabel"
-            inverse hidden="[[!isPowerwashRequired_]]">
+            on-click="onPowerwashClicked_" hidden="[[!isPowerwashRequired_]]">
         </oobe-text-button>
       </div>
-    </oobe-dialog>
-
+    </oobe-adaptive-dialog>
   </template>
 </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/demo_setup.js b/chrome/browser/resources/chromeos/login/demo_setup.js
index 302f5c5..23297787 100644
--- a/chrome/browser/resources/chromeos/login/demo_setup.js
+++ b/chrome/browser/resources/chromeos/login/demo_setup.js
@@ -58,15 +58,6 @@
       type: Boolean,
       value: false,
     },
-
-    /** Feature flag to display progress bar instead of spinner during setup. */
-    showStepsInDemoModeSetup_: {
-      type: Boolean,
-      readonly: true,
-      value() {
-        return loadTimeData.getBoolean('showStepsInDemoModeSetup');
-      }
-    }
   },
 
   defaultUIStep() {
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc b/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc
index e4cdf51..cc8cca3 100644
--- a/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc
+++ b/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc
@@ -228,11 +228,12 @@
 
 void TtsEngineExtensionObserverChromeOS::OnAccessibilityStatusChanged(
     const chromeos::AccessibilityStatusEventDetails& details) {
-  if (details.notification_type != chromeos::AccessibilityNotificationType::
-                                       ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK &&
-      details.notification_type != chromeos::AccessibilityNotificationType::
-                                       ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK)
+  if (details.notification_type !=
+          chromeos::AccessibilityNotificationType::kToggleSpokenFeedback &&
+      details.notification_type !=
+          chromeos::AccessibilityNotificationType::kToggleSelectToSpeak) {
     return;
+  }
 
   // Google speech synthesis might not be loaded yet. If it isn't, the call in
   // |OnExtensionLoaded| will do the increment. If it is, the call below will
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 58d53c6a..4d85eba 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2050,8 +2050,12 @@
       "ash/session_util.h",
       "ash/sharesheet/sharesheet_bubble_view.cc",
       "ash/sharesheet/sharesheet_bubble_view.h",
+      "ash/sharesheet/sharesheet_content_previews.cc",
+      "ash/sharesheet/sharesheet_content_previews.h",
       "ash/sharesheet/sharesheet_expand_button.cc",
       "ash/sharesheet/sharesheet_expand_button.h",
+      "ash/sharesheet/sharesheet_image_decode.cc",
+      "ash/sharesheet/sharesheet_image_decode.h",
       "ash/sharesheet/sharesheet_target_button.cc",
       "ash/sharesheet/sharesheet_target_button.h",
       "ash/system_tray_client.cc",
@@ -2227,6 +2231,8 @@
       "webui/chromeos/edu_coexistence_state_tracker.h",
       "webui/chromeos/emoji/emoji_dialog.cc",
       "webui/chromeos/emoji/emoji_dialog.h",
+      "webui/chromeos/emoji/emoji_handler.cc",
+      "webui/chromeos/emoji/emoji_handler.h",
       "webui/chromeos/emoji/emoji_picker.cc",
       "webui/chromeos/emoji/emoji_picker.h",
       "webui/chromeos/image_source.cc",
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc
index 601942b6e..32a7a16 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc
@@ -25,19 +25,11 @@
 
 FakePredictor::FakePredictor(const std::string& model_identifier)
     : RecurrencePredictor(model_identifier) {
-  // The fake predictor should only be used for testing, not in production.
-  // Record an error so we know if it is being used.
-  LogInitializationStatus(model_identifier_,
-                          InitializationStatus::kFakePredictorUsed);
 }
 
 FakePredictor::FakePredictor(const FakePredictorConfig& config,
                              const std::string& model_identifier)
     : RecurrencePredictor(model_identifier) {
-  // The fake predictor should only be used for testing, not in production.
-  // Record an error so we know if it is being used.
-  LogInitializationStatus(model_identifier_,
-                          InitializationStatus::kFakePredictorUsed);
 }
 
 FakePredictor::~FakePredictor() = default;
@@ -75,8 +67,6 @@
 
 void FakePredictor::FromProto(const RecurrencePredictorProto& proto) {
   if (!proto.has_fake_predictor()) {
-    LogSerializationStatus(model_identifier_,
-                           SerializationStatus::kFakePredictorLoadingError);
     return;
   }
 
@@ -212,9 +202,6 @@
 void ConditionalFrequencyPredictor::FromProto(
     const RecurrencePredictorProto& proto) {
   if (!proto.has_conditional_frequency_predictor()) {
-    LogSerializationStatus(
-        model_identifier_,
-        SerializationStatus::kConditionalFrequencyPredictorLoadingError);
     return;
   }
 
@@ -287,8 +274,6 @@
 
 void FrecencyPredictor::FromProto(const RecurrencePredictorProto& proto) {
   if (!proto.has_frecency_predictor()) {
-    LogSerializationStatus(model_identifier_,
-                           SerializationStatus::kFrecencyPredictorLoadingError);
     return;
   }
   const auto& predictor = proto.frecency_predictor();
@@ -396,8 +381,6 @@
 
 void HourBinPredictor::FromProto(const RecurrencePredictorProto& proto) {
   if (!proto.has_hour_bin_predictor()) {
-    LogSerializationStatus(model_identifier_,
-                           SerializationStatus::kHourBinPredictorLoadingError);
     return;
   }
 
@@ -479,8 +462,6 @@
 
 void MarkovPredictor::FromProto(const RecurrencePredictorProto& proto) {
   if (!proto.has_markov_predictor()) {
-    LogSerializationStatus(model_identifier_,
-                           SerializationStatus::kMarkovPredictorLoadingError);
     return;
   }
 
@@ -571,9 +552,6 @@
 void ExponentialWeightsEnsemble::FromProto(
     const RecurrencePredictorProto& proto) {
   if (!proto.has_exponential_weights_ensemble()) {
-    LogSerializationStatus(
-        model_identifier_,
-        SerializationStatus::kExponentialWeightsEnsembleLoadingError);
     return;
   }
   const auto& ensemble = proto.exponential_weights_ensemble();
@@ -637,9 +615,6 @@
 
 void FrequencyPredictor::FromProto(const RecurrencePredictorProto& proto) {
   if (!proto.has_frequency_predictor()) {
-    LogSerializationStatus(
-        model_identifier_,
-        SerializationStatus::kFrequencyPredictorLoadingError);
     return;
   }
 
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc
index f7ccd64..5f8042b 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc
@@ -44,8 +44,6 @@
                      const RecurrenceRankerProto& proto) {
   std::string proto_str;
   if (!proto.SerializeToString(&proto_str)) {
-    LogSerializationStatus(model_identifier,
-                           SerializationStatus::kToProtoError);
     return;
   }
 
@@ -57,12 +55,8 @@
         filepath, proto_str, "RecurrenceRanker");
   }
   if (!write_result) {
-    LogSerializationStatus(model_identifier,
-                           SerializationStatus::kModelWriteError);
     return;
   }
-
-  LogSerializationStatus(model_identifier, SerializationStatus::kSaveOk);
 }
 
 // Try to load a |RecurrenceRankerProto| from the given filepath. If it fails,
@@ -74,19 +68,14 @@
                                                 base::BlockingType::MAY_BLOCK);
   std::string proto_str;
   if (!base::ReadFileToString(filepath, &proto_str)) {
-    LogSerializationStatus(model_identifier,
-                           SerializationStatus::kModelReadError);
     return nullptr;
   }
 
   auto proto = std::make_unique<RecurrenceRankerProto>();
   if (!proto->ParseFromString(proto_str)) {
-    LogSerializationStatus(model_identifier,
-                           SerializationStatus::kFromProtoError);
     return nullptr;
   }
 
-  LogSerializationStatus(model_identifier, SerializationStatus::kLoadOk);
   return proto;
 }
 
@@ -179,8 +168,6 @@
     // Ephemeral users have no persistent storage, so we don't try and load the
     // proto from disk. Instead, we fall back on using a default (frecency)
     // predictor, which is still useful with only data from the current session.
-    LogInitializationStatus(model_identifier_,
-                            InitializationStatus::kEphemeralUser);
     predictor_ = std::make_unique<DefaultPredictor>(
         RecurrencePredictorConfigProto::DefaultPredictorConfig(),
         model_identifier_);
@@ -203,8 +190,6 @@
     std::unique_ptr<RecurrenceRankerProto> proto) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   load_from_disk_completed_ = true;
-  LogInitializationStatus(model_identifier_,
-                          InitializationStatus::kInitialized);
 
   // If OnLoadFromDisk returned nullptr, no saved ranker proto was available on
   // disk, and there is nothing to load. Save a blank ranker to prevent metrics
@@ -221,28 +206,17 @@
     // clean slate. This is not always an error: it is expected if, for example,
     // a RecurrenceRanker instance is rolled out in one release, and then
     // reconfigured in the next.
-    LogInitializationStatus(model_identifier_,
-                            InitializationStatus::kHashMismatch);
     return;
   }
 
   if (proto->has_predictor())
     predictor_->FromProto(proto->predictor());
-  else
-    LogSerializationStatus(model_identifier_,
-                           SerializationStatus::kPredictorMissingError);
 
   if (proto->has_targets())
     targets_->FromProto(proto->targets());
-  else
-    LogSerializationStatus(model_identifier_,
-                           SerializationStatus::kTargetsMissingError);
 
   if (proto->has_conditions())
     conditions_->FromProto(proto->conditions());
-  else
-    LogSerializationStatus(model_identifier_,
-                           SerializationStatus::kConditionsMissingError);
 }
 
 void RecurrenceRanker::Record(const std::string& target,
@@ -250,7 +224,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!load_from_disk_completed_)
     return;
-  LogUsage(model_identifier_, Usage::kRecord);
 
   predictor_->Train(targets_->Update(target), conditions_->Update(condition));
   MaybeSave();
@@ -261,7 +234,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!load_from_disk_completed_)
     return;
-  LogUsage(model_identifier_, Usage::kRenameTarget);
 
   targets_->Rename(target, new_target);
   MaybeSave();
@@ -273,7 +245,6 @@
   // loading is complete, resulting in the remove getting dropped.
   if (!load_from_disk_completed_)
     return;
-  LogUsage(model_identifier_, Usage::kRemoveTarget);
 
   targets_->Remove(target);
   MaybeSave();
@@ -284,7 +255,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!load_from_disk_completed_)
     return;
-  LogUsage(model_identifier_, Usage::kRenameCondition);
 
   conditions_->Rename(condition, new_condition);
   MaybeSave();
@@ -294,7 +264,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!load_from_disk_completed_)
     return;
-  LogUsage(model_identifier_, Usage::kRemoveCondition);
 
   conditions_->Remove(condition);
   MaybeSave();
@@ -305,7 +274,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!load_from_disk_completed_)
     return {};
-  LogUsage(model_identifier_, Usage::kRank);
+
   // Special case the default predictor, and return the scores from the target
   // frecency store.
   if (predictor_->GetPredictorName() == DefaultPredictor::kPredictorName)
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc
index eb0d4ce..daa51a3b 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/hash/hash.h"
-#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h"
@@ -132,60 +131,11 @@
     return proto;
   }
 
-  void ExpectErrors(bool fresh_model_created = true,
-                    bool using_fake_predictor = true,
-                    bool has_saved = false) {
-    // Total count of serialization reports:
-    //  - one for either a kLoadOk or kModelReadError
-    //  - one if |fresh_model_created| because model is written to disk with a
-    //    kSaveOk on initialization.
-    //  - one if |has_saved| because model is again written to disk with a
-    //    kSaveOk.
-    histogram_tester_.ExpectTotalCount(
-        "RecurrenceRanker.SerializationStatus.MyModel",
-        1 + static_cast<int>(has_saved) +
-            static_cast<int>(fresh_model_created));
-
-    // If a model doesn't already exist, a read error is logged.
-    if (fresh_model_created) {
-      histogram_tester_.ExpectBucketCount(
-          "RecurrenceRanker.SerializationStatus.MyModel",
-          SerializationStatus::kModelReadError, 1);
-    } else {
-      histogram_tester_.ExpectBucketCount(
-          "RecurrenceRanker.SerializationStatus.MyModel",
-          SerializationStatus::kLoadOk, 1);
-    }
-
-    histogram_tester_.ExpectBucketCount(
-        "RecurrenceRanker.SerializationStatus.MyModel",
-        SerializationStatus::kSaveOk,
-        static_cast<int>(has_saved) + static_cast<int>(fresh_model_created));
-
-    // Initialising with the fake predictor logs an UMA error, because it should
-    // be used only in tests and not in production.
-    if (using_fake_predictor) {
-      histogram_tester_.ExpectTotalCount(
-          "RecurrenceRanker.InitializationStatus.MyModel", 2);
-      histogram_tester_.ExpectBucketCount(
-          "RecurrenceRanker.InitializationStatus.MyModel",
-          InitializationStatus::kFakePredictorUsed, 1);
-      histogram_tester_.ExpectBucketCount(
-          "RecurrenceRanker.InitializationStatus.MyModel",
-          InitializationStatus::kInitialized, 1);
-    } else {
-      histogram_tester_.ExpectUniqueSample(
-          "RecurrenceRanker.InitializationStatus.MyModel",
-          InitializationStatus::kInitialized, 1);
-    }
-  }
-
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::MainThreadType::DEFAULT,
       base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED};
   base::ScopedTempDir temp_dir_;
   base::test::ScopedFeatureList scoped_feature_list_;
-  base::HistogramTester histogram_tester_;
 
   base::FilePath ranker_filepath_;
 };
@@ -199,8 +149,6 @@
 
   EXPECT_THAT(ranker->Rank(), UnorderedElementsAre(Pair("A", FloatEq(1.0f)),
                                                    Pair("B", FloatEq(2.0f))));
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, RenameTarget) {
@@ -212,8 +160,6 @@
   ranker->RenameTarget("B", "A");
 
   EXPECT_THAT(ranker->Rank(), ElementsAre(Pair("A", FloatEq(2.0f))));
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, RemoveTarget) {
@@ -225,8 +171,6 @@
   ranker->RemoveTarget("A");
 
   EXPECT_THAT(ranker->Rank(), ElementsAre(Pair("B", FloatEq(2.0f))));
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, ComplexRecordAndRank) {
@@ -246,8 +190,6 @@
   EXPECT_THAT(ranker->Rank(), UnorderedElementsAre(Pair("A", FloatEq(1.0f)),
                                                    Pair("B", FloatEq(2.0f)),
                                                    Pair("F", FloatEq(1.0f))));
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, RankTopN) {
@@ -263,8 +205,6 @@
   EXPECT_THAT(ranker->RankTopN(100),
               ElementsAre(Pair("A", FloatEq(4.0f)), Pair("B", FloatEq(3.0f)),
                           Pair("C", FloatEq(2.0f)), Pair("D", FloatEq(1.0f))));
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, Empty) {
@@ -294,8 +234,6 @@
   EXPECT_THAT(ranker.Rank(), UnorderedElementsAre(Pair("A", FloatEq(1.0f)),
                                                   Pair("B", FloatEq(2.0f)),
                                                   Pair("C", FloatEq(1.0f))));
-  ExpectErrors(/* fresh_model_created = */ false,
-               /* using_fake_predictor = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, InitializeIfNoFileExists) {
@@ -310,9 +248,6 @@
 
   EXPECT_TRUE(ranker.load_from_disk_completed_);
   EXPECT_TRUE(ranker.Rank().empty());
-
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, SaveToDisk) {
@@ -344,10 +279,6 @@
 
   // Expect the content to be proto_.
   EXPECT_TRUE(EquivToProtoLite(proto_written, MakeTestingProto()));
-
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ true,
-               /* has_saved = */ true);
 }
 
 TEST_F(RecurrenceRankerTest, SavedRankerRejectedIfConfigMismatched) {
@@ -374,10 +305,6 @@
   EXPECT_TRUE(other_ranker.Rank().empty());
   // For comparison:
   EXPECT_THAT(ranker->Rank(), UnorderedElementsAre(Pair("A", FloatEq(1.0f))));
-  // Should also log an error to UMA.
-  histogram_tester_.ExpectBucketCount(
-      "RecurrenceRanker.InitializationStatus.MyModel",
-      InitializationStatus::kHashMismatch, 1);
 }
 
 TEST_F(RecurrenceRankerTest, Cleanup) {
@@ -422,9 +349,6 @@
   Wait();
   EXPECT_THAT(ephemeral_ranker.GetPredictorNameForTesting(),
               StrEq(DefaultPredictor::kPredictorName));
-  histogram_tester_.ExpectBucketCount(
-      "RecurrenceRanker.InitializationStatus.MyModel",
-      InitializationStatus::kEphemeralUser, 1);
 }
 
 TEST_F(RecurrenceRankerTest, IntegrationWithDefaultPredictor) {
@@ -443,8 +367,6 @@
   EXPECT_THAT(ranker.Rank(), UnorderedElementsAre(Pair("A", FloatEq(0.2304f)),
                                                   Pair("B", FloatEq(0.16f)),
                                                   Pair("C", FloatEq(0.2f))));
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ false);
 }
 
 TEST_F(RecurrenceRankerTest, IntegrationWithZeroStateFrecencyPredictor) {
@@ -471,8 +393,6 @@
               UnorderedElementsAre(Pair("A", FloatEq(0.09375f / total)),
                                    Pair("B", FloatEq(0.125f / total)),
                                    Pair("C", FloatEq(0.25f / total))));
-  ExpectErrors(/* fresh_model_created = */ true,
-               /* using_fake_predictor = */ false);
 }
 
 }  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc
index ba6f8357..f8475b7 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util.cc
@@ -222,8 +222,6 @@
     return std::make_unique<ExponentialWeightsEnsemble>(
         config.exponential_weights_ensemble(), model_identifier);
 
-  LogInitializationStatus(model_identifier,
-                          InitializationStatus::kInvalidConfigPredictor);
   NOTREACHED();
   return nullptr;
 }
@@ -257,12 +255,8 @@
     data_decoder::DataDecoder::ValueOrError result) {
   RecurrenceRankerConfigProto proto;
   if (result.value && ConvertRecurrenceRanker(&result.value.value(), &proto)) {
-    LogJsonConfigConversionStatus(model_identifier,
-                                  JsonConfigConversionStatus::kSuccess);
     std::move(callback).Run(std::move(proto));
   } else {
-    LogJsonConfigConversionStatus(model_identifier,
-                                  JsonConfigConversionStatus::kFailure);
     std::move(callback).Run(base::nullopt);
   }
 }
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
index c50ce2b..8e3bd56 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sharesheet/sharesheet_metrics.h"
 #include "chrome/browser/sharesheet/sharesheet_service_delegate.h"
+#include "chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.h"
 #include "chrome/browser/ui/ash/sharesheet/sharesheet_expand_button.h"
 #include "chrome/browser/ui/ash/sharesheet/sharesheet_target_button.h"
 #include "chrome/common/chrome_features.h"
@@ -183,6 +184,9 @@
     file_title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
     file_title->SetProperty(views::kMarginsKey,
                             gfx::Insets(3, kSpacing, kSpacing, kSpacing));
+
+    main_view_->AddChildView(
+        std::make_unique<SharesheetContentPreviews>(intent_->Clone()));
   }
 
   if (targets.empty()) {
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.cc
new file mode 100644
index 0000000..9ae9f4a7
--- /dev/null
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.cc
@@ -0,0 +1,28 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.h"
+
+#include <utility>
+
+SharesheetContentPreviews::SharesheetContentPreviews(
+    apps::mojom::IntentPtr intent) {
+  intent_ = std::move(intent);
+}
+
+SharesheetContentPreviews::~SharesheetContentPreviews() = default;
+
+void SharesheetContentPreviews::SetTitlePreview() {
+  // TODO(crbug.com/2631548): Add code to add a new
+  // label view to reflect file name to the
+  // content previews view.
+  NOTIMPLEMENTED();
+}
+
+void SharesheetContentPreviews::SetImagePreview() {
+  // TODO(crbug.com/2631548): Add code to add a new
+  // image view to show image preview to the
+  // content previews view.
+  NOTIMPLEMENTED();
+}
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.h b/chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.h
new file mode 100644
index 0000000..f6cc221
--- /dev/null
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_content_previews.h
@@ -0,0 +1,31 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_ASH_SHARESHEET_SHARESHEET_CONTENT_PREVIEWS_H_
+#define CHROME_BROWSER_UI_ASH_SHARESHEET_SHARESHEET_CONTENT_PREVIEWS_H_
+
+#include "components/services/app_service/public/mojom/types.mojom.h"
+#include "ui/views/view.h"
+
+// The SharesheetContentPreviews class is the view for the image
+// previews feature.
+class SharesheetContentPreviews : public views::View {
+ public:
+  explicit SharesheetContentPreviews(apps::mojom::IntentPtr intent);
+  ~SharesheetContentPreviews() override;
+  SharesheetContentPreviews(const SharesheetContentPreviews&) = delete;
+  SharesheetContentPreviews& operator=(const SharesheetContentPreviews&) =
+      delete;
+
+ private:
+  // Adds the title preview to the view.
+  void SetTitlePreview();
+
+  // Adds the image preview to the view.
+  void SetImagePreview();
+
+  apps::mojom::IntentPtr intent_;
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_SHARESHEET_SHARESHEET_CONTENT_PREVIEWS_H_
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_image_decode.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_image_decode.cc
new file mode 100644
index 0000000..2194e8b
--- /dev/null
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_image_decode.cc
@@ -0,0 +1,26 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/ash/sharesheet/sharesheet_image_decode.h"
+
+SharesheetImageDecode::SharesheetImageDecode() = default;
+
+void SharesheetImageDecode::URLToEncodedBytes(const base::FilePath& url) {
+  // TODO(crbug.com/2631548): Add code to encode the url by adding
+  // a new task to the main thread, use FileToString() function and
+  // pass the result into DecodeURLForPreview.
+  NOTIMPLEMENTED();
+}
+
+void SharesheetImageDecode::DecodeURLForPreview(std::string image_data) {
+  // TODO(crbug.com/2631548): Run sandboxed process using
+  // DecodeImageIsolated and pass result into BitMapToImage.
+  NOTIMPLEMENTED();
+}
+
+void SharesheetImageDecode::BitMapToImage(const SkBitmap& decoded_image) {
+  // TODO(crbug.com/2631548): Use CreateFrom1xBitmap function to convert
+  // encoded bitmap into type imageskia and add to content previews view.
+  NOTIMPLEMENTED();
+}
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_image_decode.h b/chrome/browser/ui/ash/sharesheet/sharesheet_image_decode.h
new file mode 100644
index 0000000..0caebbe
--- /dev/null
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_image_decode.h
@@ -0,0 +1,32 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_ASH_SHARESHEET_SHARESHEET_IMAGE_DECODE_H_
+#define CHROME_BROWSER_UI_ASH_SHARESHEET_SHARESHEET_IMAGE_DECODE_H_
+
+#include "base/memory/weak_ptr.h"
+#include "components/services/app_service/public/mojom/types.mojom.h"
+
+class SharesheetImageDecode {
+ public:
+  SharesheetImageDecode();
+  ~SharesheetImageDecode();
+  SharesheetImageDecode(const SharesheetImageDecode&) = delete;
+  SharesheetImageDecode& operator=(const SharesheetImageDecode&) = delete;
+
+ private:
+  // Encodes the FilePath |GURL| into encoded bytes.
+  void URLToEncodedBytes(const base::FilePath& url);
+
+  // Decodes the string of encoded bytes |image_data|
+  // into an SkBitmap in a sandboxed process.
+  void DecodeURLForPreview(std::string image_data);
+
+  // Converts the |decoded_image| into an ImageSkia.
+  void BitMapToImage(const SkBitmap& decoded_image);
+
+  base::WeakPtrFactory<SharesheetImageDecode> weak_ptr_factory_{this};
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_SHARESHEET_SHARESHEET_IMAGE_DECODE_H_
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
index b78328a..5580bb9 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
@@ -602,7 +602,7 @@
 void TopControlsSlideControllerChromeOS::OnAccessibilityStatusChanged(
     const chromeos::AccessibilityStatusEventDetails& event_details) {
   if (event_details.notification_type !=
-      chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) {
+      chromeos::AccessibilityNotificationType::kToggleSpokenFeedback) {
     return;
   }
 
diff --git a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
index 35ebb98a..8538a74 100644
--- a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
+#include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
@@ -25,7 +26,10 @@
 
 class WebAppLinkCapturingBrowserTest : public WebAppNavigationBrowserTest {
  public:
-  WebAppLinkCapturingBrowserTest() = default;
+  WebAppLinkCapturingBrowserTest() {
+    os_hooks_supress_ = OsIntegrationManager::ScopedSuppressOsHooksForTesting();
+  }
+
   ~WebAppLinkCapturingBrowserTest() override = default;
 
   void SetUpOnMainThread() override {
@@ -93,6 +97,8 @@
 
   const GURL about_blank_{"about:blank"};
   const GURL out_of_scope_{"https://other-domain.org/"};
+
+  ScopedOsHooksSuppress os_hooks_supress_;
 };
 
 class WebAppTabStripLinkCapturingBrowserTest
@@ -265,4 +271,31 @@
   ExpectTabs(browser(), {about_blank_, in_scope_2_});
 }
 
+IN_PROC_BROWSER_TEST_F(WebAppDeclarativeLinkCapturingBrowserTest,
+                       CaptureLinksExistingClientNavigate) {
+  InstallTestApp("/web_apps/capture_links_existing_client_navigate.html");
+
+  Navigate(browser(), out_of_scope_);
+
+  // In scope navigation should open an app window (because there are none
+  // already open).
+  Navigate(browser(), in_scope_1_);
+  Browser* app_browser = BrowserList::GetInstance()->GetLastActive();
+  EXPECT_TRUE(AppBrowserController::IsForWebApp(app_browser, app_id_));
+  ExpectTabs(browser(), {out_of_scope_});
+  ExpectTabs(app_browser, {in_scope_1_});
+
+  // In scope navigation should navigate the existing app window.
+  Navigate(browser(), in_scope_2_);
+  EXPECT_EQ(app_browser, BrowserList::GetInstance()->GetLastActive());
+  ExpectTabs(browser(), {out_of_scope_});
+  ExpectTabs(app_browser, {in_scope_2_});
+
+  // In scope navigation should navigate the existing app window.
+  Navigate(browser(), in_scope_1_);
+  EXPECT_EQ(app_browser, BrowserList::GetInstance()->GetLastActive());
+  ExpectTabs(browser(), {out_of_scope_});
+  ExpectTabs(app_browser, {in_scope_1_});
+}
+
 }  // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_metrics.cc b/chrome/browser/ui/web_applications/web_app_metrics.cc
index 9d83805..7ebac4f 100644
--- a/chrome/browser/ui/web_applications/web_app_metrics.cc
+++ b/chrome/browser/ui/web_applications/web_app_metrics.cc
@@ -379,14 +379,18 @@
 void WebAppMetrics::UpdateForegroundWebContents(WebContents* web_contents) {
   if (web_contents == foreground_web_contents_)
     return;
-  app_banner_manager_observer_.RemoveAll();
+  if (web_contents && web_contents->IsBeingDestroyed()) {
+    base::debug::DumpWithoutCrashing();
+    web_contents = nullptr;
+  }
+  app_banner_manager_observer_.Reset();
   foreground_web_contents_ = web_contents;
   WebContentsObserver::Observe(web_contents);
   if (web_contents) {
     auto* app_banner_manager =
         webapps::AppBannerManager::FromWebContents(web_contents);
     DCHECK(app_banner_manager);
-    app_banner_manager_observer_.Add(app_banner_manager);
+    app_banner_manager_observer_.Observe(app_banner_manager);
   }
 }
 
diff --git a/chrome/browser/ui/web_applications/web_app_metrics.h b/chrome/browser/ui/web_applications/web_app_metrics.h
index 7426f408..d481f3d 100644
--- a/chrome/browser/ui/web_applications/web_app_metrics.h
+++ b/chrome/browser/ui/web_applications/web_app_metrics.h
@@ -7,7 +7,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/power_monitor/power_observer.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #include "chrome/browser/banners/app_banner_manager.h"
 #include "chrome/browser/ui/browser_tab_strip_tracker.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
@@ -96,7 +96,8 @@
   Profile* const profile_;
 
   BrowserTabStripTracker browser_tab_strip_tracker_;
-  ScopedObserver<webapps::AppBannerManager, webapps::AppBannerManager::Observer>
+  base::ScopedObservation<webapps::AppBannerManager,
+                          webapps::AppBannerManager::Observer>
       app_banner_manager_observer_{this};
 
   base::WeakPtrFactory<WebAppMetrics> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 21c37e3..2dbd378 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -786,7 +786,8 @@
       return &NewWebUI<chromeos::ArcPowerControlUI>;
     }
   }
-  if (url.host_piece() == chrome::kChromeUIEmojiPickerHost) {
+  if (url.host_piece() == chrome::kChromeUIEmojiPickerHost &&
+      base::FeatureList::IsEnabled(chromeos::features::kImeSystemEmojiPicker)) {
     return &NewWebUI<chromeos::EmojiPicker>;
   }
 
diff --git a/chrome/browser/ui/webui/chromeos/emoji/emoji_handler.cc b/chrome/browser/ui/webui/chromeos/emoji/emoji_handler.cc
new file mode 100644
index 0000000..a841dc5
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/emoji/emoji_handler.cc
@@ -0,0 +1,31 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/chromeos/emoji/emoji_handler.h"
+
+#include "base/logging.h"
+
+namespace chromeos {
+
+EmojiHandler::EmojiHandler() = default;
+EmojiHandler::~EmojiHandler() = default;
+
+void EmojiHandler::RegisterMessages() {
+  web_ui()->RegisterMessageCallback(
+      "insertEmoji", base::BindRepeating(&EmojiHandler::HandleInsertEmoji,
+                                         base::Unretained(this)));
+}
+
+void EmojiHandler::HandleInsertEmoji(const base::ListValue* args) {
+  if (args->GetSize() != 1) {
+    DLOG(WARNING)
+        << "insertEmoji called with incorrect number of arguments (expected 1)";
+    return;
+  }
+
+  // Example usage:
+  // const std::string& emoji = args->GetList()[0].GetString();
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/emoji/emoji_handler.h b/chrome/browser/ui/webui/chromeos/emoji/emoji_handler.h
new file mode 100644
index 0000000..26f74ca7
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/emoji/emoji_handler.h
@@ -0,0 +1,30 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_EMOJI_EMOJI_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_EMOJI_EMOJI_HANDLER_H_
+
+#include "base/macros.h"
+#include "content/public/browser/web_ui_message_handler.h"
+
+namespace chromeos {
+
+// The WebUI message handler for chrome://emoji-picker
+class EmojiHandler : public content::WebUIMessageHandler {
+ public:
+  EmojiHandler();
+  ~EmojiHandler() override;
+
+ private:
+  // content::WebUIMessageHandler:
+  void RegisterMessages() override;
+
+  void HandleInsertEmoji(const base::ListValue* args);
+
+  DISALLOW_COPY_AND_ASSIGN(EmojiHandler);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_EMOJI_EMOJI_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/emoji/emoji_picker.cc b/chrome/browser/ui/webui/chromeos/emoji/emoji_picker.cc
index 790517c..0d293ae 100644
--- a/chrome/browser/ui/webui/chromeos/emoji/emoji_picker.cc
+++ b/chrome/browser/ui/webui/chromeos/emoji/emoji_picker.cc
@@ -14,6 +14,7 @@
 #include "content/public/browser/web_ui_data_source.h"
 
 #include "chrome/browser/ui/webui/chromeos/emoji/emoji_dialog.h"
+#include "chrome/browser/ui/webui/chromeos/emoji/emoji_handler.h"
 
 namespace chromeos {
 
@@ -35,6 +36,9 @@
       base::make_span(kEmojiPickerResources, kEmojiPickerResourcesSize),
       IDR_EMOJI_PICKER_INDEX_HTML);
 
+  // Attach message handler to handle emoji click events.
+  web_ui->AddMessageHandler(std::make_unique<EmojiHandler>());
+
   content::BrowserContext* browser_context =
       web_ui->GetWebContents()->GetBrowserContext();
   content::WebUIDataSource::Add(browser_context, html_source.release());
diff --git a/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.cc
index 8dd97791..d66c0b4d 100644
--- a/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.cc
@@ -83,10 +83,6 @@
 
 void DemoSetupScreenHandler::GetAdditionalParameters(
     base::DictionaryValue* parameters) {
-  parameters->SetBoolKey(
-      "showStepsInDemoModeSetup",
-      base::FeatureList::IsEnabled(features::kShowStepsInDemoModeSetup));
-
   parameters->SetPath("demoSetupSteps",
                       DemoSetupController::GetDemoSetupSteps());
 }
diff --git a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
index 844e877..845374be0 100644
--- a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
@@ -58,7 +58,8 @@
 
 void UpdateScreenHandler::OnAccessibilityStatusChanged(
     const AccessibilityStatusEventDetails& details) {
-  if (details.notification_type == ACCESSIBILITY_MANAGER_SHUTDOWN) {
+  if (details.notification_type ==
+      AccessibilityNotificationType::kManagerShutdown) {
     accessibility_subscription_ = {};
     return;
   }
diff --git a/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.cc
index acc44c6f..f152655 100644
--- a/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.cc
@@ -311,10 +311,12 @@
 
 void WelcomeScreenHandler::OnAccessibilityStatusChanged(
     const AccessibilityStatusEventDetails& details) {
-  if (details.notification_type == ACCESSIBILITY_MANAGER_SHUTDOWN)
+  if (details.notification_type ==
+      AccessibilityNotificationType::kManagerShutdown) {
     accessibility_subscription_ = {};
-  else
+  } else {
     UpdateA11yState();
+  }
 }
 
 void WelcomeScreenHandler::UpdateA11yState() {
diff --git a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
index 54b8c63cf..ae5ab09b 100644
--- a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
+++ b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
@@ -83,7 +83,7 @@
 void AccessibilityMainHandler::OnAccessibilityStatusChanged(
     const chromeos::AccessibilityStatusEventDetails& details) {
   if (details.notification_type ==
-      chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) {
+      chromeos::AccessibilityNotificationType::kToggleSpokenFeedback) {
     SendScreenReaderStateChanged();
   }
 }
diff --git a/chrome/browser/web_applications/components/web_app_id_constants.h b/chrome/browser/web_applications/components/web_app_id_constants.h
index 8589e230e..93de55a 100644
--- a/chrome/browser/web_applications/components/web_app_id_constants.h
+++ b/chrome/browser/web_applications/components/web_app_id_constants.h
@@ -36,6 +36,10 @@
 constexpr char kGoogleDriveAppId[] = "aghbiahbpaijignceidepookljebhfak";
 
 // Generated as: web_app::GenerateAppIdFromURL(GURL(
+//     "https://keep.google.com/?usp=installed_webapp"))
+constexpr char kGoogleKeepAppId[] = "eilembjdkfgodjkcjnpgpaenohkicgjd";
+
+// Generated as: web_app::GenerateAppIdFromURL(GURL(
 //     "https://www.google.com/maps?force=tt&source=ttpwa"))
 constexpr char kGoogleMapsAppId[] = "mnhkaebcjjhencmpkapnbdaogjamfbcj";
 
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 4266e5a6..2ea73708 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-master-1610755196-61d932c6744ad62f0472d9ac776510bd42cd0a54.profdata
+chrome-linux-master-1610775681-262289403e7fd8444a73878a73a9f9f97304c245.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 750dee4e..607efad 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-master-1610755196-59a4a0c119004651094c88c9b6ab2bda6a695e2e.profdata
+chrome-mac-master-1610948968-472c5c5ed4005e92cd456548bcb91e146ae8a09f.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index eaba014..f310589 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-master-1610744388-5f878bc1b38d4c2e869a6a4ceb1a959431b1ffe7.profdata
+chrome-win32-master-1610948968-73b5b51cc98aa3edcd70782870e3aaa675f980cb.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index d61cf2e..f5942279 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1610755196-7abba2cfdf73565a08dbdbba7efd11f1e8902293.profdata
+chrome-win64-master-1610926940-236c747d5ac0deeb141d61adc07a8e2f2f5cae68.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 3d87d7cf..669ecf5 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1643,23 +1643,6 @@
       ]
     }
 
-    if (is_chromeos_ash) {
-      sources += [
-        "../browser/chrome_main_browsertest.cc",
-        "../browser/chromeos/login/saml/test_client_cert_saml_idp_mixin.cc",
-        "../browser/chromeos/login/saml/test_client_cert_saml_idp_mixin.h",
-        "../browser/chromeos/scoped_test_system_nss_key_slot_mixin.cc",
-        "../browser/chromeos/scoped_test_system_nss_key_slot_mixin.h",
-        "../browser/process_singleton_browsertest.cc",
-        "../browser/sessions/session_restore_browsertest_chromeos.cc",
-        "../browser/ui/browser_navigator_browsertest_chromeos.cc",
-        "../browser/ui/settings_window_manager_browsertest_chromeos.cc",
-        "../browser/ui/webui/chromeos/bluetooth_pairing_dialog_browsertest-inl.h",
-        "../browser/ui/webui/chromeos/machine_learning/machine_learning_internals_browsertest.cc",
-        "../browser/ui/webui/chromeos/machine_learning/machine_learning_internals_browsertest.h",
-      ]
-    }
-
     if (is_win) {
       sources += [
         "../browser/chrome_main_browsertest.cc",
@@ -2401,6 +2384,7 @@
           [ "../browser/chromeos/crosapi/screen_manager_ash_browsertest.cc" ]
     }
 
+    # NOTE: This is the main "browser_tests" section for |is_chromeos_ash|.
     if (is_chromeos_ash) {
       sources += [
         "../browser/apps/platform_apps/app_window_interactive_uitest_base.cc",
@@ -2417,6 +2401,7 @@
         "../browser/ash/accessibility/sticky_keys_browsertest.cc",
         "../browser/ash/accessibility/switch_access_browsertest.cc",
         "../browser/ash/accessibility/touch_exploration_controller_browsertest.cc",
+        "../browser/chrome_main_browsertest.cc",
         "../browser/chromeos/account_manager/account_manager_policy_controller_browsertest.cc",
         "../browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc",
         "../browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc",
@@ -2505,6 +2490,7 @@
         "../browser/chromeos/file_manager/video_player_browsertest.cc",
         "../browser/chromeos/file_manager/video_player_jstest.cc",
         "../browser/chromeos/first_run/drive_first_run_browsertest.cc",
+        "../browser/chromeos/full_restore/app_launch_handler_browsertest.cc",
         "../browser/chromeos/input_method/input_method_engine_browsertests.cc",
         "../browser/chromeos/input_method/native_input_method_engine_browsertest.cc",
         "../browser/chromeos/input_method/textinput_browsertest.cc",
@@ -2571,6 +2557,8 @@
         "../browser/chromeos/login/saml/password_change_success_detection_browsertest.cc",
         "../browser/chromeos/login/saml/saml_browsertest.cc",
         "../browser/chromeos/login/saml/security_token_saml_browsertest.cc",
+        "../browser/chromeos/login/saml/test_client_cert_saml_idp_mixin.cc",
+        "../browser/chromeos/login/saml/test_client_cert_saml_idp_mixin.h",
         "../browser/chromeos/login/screens/app_downloading_screen_browsertest.cc",
         "../browser/chromeos/login/screens/assistant_optin_flow_screen_browsertest.cc",
         "../browser/chromeos/login/screens/edu_coexistence_login_browsertest.cc",
@@ -2747,6 +2735,8 @@
         "../browser/chromeos/profiles/profile_helper_browsertest.cc",
         "../browser/chromeos/remote_apps/remote_apps_impl_browsertest.cc",
         "../browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc",
+        "../browser/chromeos/scoped_test_system_nss_key_slot_mixin.cc",
+        "../browser/chromeos/scoped_test_system_nss_key_slot_mixin.h",
         "../browser/chromeos/shutdown_policy_browsertest.cc",
         "../browser/chromeos/startup_settings_cache_browsertest.cc",
         "../browser/chromeos/system/device_disabling_browsertest.cc",
@@ -2774,7 +2764,9 @@
         "../browser/metrics/family_user_metrics_provider_browsertest.cc",
         "../browser/metrics/majority_age_user_metrics_provider_browsertest.cc",
         "../browser/notifications/notification_platform_bridge_chromeos_browsertest.cc",
+        "../browser/process_singleton_browsertest.cc",
         "../browser/resources/chromeos/zip_archiver/test/zip_archiver_jstest.cc",
+        "../browser/sessions/session_restore_browsertest_chromeos.cc",
         "../browser/signin/chromeos_mirror_account_consistency_browsertest.cc",
         "../browser/ui/app_list/app_list_client_impl_browsertest.cc",
         "../browser/ui/app_list/app_service/app_service_app_item_browsertest.cc",
@@ -2811,6 +2803,8 @@
         "../browser/ui/ash/tablet_mode_page_behavior_browsertest.cc",
         "../browser/ui/ash/volume_controller_browsertest.cc",
         "../browser/ui/browser_finder_chromeos_browsertest.cc",
+        "../browser/ui/browser_navigator_browsertest_chromeos.cc",
+        "../browser/ui/settings_window_manager_browsertest_chromeos.cc",
         "../browser/ui/views/apps/app_dialog/app_dialog_view_browsertest.cc",
         "../browser/ui/views/apps/app_dialog/app_uninstall_dialog_view_browsertest.cc",
         "../browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc",
@@ -2840,12 +2834,15 @@
         "../browser/ui/web_applications/web_share_target_browsertest.cc",
         "../browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder_browsertest.cc",
         "../browser/ui/webui/chromeos/add_supervision/add_supervision_ui_browsertest.cc",
+        "../browser/ui/webui/chromeos/bluetooth_pairing_dialog_browsertest-inl.h",
         "../browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog_browsertest.cc",
         "../browser/ui/webui/chromeos/edu_coexistence_login_handler_browsertest.cc",
         "../browser/ui/webui/chromeos/login/js_calls_container_test_api.cc",
         "../browser/ui/webui/chromeos/login/js_calls_container_test_api.h",
         "../browser/ui/webui/chromeos/login/oobe_display_chooser_browsertest.cc",
         "../browser/ui/webui/chromeos/login/testapi/oobe_test_api_browsertest.cc",
+        "../browser/ui/webui/chromeos/machine_learning/machine_learning_internals_browsertest.cc",
+        "../browser/ui/webui/chromeos/machine_learning/machine_learning_internals_browsertest.h",
         "../browser/ui/webui/chromeos/smb_shares/smb_credentials_dialog_browsertest.cc",
         "../browser/ui/webui/chromeos/system_web_dialog_browsertest.cc",
         "../browser/ui/webui/settings/chromeos/account_manager_handler_browsertest.cc",
@@ -2858,22 +2855,20 @@
         "base/interactive_test_utils_views.cc",
       ]
       data += [ "../browser/resources/chromeos/accessibility/switch_access/test_support.js" ]
-      if (is_chromeos_ash && !is_official_build) {
+      if (!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_ash) {
-          sources += [
-            "../browser/chromeos/extensions/printing/fake_print_job_controller.cc",
-            "../browser/chromeos/extensions/printing/fake_print_job_controller.h",
-            "../browser/chromeos/extensions/printing/printing_apitest.cc",
-            "../browser/chromeos/extensions/printing_metrics/print_job_finished_event_dispatcher_apitest.cc",
-            "../browser/chromeos/extensions/printing_metrics/printing_metrics_apitest.cc",
-          ]
-        }
+        sources += [
+          "../browser/chromeos/extensions/printing/fake_print_job_controller.cc",
+          "../browser/chromeos/extensions/printing/fake_print_job_controller.h",
+          "../browser/chromeos/extensions/printing/printing_apitest.cc",
+          "../browser/chromeos/extensions/printing_metrics/print_job_finished_event_dispatcher_apitest.cc",
+          "../browser/chromeos/extensions/printing_metrics/printing_metrics_apitest.cc",
+        ]
         deps += [ "//printing:test_support" ]
       }
       if (enable_assistant_integration_tests) {
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index d5c50cd..0ffe2a4 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -67,9 +67,7 @@
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/test/history_service_test_util.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/keyed_service/core/refcounted_keyed_service.h"
-#include "components/keyed_service/core/simple_dependency_manager.h"
 #include "components/keyed_service/core/simple_factory_key.h"
 #include "components/keyed_service/core/simple_key_map.h"
 #include "components/leveldb_proto/public/proto_database_provider.h"
@@ -152,9 +150,6 @@
 
 namespace {
 
-// Default profile name
-const char kTestingProfile[] = "testing_profile";
-
 void TestProfileErrorCallback(WebDataServiceWrapper::ErrorType error_type,
                               sql::InitStatus status,
                               const std::string& diagnostics) {
@@ -180,6 +175,9 @@
 }  // namespace
 
 // static
+const char TestingProfile::kDefaultProfileUserName[] = "testing_profile";
+
+// static
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Must be kept in sync with
 // ChromeBrowserMainPartsChromeos::PreEarlyInitialization.
@@ -216,22 +214,7 @@
     : TestingProfile(path, nullptr) {}
 
 TestingProfile::TestingProfile(const base::FilePath& path, Delegate* delegate)
-    : start_time_(Time::Now()),
-      testing_prefs_(nullptr),
-      original_profile_(nullptr),
-      guest_session_(false),
-      allows_browser_windows_(true),
-      is_new_profile_(false),
-      last_session_exited_cleanly_(true),
-      profile_path_(path),
-      simple_dependency_manager_(SimpleDependencyManager::GetInstance()),
-      browser_context_dependency_manager_(
-          BrowserContextDependencyManager::GetInstance()),
-      resource_context_(nullptr),
-      delegate_(delegate),
-      profile_name_(kTestingProfile),
-      override_policy_connector_is_managed_(base::nullopt),
-      otr_profile_id_(base::nullopt) {
+    : profile_path_(path), delegate_(delegate) {
   if (profile_path_.empty()) {
     profile_path_ = base::CreateUniqueTempDirectoryScopedToTest();
   }
@@ -267,23 +250,16 @@
     const std::string& profile_name,
     base::Optional<bool> override_policy_connector_is_managed,
     base::Optional<OTRProfileID> otr_profile_id)
-    : start_time_(Time::Now()),
-      prefs_(std::move(prefs)),
-      testing_prefs_(nullptr),
+    : prefs_(std::move(prefs)),
       original_profile_(parent),
       guest_session_(guest_session),
       allows_browser_windows_(allows_browser_windows),
       is_new_profile_(is_new_profile),
       supervised_user_id_(supervised_user_id),
-      last_session_exited_cleanly_(true),
 #if BUILDFLAG(ENABLE_EXTENSIONS)
       extension_special_storage_policy_(extension_policy),
 #endif
       profile_path_(path),
-      simple_dependency_manager_(SimpleDependencyManager::GetInstance()),
-      browser_context_dependency_manager_(
-          BrowserContextDependencyManager::GetInstance()),
-      resource_context_(nullptr),
       user_cloud_policy_manager_(std::move(policy_manager)),
       delegate_(delegate),
       profile_name_(profile_name),
@@ -1022,16 +998,9 @@
   return last_session_exited_cleanly_ ? EXIT_NORMAL : EXIT_CRASHED;
 }
 
-TestingProfile::Builder::Builder()
-    : build_called_(false),
-      delegate_(nullptr),
-      guest_session_(false),
-      allows_browser_windows_(true),
-      is_new_profile_(false),
-      profile_name_(kTestingProfile) {}
+TestingProfile::Builder::Builder() = default;
 
-TestingProfile::Builder::~Builder() {
-}
+TestingProfile::Builder::~Builder() = default;
 
 void TestingProfile::Builder::SetPath(const base::FilePath& path) {
   path_ = path;
@@ -1113,7 +1082,7 @@
   DCHECK(!build_called_);
   build_called_ = true;
 
-  return std::unique_ptr<TestingProfile>(new TestingProfile(
+  return std::make_unique<TestingProfile>(
       path_, delegate_,
 #if BUILDFLAG(ENABLE_EXTENSIONS)
       extension_policy_,
@@ -1122,7 +1091,7 @@
       allows_browser_windows_, is_new_profile_, supervised_user_id_,
       std::move(user_cloud_policy_manager_), std::move(policy_service_),
       std::move(testing_factories_), profile_name_,
-      override_policy_connector_is_managed_, base::Optional<OTRProfileID>()));
+      override_policy_connector_is_managed_, base::Optional<OTRProfileID>());
 }
 
 TestingProfile* TestingProfile::Builder::BuildOffTheRecord(
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index f5b2b249..52f3c4a 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -15,12 +15,15 @@
 #include "base/memory/ref_counted.h"
 #include "base/optional.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/time/time.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"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/keyed_service/core/simple_dependency_manager.h"
 #include "components/keyed_service/core/simple_factory_key.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/buildflags/buildflags.h"
@@ -34,8 +37,6 @@
 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #endif
 
-class BrowserContextDependencyManager;
-class SimpleDependencyManager;
 class ExtensionSpecialStoragePolicy;
 class HostContentSettingsMap;
 class TestingPrefStore;
@@ -74,6 +75,8 @@
 
 class TestingProfile : public Profile {
  public:
+  static const char kDefaultProfileUserName[];
+
   // Profile directory name for the test user. This is "Default" on most
   // platforms but must be different on ChromeOS because a logged-in user cannot
   // use "Default" as profile directory.
@@ -185,7 +188,7 @@
 
    private:
     // If true, Build() has already been called.
-    bool build_called_;
+    bool build_called_ = false;
 
     // Various staging variables where values are held until Build() is invoked.
     std::unique_ptr<sync_preferences::PrefServiceSyncable> pref_service_;
@@ -193,10 +196,10 @@
     scoped_refptr<ExtensionSpecialStoragePolicy> extension_policy_;
 #endif
     base::FilePath path_;
-    Delegate* delegate_;
-    bool guest_session_;
-    bool allows_browser_windows_;
-    bool is_new_profile_;
+    Delegate* delegate_ = nullptr;
+    bool guest_session_ = false;
+    bool allows_browser_windows_ = true;
+    bool is_new_profile_ = false;
     std::string supervised_user_id_;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     std::unique_ptr<policy::UserCloudPolicyManagerChromeOS>
@@ -206,7 +209,7 @@
 #endif
     std::unique_ptr<policy::PolicyService> policy_service_;
     TestingFactories testing_factories_;
-    std::string profile_name_;
+    std::string profile_name_{kDefaultProfileUserName};
     base::Optional<bool> override_policy_connector_is_managed_;
   };
 
@@ -411,7 +414,7 @@
   ProfileDestructionCallback profile_destruction_callback_;
 
  protected:
-  base::Time start_time_;
+  base::Time start_time_{base::Time::Now()};
 
   // The key to index KeyedService instances created by
   // SimpleKeyedServiceFactory.
@@ -419,7 +422,7 @@
 
   std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs_;
   // ref only for right type, lifecycle is managed by prefs_
-  sync_preferences::TestingPrefServiceSyncable* testing_prefs_;
+  sync_preferences::TestingPrefServiceSyncable* testing_prefs_ = nullptr;
 
   // Profile implementation.
   bool IsSignedIn() override;
@@ -451,18 +454,18 @@
       extensions_cookie_store_;
 
   std::map<OTRProfileID, std::unique_ptr<Profile>> otr_profiles_;
-  TestingProfile* original_profile_;
+  TestingProfile* original_profile_ = nullptr;
 
-  bool guest_session_;
+  bool guest_session_ = false;
 
-  bool allows_browser_windows_;
+  bool allows_browser_windows_ = true;
 
-  bool is_new_profile_;
+  bool is_new_profile_ = false;
 
   std::string supervised_user_id_;
 
-  // Did the last session exit cleanly? Default is true.
-  bool last_session_exited_cleanly_;
+  // Whether the last session exited cleanly.
+  bool last_session_exited_cleanly_ = true;
 
   scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
 
@@ -482,12 +485,14 @@
   // We keep a weak pointer to the dependency manager we want to notify on our
   // death. Defaults to the Singleton implementation but overridable for
   // testing.
-  SimpleDependencyManager* simple_dependency_manager_;
-  BrowserContextDependencyManager* browser_context_dependency_manager_;
+  SimpleDependencyManager* simple_dependency_manager_{
+      SimpleDependencyManager::GetInstance()};
+  BrowserContextDependencyManager* browser_context_dependency_manager_{
+      BrowserContextDependencyManager::GetInstance()};
 
   // Owned, but must be deleted on the IO thread so not placing in a
   // std::unique_ptr<>.
-  content::MockResourceContext* resource_context_;
+  content::MockResourceContext* resource_context_ = nullptr;
 
   std::unique_ptr<policy::SchemaRegistryService> schema_registry_service_;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -499,9 +504,9 @@
   std::unique_ptr<policy::ProfilePolicyConnector> profile_policy_connector_;
 
   // Weak pointer to a delegate for indicating that a profile was created.
-  Delegate* delegate_;
+  Delegate* delegate_ = nullptr;
 
-  std::string profile_name_;
+  std::string profile_name_{kDefaultProfileUserName};
 
   base::Optional<bool> override_policy_connector_is_managed_;
   base::Optional<OTRProfileID> otr_profile_id_;
diff --git a/chrome/test/data/web_apps/capture_links_existing_client_navigate.html b/chrome/test/data/web_apps/capture_links_existing_client_navigate.html
new file mode 100644
index 0000000..1e8ff57
--- /dev/null
+++ b/chrome/test/data/web_apps/capture_links_existing_client_navigate.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<head>
+  <title>"capture_links": "existing-client-navigate"</title>
+  <link rel="manifest" href="capture_links_existing_client_navigate.json">
+</head>
diff --git a/chrome/test/data/web_apps/capture_links_existing_client_navigate.json b/chrome/test/data/web_apps/capture_links_existing_client_navigate.json
new file mode 100644
index 0000000..42f57a57
--- /dev/null
+++ b/chrome/test/data/web_apps/capture_links_existing_client_navigate.json
@@ -0,0 +1,6 @@
+{
+  "name": "\"capture_links\": \"existing-client-navigate\"",
+  "start_url": "capture_links_existing_client_navigate.html",
+  "display": "standalone",
+  "capture_links": "existing-client-navigate"
+}
diff --git a/chromeos/components/help_app_ui/test/guest_query_receiver.js b/chromeos/components/help_app_ui/test/guest_query_receiver.js
index 185b3dc..58b93f7 100644
--- a/chromeos/components/help_app_ui/test/guest_query_receiver.js
+++ b/chromeos/components/help_app_ui/test/guest_query_receiver.js
@@ -81,4 +81,4 @@
   installTestHandlers();
 }
 
-//# sourceURL=guest_query_reciever.js
+//# sourceURL=guest_query_receiver.js
diff --git a/chromeos/components/sensors/fake_sensor_hal_server.cc b/chromeos/components/sensors/fake_sensor_hal_server.cc
index 26e00df5..77363764 100644
--- a/chromeos/components/sensors/fake_sensor_hal_server.cc
+++ b/chromeos/components/sensors/fake_sensor_hal_server.cc
@@ -13,8 +13,7 @@
 
 void FakeSensorHalServer::CreateChannel(
     mojo::PendingReceiver<mojom::SensorService> sensor_service_receiver) {
-  DCHECK(!sensor_service_->is_bound());
-  sensor_service_->Bind(std::move(sensor_service_receiver));
+  sensor_service_->AddReceiver(std::move(sensor_service_receiver));
 }
 
 mojo::PendingRemote<mojom::SensorHalServer> FakeSensorHalServer::PassRemote() {
diff --git a/chromeos/components/sensors/fake_sensor_service.cc b/chromeos/components/sensors/fake_sensor_service.cc
index 61e27302..96315c5 100644
--- a/chromeos/components/sensors/fake_sensor_service.cc
+++ b/chromeos/components/sensors/fake_sensor_service.cc
@@ -21,26 +21,23 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-bool FakeSensorService::is_bound() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  return receiver_.is_bound();
-}
-
-void FakeSensorService::Bind(
+void FakeSensorService::AddReceiver(
     mojo::PendingReceiver<mojom::SensorService> pending_receiver) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!is_bound());
 
-  receiver_.Bind(std::move(pending_receiver));
-  receiver_.set_disconnect_handler(base::BindOnce(
-      &FakeSensorService::OnServiceDisconnect, base::Unretained(this)));
+  receiver_set_.Add(this, std::move(pending_receiver));
 }
 
-void FakeSensorService::OnServiceDisconnect() {
+void FakeSensorService::ClearReceivers() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  receiver_.reset();
+  receiver_set_.Clear();
+}
+
+bool FakeSensorService::HasReceivers() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  return !receiver_set_.empty();
 }
 
 void FakeSensorService::SetDevice(
diff --git a/chromeos/components/sensors/fake_sensor_service.h b/chromeos/components/sensors/fake_sensor_service.h
index 1a2b6f0..a5df1ff 100644
--- a/chromeos/components/sensors/fake_sensor_service.h
+++ b/chromeos/components/sensors/fake_sensor_service.h
@@ -12,7 +12,7 @@
 #include "base/sequence_checker.h"
 #include "chromeos/components/sensors/fake_sensor_device.h"
 #include "chromeos/components/sensors/mojom/sensor.mojom.h"
-#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
 
 namespace chromeos {
@@ -25,9 +25,10 @@
   FakeSensorService& operator=(const FakeSensorService&) = delete;
   ~FakeSensorService() override;
 
-  bool is_bound();
-  void Bind(mojo::PendingReceiver<mojom::SensorService> pending_receiver);
-  void OnServiceDisconnect();
+  void AddReceiver(
+      mojo::PendingReceiver<mojom::SensorService> pending_receiver);
+  void ClearReceivers();
+  bool HasReceivers() const;
 
   void SetDevice(int32_t iio_device_id,
                  std::set<mojom::DeviceType> types,
@@ -58,7 +59,7 @@
   // First is the iio_device_id, second is the device's data.
   std::map<int32_t, DeviceData> devices_;
 
-  mojo::Receiver<mojom::SensorService> receiver_{this};
+  mojo::ReceiverSet<mojom::SensorService> receiver_set_;
   mojo::RemoteSet<mojom::SensorServiceNewDevicesObserver> observers_;
 
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chromeos/components/sensors/sensor_hal_dispatcher_unittest.cc b/chromeos/components/sensors/sensor_hal_dispatcher_unittest.cc
index 1231e02..808fcce 100644
--- a/chromeos/components/sensors/sensor_hal_dispatcher_unittest.cc
+++ b/chromeos/components/sensors/sensor_hal_dispatcher_unittest.cc
@@ -55,7 +55,7 @@
   // Wait until the server and client get the established Mojo channel.
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_TRUE(fake_server->GetSensorService()->is_bound());
+  EXPECT_TRUE(fake_server->GetSensorService()->HasReceivers());
   EXPECT_TRUE(fake_client->SensorServiceIsValid());
 
   // Re-create a new server to simulate a server crash.
@@ -72,7 +72,7 @@
   // client.
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_TRUE(fake_server->GetSensorService()->is_bound());
+  EXPECT_TRUE(fake_server->GetSensorService()->HasReceivers());
   EXPECT_TRUE(fake_client->SensorServiceIsValid());
 }
 
@@ -93,12 +93,12 @@
   // Wait until the server and client get the established Mojo channel.
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_TRUE(fake_server->GetSensorService()->is_bound());
+  EXPECT_TRUE(fake_server->GetSensorService()->HasReceivers());
   EXPECT_TRUE(fake_client->SensorServiceIsValid());
 
   // Re-create a new client to simulate a client crash.
   fake_client = std::make_unique<FakeSensorHalClient>();
-  fake_server->GetSensorService()->OnServiceDisconnect();
+  fake_server->GetSensorService()->ClearReceivers();
 
   remote_client = fake_client->PassRemote();
   SensorHalDispatcher::GetInstance()->RegisterClient(std::move(remote_client));
@@ -107,7 +107,7 @@
   // client.
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_TRUE(fake_server->GetSensorService()->is_bound());
+  EXPECT_TRUE(fake_server->GetSensorService()->HasReceivers());
   EXPECT_TRUE(fake_client->SensorServiceIsValid());
 }
 
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 23f47589..25b7a55 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -400,10 +400,6 @@
 const base::Feature kGesturePropertiesDBusService{
     "GesturePropertiesDBusService", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enable Guest OS external protocol handling.
-const base::Feature kGuestOsExternalProtocol{"GuestOsExternalProtocol",
-                                             base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Enables editing with handwriting gestures within the virtual keyboard.
 const base::Feature kHandwritingGestureEditing{
     "HandwritingGestureEditing", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -619,10 +615,6 @@
 const base::Feature kShowPlayInDemoMode{"ShowPlayInDemoMode",
                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Shows individual steps during Demo Mode setup.
-const base::Feature kShowStepsInDemoModeSetup{"ShowStepsInDemoModeSetup",
-                                              base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Uses experimental component version for smart dim.
 const base::Feature kSmartDimExperimentalComponent{
     "SmartDimExperimentalComponent", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index 7329576..48487f23 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -183,8 +183,6 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kGesturePropertiesDBusService;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
-extern const base::Feature kGuestOsExternalProtocol;
-COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kHelpAppSearchServiceIntegration;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kImeMojoDecoder;
@@ -283,8 +281,6 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kShowPlayInDemoMode;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
-extern const base::Feature kShowStepsInDemoModeSetup;
-COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kSmartDimExperimentalComponent;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kSmartDimNewMlAgent;
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom
index 123e9d4..a631bddb 100644
--- a/chromeos/crosapi/mojom/crosapi.mojom
+++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -200,9 +200,12 @@
   // Note that this is an approach consistent with ARC's behavior.
   kConsumedByImeWorkaround = 1,
 
-  // TODO(crbug.com/1093194): For long term, we're looking at a way to remove
-  // the above workaround. It will be exclusive state, so on implementing
-  // ash-chrome's fix, it is necessary to add a new value here, too, atomically.
+  // Exo sends keysym events to a client using a separate API.
+  // Once the client (lacros-chrome) gets ready to handle wl_keyboard::key and
+  // zwp_text_input_v1::keysym properly in separate paths, exo can send each
+  // each event without the ConsumedByIme() workaround above and tell the client
+  // that it dropped the workaround using kSupported flag.
+  [MinVersion=1] kSupported = 2,
 };
 
 // LacrosInitParams is a set of parameters for initialization of lacros-chrome,
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 722b716a..7fb0505 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-89-4380.0-1610362181-benchmark-89.0.4387.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-89-4380.0-1610362181-benchmark-89.0.4389.4-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index a7460754..9910680 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-89-4374.0-1610361443-benchmark-89.0.4387.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-89-4374.0-1610361443-benchmark-89.0.4389.4-r1-redacted.afdo.xz
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index ceaed911..0eca72cc 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -338,6 +338,13 @@
 // TODO(crbug/1131038): Remove once it's launched.
 const base::Feature kAutofillUseUniqueRendererIDsOnIOS{
     "AutofillUseUniqueRendererIDsOnIOS", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Controls whether the creation of new address profiles is enabled in settings
+// on IOS.
+// TODO(crbug/1167105): Remove once it's launched.
+const base::Feature kAutofillEnableNewAddressProfileCreationInSettingsOnIOS{
+    "AutofillEnableNewAddressProfileCreationInSettingsOnIOS",
+    base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
 #if defined(OS_ANDROID)
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 9645be0..bcfd5f8 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -95,6 +95,8 @@
 
 #if defined(OS_IOS)
 extern const base::Feature kAutofillUseUniqueRendererIDsOnIOS;
+extern const base::Feature
+    kAutofillEnableNewAddressProfileCreationInSettingsOnIOS;
 #endif  // OS_IOS
 
 #if defined(OS_ANDROID)
diff --git a/components/metrics/structured/structured_metrics_provider.cc b/components/metrics/structured/structured_metrics_provider.cc
index 5053c93..c33799b 100644
--- a/components/metrics/structured/structured_metrics_provider.cc
+++ b/components/metrics/structured/structured_metrics_provider.cc
@@ -48,7 +48,7 @@
                       ChromeUserMetricsExtension* uma_proto) {
   DCHECK(events->is_list());
   for (const auto& event : events->GetList()) {
-    auto* event_proto = uma_proto->add_structured_event();
+    auto* event_proto = uma_proto->add_deprecated_structured_event();
 
     const auto event_name_hash = StringValueToUint(event.FindKey("name"));
     if (!event_name_hash)
diff --git a/components/metrics/structured/structured_metrics_provider_unittest.cc b/components/metrics/structured/structured_metrics_provider_unittest.cc
index 44ec9ab2..b1e96ec 100644
--- a/components/metrics/structured/structured_metrics_provider_unittest.cc
+++ b/components/metrics/structured/structured_metrics_provider_unittest.cc
@@ -183,7 +183,7 @@
   Init();
   OnRecordingDisabled();
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 0);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 0);
   ExpectOnlyFileReadError();
 }
 
@@ -237,7 +237,7 @@
       .SetTestMetricTwo(12345)
       .Record();
 
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 3);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 3);
   ExpectOnlyFileReadError();
 }
 
@@ -254,10 +254,10 @@
       .Record();
 
   const auto uma = GetProvidedEvents();
-  ASSERT_EQ(uma.structured_event_size(), 2);
+  ASSERT_EQ(uma.deprecated_structured_event_size(), 2);
 
   {  // First event
-    const auto& event = uma.structured_event(0);
+    const auto& event = uma.deprecated_structured_event(0);
     EXPECT_EQ(event.event_name_hash(), kEventOneHash);
     EXPECT_EQ(HashToHex(event.profile_event_id()), kProjectOneId);
     ASSERT_EQ(event.metrics_size(), 2);
@@ -279,7 +279,7 @@
   }
 
   {  // Second event
-    const auto& event = uma.structured_event(1);
+    const auto& event = uma.deprecated_structured_event(1);
     EXPECT_EQ(event.event_name_hash(), kEventTwoHash);
     EXPECT_EQ(HashToHex(event.profile_event_id()), kProjectTwoId);
     ASSERT_EQ(event.metrics_size(), 1);
@@ -307,11 +307,11 @@
   events::test_project_two::TestEventThree().Record();
 
   const auto uma = GetProvidedEvents();
-  ASSERT_EQ(uma.structured_event_size(), 3);
+  ASSERT_EQ(uma.deprecated_structured_event_size(), 3);
 
-  const auto& event_one = uma.structured_event(0);
-  const auto& event_two = uma.structured_event(1);
-  const auto& event_three = uma.structured_event(2);
+  const auto& event_one = uma.deprecated_structured_event(0);
+  const auto& event_two = uma.deprecated_structured_event(1);
+  const auto& event_three = uma.deprecated_structured_event(2);
 
   // Check events are in the right order.
   EXPECT_EQ(event_one.event_name_hash(), kEventOneHash);
@@ -336,14 +336,14 @@
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
   events::test_project_one::TestEventOne().SetTestMetricTwo(2).Record();
   // Should provide both the previous events.
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 2);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 2);
 
   // But the previous events shouldn't appear in the second report.
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 0);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 0);
 
   events::test_project_one::TestEventOne().SetTestMetricTwo(3).Record();
   // The third request should only contain the third event.
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 1);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 1);
 
   ExpectOnlyFileReadError();
 }
@@ -362,9 +362,9 @@
   // Start a second session and ensure the event is reported.
   Init();
   const auto uma = GetProvidedEvents();
-  ASSERT_EQ(uma.structured_event_size(), 1);
-  ASSERT_EQ(uma.structured_event(0).metrics_size(), 1);
-  EXPECT_EQ(uma.structured_event(0).metrics(0).value_int64(), 1234);
+  ASSERT_EQ(uma.deprecated_structured_event_size(), 1);
+  ASSERT_EQ(uma.deprecated_structured_event(0).metrics_size(), 1);
+  EXPECT_EQ(uma.deprecated_structured_event(0).metrics(0).value_int64(), 1234);
 
   ExpectOnlyFileReadError();
 }
@@ -384,7 +384,7 @@
   // done, because the provider hasn't finished loading the keys from disk.
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
   Wait();
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 0);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 0);
 
   ExpectOnlyFileReadError();
 }
@@ -399,7 +399,7 @@
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
   OnRecordingDisabled();
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 0);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 0);
 
   ExpectOnlyFileReadError();
 }
@@ -416,7 +416,7 @@
   OnRecordingEnabled();
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 2);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 2);
 
   ExpectOnlyFileReadError();
 }
@@ -426,11 +426,11 @@
 TEST_F(StructuredMetricsProviderTest,
        ReportsNothingBeforeInitializationComplete) {
   provider_ = std::make_unique<StructuredMetricsProvider>();
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 0);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 0);
   OnRecordingEnabled();
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 0);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 0);
   OnProfileAdded(TempDirPath());
-  EXPECT_EQ(GetProvidedEvents().structured_event_size(), 0);
+  EXPECT_EQ(GetProvidedEvents().deprecated_structured_event_size(), 0);
 }
 
 // Ensure an old structured_metrics.json file correctly migrates to the new
diff --git a/components/onc/docs/onc_spec.md b/components/onc/docs/onc_spec.md
index fa703ae1..50d28d4 100644
--- a/components/onc/docs/onc_spec.md
+++ b/components/onc/docs/onc_spec.md
@@ -1671,7 +1671,7 @@
     * (required if **Type** is
         *Client*, otherwise ignored) - **string**
     * For certificates with
-      private keys, this is the base64 encoding of the a PKCS#12 file.
+      private keys, this is the base64 encoding of a PKCS#12 file.
 
 * **Remove**
     * (optional, defaults to *false*) - **boolean**
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index ff444733..114378f 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -10993,6 +10993,7 @@
             'camera',
             'scanning',
             'web_store',
+            'canvas',
           ],
         },
       },
@@ -11022,6 +11023,11 @@
           'value': 'web_store',
           'caption': '''Web Store (supported since version 89)''',
         },
+        {
+          'name': 'canvas',
+          'value': 'canvas',
+          'caption': '''Canvas (supported since version 90)''',
+        },
       ],
       'supported_on': ['chrome_os:84-'],
       'features': {
@@ -11029,9 +11035,9 @@
         'dynamic_refresh': True,
         'per_profile': False,
       },
-      'example_value': ['camera', 'browser_settings', 'os_settings', 'scanning', 'web_store'],
+      'example_value': ['camera', 'browser_settings', 'os_settings', 'scanning', 'web_store', 'canvas'],
       'id': 689,
-      'caption': '''Configure the camera, browser settings, os settings, scanning and web store features to be disabled''',
+      'caption': '''Configure the camera, browser settings, os settings, scanning, web store and canvas features to be disabled''',
       'tags': [],
       'desc': '''Allows you to set a list of <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> features to be disabled.
 
diff --git a/components/services/storage/public/mojom/service_worker_storage_control.mojom b/components/services/storage/public/mojom/service_worker_storage_control.mojom
index 3bae1f50..316ee57 100644
--- a/components/services/storage/public/mojom/service_worker_storage_control.mojom
+++ b/components/services/storage/public/mojom/service_worker_storage_control.mojom
@@ -81,10 +81,11 @@
       (int32 status,
        network.mojom.URLResponseHead? response_head,
        mojo_base.mojom.BigBuffer? metadata);
-  // Reads the content of the resource associated with this reader.
+  // Reads the content of the resource associated with this reader. `pipe`
+  // can be empty when creating a data pipe fails.
   ReadData(int64 size,
            pending_remote<ServiceWorkerDataPipeStateNotifier> notifier) =>
-      (handle<data_pipe_consumer> pipe);
+      (handle<data_pipe_consumer>? pipe);
 };
 
 // An interface that writes a service worker script (resource) to storage.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 7f7ebda..7c16635 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1534,8 +1534,6 @@
     "renderer_host/text_input_manager.h",
     "renderer_host/ui_events_helper.cc",
     "renderer_host/ui_events_helper.h",
-    "renderer_host/web_database_host_impl.cc",
-    "renderer_host/web_database_host_impl.h",
     "resource_context_impl.cc",
     "resource_context_impl.h",
     "resource_coordinator_service.cc",
@@ -1782,6 +1780,8 @@
     "web_contents/web_contents_view_aura.h",
     "web_contents/web_contents_view_child_frame.cc",
     "web_contents/web_contents_view_child_frame.h",
+    "web_database/web_database_host_impl.cc",
+    "web_database/web_database_host_impl.h",
     "web_package/prefetched_signed_exchange_cache.cc",
     "web_package/prefetched_signed_exchange_cache.h",
     "web_package/prefetched_signed_exchange_cache_adapter.cc",
diff --git a/content/browser/native_io/native_io_manager.cc b/content/browser/native_io/native_io_manager.cc
index 4583930..fbfd0f4 100644
--- a/content/browser/native_io/native_io_manager.cc
+++ b/content/browser/native_io/native_io_manager.cc
@@ -11,6 +11,8 @@
 #include "content/browser/native_io/native_io_host.h"
 #include "content/browser/native_io/native_io_quota_client.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
 #include "storage/browser/quota/quota_client_type.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
@@ -35,11 +37,13 @@
     : root_path_(GetNativeIORootPath(profile_root)),
       special_storage_policy_(std::move(special_storage_policy)),
       quota_manager_proxy_(std::move(quota_manager_proxy)) {
-  if (quota_manager_proxy_) {
-    // TODO(crbug.com/1163048): Use mojo and switch to RegisterClient().
-    quota_manager_proxy_->RegisterLegacyClient(
-        base::MakeRefCounted<NativeIOQuotaClient>(),
-        storage::QuotaClientType::kNativeIO,
+  if (quota_manager_proxy) {
+    // Quota client assumes all backends have registered.
+    mojo::PendingRemote<storage::mojom::QuotaClient> quota_client;
+    mojo::MakeSelfOwnedReceiver(std::make_unique<NativeIOQuotaClient>(),
+                                quota_client.InitWithNewPipeAndPassReceiver());
+    quota_manager_proxy->RegisterClient(
+        std::move(quota_client), storage::QuotaClientType::kNativeIO,
         {blink::mojom::StorageType::kTemporary});
   }
 }
diff --git a/content/browser/native_io/native_io_manager_unittest.cc b/content/browser/native_io/native_io_manager_unittest.cc
index 933947e3..6830896a 100644
--- a/content/browser/native_io/native_io_manager_unittest.cc
+++ b/content/browser/native_io/native_io_manager_unittest.cc
@@ -178,7 +178,6 @@
 
   void TearDown() override {
     // Let the client go away before dropping a ref of the quota manager proxy.
-    quota_manager_proxy()->SimulateQuotaManagerDestroyed();
     quota_manager_ = nullptr;
     quota_manager_proxy_ = nullptr;
   }
diff --git a/content/browser/native_io/native_io_quota_client.cc b/content/browser/native_io/native_io_quota_client.cc
index e3c71b6c..62ad33d 100644
--- a/content/browser/native_io/native_io_quota_client.cc
+++ b/content/browser/native_io/native_io_quota_client.cc
@@ -19,8 +19,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-void NativeIOQuotaClient::OnQuotaManagerDestroyed() {}
-
 void NativeIOQuotaClient::GetOriginUsage(const url::Origin& origin,
                                          blink::mojom::StorageType type,
                                          GetOriginUsageCallback callback) {
diff --git a/content/browser/native_io/native_io_quota_client.h b/content/browser/native_io/native_io_quota_client.h
index 069a7734..641a5f9 100644
--- a/content/browser/native_io/native_io_quota_client.h
+++ b/content/browser/native_io/native_io_quota_client.h
@@ -6,8 +6,8 @@
 #define CONTENT_BROWSER_NATIVE_IO_NATIVE_IO_QUOTA_CLIENT_H_
 
 #include "base/sequence_checker.h"
+#include "components/services/storage/public/mojom/quota_client.mojom.h"
 #include "content/common/content_export.h"
-#include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_client_type.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
 #include "url/origin.h"
@@ -20,15 +20,15 @@
 // NativeIOQuotaClient is owned by the QuotaManager. There is one per
 // NativeIOManager/NativeIOOwner tuple. Created and accessed on
 // the IO thread.
-class CONTENT_EXPORT NativeIOQuotaClient : public storage::QuotaClient {
+class CONTENT_EXPORT NativeIOQuotaClient : public storage::mojom::QuotaClient {
  public:
   NativeIOQuotaClient();
+  ~NativeIOQuotaClient() override;
 
   NativeIOQuotaClient(const NativeIOQuotaClient&) = delete;
   NativeIOQuotaClient& operator=(const NativeIOQuotaClient&) = delete;
 
   // QuotaClient.
-  void OnQuotaManagerDestroyed() override;
   void GetOriginUsage(const url::Origin& origin,
                       blink::mojom::StorageType type,
                       GetOriginUsageCallback callback) override;
@@ -44,8 +44,6 @@
                              PerformStorageCleanupCallback callback) override;
 
  private:
-  ~NativeIOQuotaClient() override;
-
   SEQUENCE_CHECKER(sequence_checker_);
 };
 
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc
index 8512f089..107fb763 100644
--- a/content/browser/prerender/prerender_browsertest.cc
+++ b/content/browser/prerender/prerender_browsertest.cc
@@ -318,66 +318,86 @@
   }
 }
 
-// Makes sure that activations on navigations for iframes don't happen.
+// Makes sure that activation on navigation for an iframes doesn't happen.
 IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, Activation_iFrame) {
-  const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
-  const GURL kPrerenderingUrl = GetUrl("/empty.html");
-
   // Navigate to an initial page.
+  const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
   ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-  ASSERT_EQ(shell()->web_contents()->GetURL(), kInitialUrl);
 
-  // Add <link rel=prerender> that will prerender `kPrerenderingUrl`.
-  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
+  // Start a prerender.
+  const GURL kPrerenderingUrl = GetUrl("/empty.html");
   AddPrerender(kPrerenderingUrl);
-  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
-
-  // A prerender host for the URL should be registered.
   PrerenderHostRegistry& registry = GetPrerenderHostRegistry();
   PrerenderHost* prerender_host =
       registry.FindHostByUrlForTesting(kPrerenderingUrl);
-  EXPECT_TRUE(prerender_host);
+  ASSERT_TRUE(prerender_host);
 
   // Attempt to activate the prerendered page for an iframe. This should fail
   // and fallback to network request.
+  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
   EXPECT_EQ("LOADED", EvalJs(shell()->web_contents(),
                              JsReplace("add_iframe($1)", kPrerenderingUrl)));
-
-  // Activation shouldn't happen, so the prerender host should not be consumed,
-  // and navigation for the iframe should issue a request again.
-  EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl), prerender_host);
   EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2);
+
+  // Activation shouldn't happen, so the prerender host should not be consumed.
+  EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl), prerender_host);
 }
 
-// Makes sure that activations on navigations for pop-up windows don't happen.
+// Makes sure that activation on navigation for a pop-up window doesn't happen.
 IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, Activation_PopUpWindow) {
-  const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
-  const GURL kPrerenderingUrl = GetUrl("/empty.html");
-
   // Navigate to an initial page.
+  const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
   ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-  ASSERT_EQ(shell()->web_contents()->GetURL(), kInitialUrl);
 
-  // Add <link rel=prerender> that will prerender `kPrerenderingUrl`.
-  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
+  // Start a prerender.
+  const GURL kPrerenderingUrl = GetUrl("/empty.html");
   AddPrerender(kPrerenderingUrl);
-  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
-
-  // A prerender host for the URL should be registered.
   PrerenderHostRegistry& registry = GetPrerenderHostRegistry();
   PrerenderHost* prerender_host =
       registry.FindHostByUrlForTesting(kPrerenderingUrl);
-  EXPECT_TRUE(prerender_host);
+  ASSERT_TRUE(prerender_host);
 
   // Attempt to activate the prerendered page for a pop-up window. This should
   // fail and fallback to network request.
+  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
   EXPECT_EQ("LOADED", EvalJs(shell()->web_contents(),
                              JsReplace("open_window($1)", kPrerenderingUrl)));
-
-  // Activation shouldn't happen, so the prerender host should not be consumed,
-  // and navigation for the pop-up window should issue a request again.
-  EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl), prerender_host);
   EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2);
+
+  // Activation shouldn't happen, so the prerender host should not be consumed.
+  EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl), prerender_host);
+}
+
+// Makes sure that activation on navigation for a page that has a pop-up window
+// doesn't happen.
+IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, Activation_PageWithPopUpWindow) {
+  // Navigate to an initial page.
+  const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
+  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
+
+  // Start a prerender.
+  const GURL kPrerenderingUrl = GetUrl("/empty.html?next");
+  AddPrerender(kPrerenderingUrl);
+  PrerenderHostRegistry& registry = GetPrerenderHostRegistry();
+  ASSERT_TRUE(registry.FindHostByUrlForTesting(kPrerenderingUrl));
+
+  // Open a pop-up window.
+  const GURL kWindowUrl = GetUrl("/empty.html?window");
+  EXPECT_EQ("LOADED", EvalJs(shell()->web_contents(),
+                             JsReplace("open_window($1)", kWindowUrl)));
+
+  // Attempt to activate the prerendered page for the top-level frame. This
+  // should fail and fallback to network request because the pop-up window
+  // exists.
+  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
+  NavigateWithLocation(kPrerenderingUrl);
+  EXPECT_EQ(shell()->web_contents()->GetURL(), kPrerenderingUrl);
+  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2);
+
+  // Activation shouldn't happen, so the prerender host should not be consumed.
+  // However, we don't check the existence of the prerender host here unlike
+  // other activation tests because navigating the frame that triggered
+  // prerendering abandons the prerendered page regardless of activation.
 }
 
 // Tests that back-forward history is preserved after activation.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index d77cc6c..0c9a70f 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -127,7 +127,6 @@
 #include "content/browser/renderer_host/render_message_filter.h"
 #include "content/browser/renderer_host/render_widget_helper.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/browser/renderer_host/web_database_host_impl.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/browser/storage_partition_impl.h"
@@ -135,6 +134,7 @@
 #include "content/browser/tracing/background_tracing_manager_impl.h"
 #include "content/browser/url_loader_factory_params_helper.h"
 #include "content/browser/v8_snapshot_files.h"
+#include "content/browser/web_database/web_database_host_impl.h"
 #include "content/browser/websockets/websocket_connector_impl.h"
 #include "content/browser/webui/web_ui_controller_factory_registry.h"
 #include "content/common/child_process.mojom.h"
diff --git a/content/browser/service_worker/service_worker_cache_writer.cc b/content/browser/service_worker/service_worker_cache_writer.cc
index aaa85610..10dfd44 100644
--- a/content/browser/service_worker/service_worker_cache_writer.cc
+++ b/content/browser/service_worker/service_worker_cache_writer.cc
@@ -739,6 +739,13 @@
   }
 
   void OnReadData(mojo::ScopedDataPipeConsumerHandle data) {
+    // An invalid handle can be returned when creating a data pipe fails on the
+    // other side of the endpoint.
+    if (!data) {
+      owner_->AsyncDoLoop(net::ERR_FAILED);
+      return;
+    }
+
     data_ = std::move(data);
     watcher_.Watch(data_.get(),
                    MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
diff --git a/content/browser/web_database/DIR_METADATA b/content/browser/web_database/DIR_METADATA
new file mode 100644
index 0000000..030cb463
--- /dev/null
+++ b/content/browser/web_database/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail {
+  component: "Blink>Storage>WebSQL"
+}
+team_email: "storage-dev@chromium.org"
diff --git a/content/browser/web_database/OWNERS b/content/browser/web_database/OWNERS
new file mode 100644
index 0000000..57475828
--- /dev/null
+++ b/content/browser/web_database/OWNERS
@@ -0,0 +1 @@
+file://storage/browser/database/OWNERS
diff --git a/content/browser/renderer_host/web_database_host_impl.cc b/content/browser/web_database/web_database_host_impl.cc
similarity index 99%
rename from content/browser/renderer_host/web_database_host_impl.cc
rename to content/browser/web_database/web_database_host_impl.cc
index daed545..f9b489da 100644
--- a/content/browser/renderer_host/web_database_host_impl.cc
+++ b/content/browser/web_database/web_database_host_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/renderer_host/web_database_host_impl.h"
+#include "content/browser/web_database/web_database_host_impl.h"
 
 #include <string>
 #include <utility>
@@ -27,8 +27,8 @@
 #include "url/origin.h"
 
 using storage::DatabaseUtil;
-using storage::VfsBackend;
 using storage::QuotaManager;
+using storage::VfsBackend;
 
 namespace content {
 namespace {
diff --git a/content/browser/renderer_host/web_database_host_impl.h b/content/browser/web_database/web_database_host_impl.h
similarity index 96%
rename from content/browser/renderer_host/web_database_host_impl.h
rename to content/browser/web_database/web_database_host_impl.h
index 4c14a76..29d52aaa 100644
--- a/content/browser/renderer_host/web_database_host_impl.h
+++ b/content/browser/web_database/web_database_host_impl.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_BROWSER_RENDERER_HOST_WEB_DATABASE_HOST_IMPL_H_
-#define CONTENT_BROWSER_RENDERER_HOST_WEB_DATABASE_HOST_IMPL_H_
+#ifndef CONTENT_BROWSER_WEB_DATABASE_WEB_DATABASE_HOST_IMPL_H_
+#define CONTENT_BROWSER_WEB_DATABASE_WEB_DATABASE_HOST_IMPL_H_
 
 #include <string>
 
@@ -162,4 +162,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_BROWSER_RENDERER_HOST_WEB_DATABASE_HOST_IMPL_H_
+#endif  // CONTENT_BROWSER_WEB_DATABASE_WEB_DATABASE_HOST_IMPL_H_
diff --git a/content/browser/renderer_host/web_database_host_impl_unittest.cc b/content/browser/web_database/web_database_host_impl_unittest.cc
similarity index 98%
rename from content/browser/renderer_host/web_database_host_impl_unittest.cc
rename to content/browser/web_database/web_database_host_impl_unittest.cc
index dac2cae35..27ddfedc 100644
--- a/content/browser/renderer_host/web_database_host_impl_unittest.cc
+++ b/content/browser/web_database/web_database_host_impl_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/renderer_host/web_database_host_impl.h"
+#include "content/browser/web_database/web_database_host_impl.h"
 
 #include "base/bind.h"
 #include "base/run_loop.h"
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 7390c0e..313bd09 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1981,7 +1981,6 @@
     "../browser/renderer_host/render_widget_host_view_aura_unittest.cc",
     "../browser/renderer_host/render_widget_host_view_base_unittest.cc",
     "../browser/renderer_host/render_widget_host_view_child_frame_unittest.cc",
-    "../browser/renderer_host/web_database_host_impl_unittest.cc",
     "../browser/scheduler/browser_io_thread_delegate_unittest.cc",
     "../browser/scheduler/browser_task_executor_unittest.cc",
     "../browser/scheduler/browser_task_queues_unittest.cc",
@@ -2036,6 +2035,7 @@
     "../browser/web_contents/web_contents_impl_unittest.cc",
     "../browser/web_contents/web_contents_user_data_unittest.cc",
     "../browser/web_contents/web_contents_view_aura_unittest.cc",
+    "../browser/web_database/web_database_host_impl_unittest.cc",
     "../browser/web_package/signed_exchange_cert_fetcher_unittest.cc",
     "../browser/web_package/signed_exchange_certificate_chain_unittest.cc",
     "../browser/web_package/signed_exchange_envelope_unittest.cc",
diff --git a/content/web_test/browser/web_test_control_host.cc b/content/web_test/browser/web_test_control_host.cc
index 9c85cad..2012155 100644
--- a/content/web_test/browser/web_test_control_host.cc
+++ b/content/web_test/browser/web_test_control_host.cc
@@ -1091,7 +1091,7 @@
   main_window_render_view_hosts_.erase(render_view_host);
 }
 
-void WebTestControlHost::DidFinishNavigation(
+void WebTestControlHost::ReadyToCommitNavigation(
     NavigationHandle* navigation_handle) {
   NavigationRequest* request = NavigationRequest::From(navigation_handle);
   RenderFrameHostImpl* rfh = request->rfh_restored_from_back_forward_cache();
diff --git a/content/web_test/browser/web_test_control_host.h b/content/web_test/browser/web_test_control_host.h
index 87aabadf..5c643fd 100644
--- a/content/web_test/browser/web_test_control_host.h
+++ b/content/web_test/browser/web_test_control_host.h
@@ -162,7 +162,7 @@
   void RenderViewHostChanged(RenderViewHost* old_host,
                              RenderViewHost* new_host) override;
   void RenderViewDeleted(RenderViewHost* render_view_host) override;
-  void DidFinishNavigation(NavigationHandle* navigation_handle) override;
+  void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override;
 
   // RenderProcessHostObserver implementation.
   void RenderProcessHostDestroyed(
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index e0131b61..8009d25d 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -3490,21 +3490,6 @@
       ]
     },
     {
-      "id": 349,
-      "cr_bugs": [1126058],
-      "description": "VP8 decoding hangs on Intel Broadwell",
-      "os": {
-        "type": "chromeos"
-      },
-      "vendor_id": "0x8086",
-      "intel_gpu_series": [
-        "broadwell"
-      ],
-      "features": [
-        "disable_accelerated_vp8_decode"
-      ]
-    },
-    {
       "id": 352,
       "cr_bugs": [1038006],
       "description": "Intel device 0x1066 can't use d3d11 video decoder",
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index a15a53e..1035a261 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -250,6 +250,7 @@
     "//headless:headless",
     "//headless:headless_non_renderer",
   ]
+  defines = []
 
   sources = [
     "app/headless_shell_switches.cc",
@@ -298,6 +299,10 @@
   }
 
   configs += [ ":inside_headless_component" ]
+
+  if (headless_use_prefs) {
+    defines += [ "HEADLESS_USE_PREFS" ]
+  }
 }
 
 # Code that is needed in a renderer process.
@@ -595,6 +600,7 @@
     "public/domains/types_unittest.cc",
     "public/util/error_reporter_unittest.cc",
   ]
+  defines = []
 
   deps = [
     ":headless_shell_lib",
@@ -612,6 +618,10 @@
     deps += [ "//components/crash/core/app:crash_export_thunks" ]
   }
 
+  if (headless_use_prefs) {
+    defines += [ "HEADLESS_USE_PREFS" ]
+  }
+
   if (enable_basic_printing) {
     sources += [ "lib/browser/headless_printing_unittest.cc" ]
     deps += [
@@ -735,6 +745,7 @@
     "app/headless_shell.h",
     "public/headless_shell.h",
   ]
+  defines = []
 
   if (!is_component_build) {
     sources += [
@@ -788,6 +799,10 @@
   if (is_mac) {
     deps += [ "//components/os_crypt" ]
   }
+
+  if (headless_use_prefs) {
+    defines += [ "HEADLESS_USE_PREFS" ]
+  }
 }
 
 if (is_fuchsia) {
@@ -805,6 +820,7 @@
 
 executable("headless_shell") {
   sources = [ "app/headless_shell_main.cc" ]
+  defines = []
 
   deps = [ ":headless_shell_lib" ]
 
@@ -819,6 +835,10 @@
   if (is_mac) {
     deps += [ "//sandbox/mac:seatbelt" ]
   }
+
+  if (headless_use_prefs) {
+    defines += [ "HEADLESS_USE_PREFS" ]
+  }
 }
 
 process_version("version_header") {
@@ -832,9 +852,14 @@
 
 executable("headless_example") {
   sources = [ "app/headless_example.cc" ]
+  defines = []
 
   deps = [
     ":headless_shell_lib",
     "//skia",  # we need this to override font render hinting in headless build
   ]
+
+  if (headless_use_prefs) {
+    defines += [ "HEADLESS_USE_PREFS" ]
+  }
 }
diff --git a/headless/lib/DEPS b/headless/lib/DEPS
index aeaf64994..6461c338 100644
--- a/headless/lib/DEPS
+++ b/headless/lib/DEPS
@@ -5,12 +5,8 @@
   "headless_content_client.cc": [
       "+components/embedder_support/origin_trials",
   ],
-  "headless_content_main_delegate.h": [
-    "+components/prefs",
-  ],
   "headless_content_main_delegate.cc": [
     "+cc/base/switches.h",
-    "+components/prefs",
     "+components/viz/common/switches.h",
     "+gpu/config/gpu_switches.h",
     "+third_party/blink/public/common/switches.h",
diff --git a/headless/lib/browser/DEPS b/headless/lib/browser/DEPS
index e052a7dc..db588fe6 100644
--- a/headless/lib/browser/DEPS
+++ b/headless/lib/browser/DEPS
@@ -18,3 +18,11 @@
   "+ui/compositor",
   "+ui/events/keycodes/dom",
 ]
+specific_include_rules = {
+  "headless_browser_main_parts.h": [
+    "+components/prefs",
+  ],
+  "headless_browser_main_parts.cc": [
+    "+components/prefs",
+  ],
+}
diff --git a/headless/lib/browser/headless_browser_main_parts.cc b/headless/lib/browser/headless_browser_main_parts.cc
index 040737d..70f0415 100644
--- a/headless/lib/browser/headless_browser_main_parts.cc
+++ b/headless/lib/browser/headless_browser_main_parts.cc
@@ -9,8 +9,23 @@
 #include "headless/lib/browser/headless_devtools.h"
 #include "headless/lib/browser/headless_screen.h"
 
+#if defined(HEADLESS_USE_PREFS)
+#include "components/os_crypt/os_crypt.h"
+#include "components/prefs/json_pref_store.h"
+#include "components/prefs/pref_service_factory.h"
+#endif
+
 namespace headless {
 
+namespace {
+
+#if defined(HEADLESS_USE_PREFS)
+const base::FilePath::CharType kLocalStateFilename[] =
+    FILE_PATH_LITERAL("Local State");
+#endif
+
+}  // namespace
+
 HeadlessBrowserMainParts::HeadlessBrowserMainParts(
     const content::MainFunctionParams& parameters,
     HeadlessBrowserImpl* browser)
@@ -19,6 +34,9 @@
 HeadlessBrowserMainParts::~HeadlessBrowserMainParts() = default;
 
 void HeadlessBrowserMainParts::PreMainMessageLoopRun() {
+#if defined(HEADLESS_USE_PREFS)
+  CreatePrefService();
+#endif
   if (browser_->options()->DevtoolsServerEnabled()) {
     StartLocalDevToolsHttpHandler(browser_);
     devtools_http_handler_started_ = true;
@@ -47,6 +65,10 @@
     StopLocalDevToolsHttpHandler();
     devtools_http_handler_started_ = false;
   }
+#if defined(HEADLESS_USE_PREFS)
+  if (local_state_)
+    local_state_->CommitPendingWrite();
+#endif
 }
 
 void HeadlessBrowserMainParts::QuitMainMessageLoop() {
@@ -54,4 +76,33 @@
     std::move(quit_main_message_loop_).Run();
 }
 
+#if defined(HEADLESS_USE_PREFS)
+void HeadlessBrowserMainParts::CreatePrefService() {
+  if (browser_->options()->user_data_dir.empty()) {
+    LOG(WARNING) << "Cannot create Pref Service with no user data dir.";
+    return;
+  }
+
+  base::FilePath local_state_file =
+      browser_->options()->user_data_dir.Append(kLocalStateFilename);
+  auto pref_store = base::MakeRefCounted<JsonPrefStore>(local_state_file);
+  auto result = pref_store->ReadPrefs();
+  CHECK(result == JsonPrefStore::PREF_READ_ERROR_NONE ||
+        result == JsonPrefStore::PREF_READ_ERROR_NO_FILE);
+
+  auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
+#if defined(OS_WIN)
+  OSCrypt::RegisterLocalPrefs(pref_registry.get());
+#endif
+
+  PrefServiceFactory factory;
+  factory.set_user_prefs(pref_store);
+  local_state_ = factory.Create(std::move(pref_registry));
+
+#if defined(OS_WIN)
+  CHECK(OSCrypt::Init(local_state_.get()));
+#endif
+}
+#endif  // defined(HEADLESS_USE_PREFS)
+
 }  // namespace headless
diff --git a/headless/lib/browser/headless_browser_main_parts.h b/headless/lib/browser/headless_browser_main_parts.h
index 1bc2192..e1a531c9 100644
--- a/headless/lib/browser/headless_browser_main_parts.h
+++ b/headless/lib/browser/headless_browser_main_parts.h
@@ -13,6 +13,11 @@
 #include "content/public/common/main_function_params.h"
 #include "headless/public/headless_browser.h"
 
+#if defined(HEADLESS_USE_PREFS)
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+#endif
+
 namespace headless {
 
 class HeadlessBrowserImpl;
@@ -38,9 +43,17 @@
   void QuitMainMessageLoop();
 
  private:
+#if defined(HEADLESS_USE_PREFS)
+  void CreatePrefService();
+#endif
+
   const content::MainFunctionParams parameters_;  // For running browser tests.
   HeadlessBrowserImpl* browser_;  // Not owned.
 
+#if defined(HEADLESS_USE_PREFS)
+  std::unique_ptr<PrefService> local_state_;
+#endif
+
   bool run_message_loop_ = true;
   bool devtools_http_handler_started_ = false;
   base::OnceClosure quit_main_message_loop_;
diff --git a/headless/lib/headless_content_main_delegate.cc b/headless/lib/headless_content_main_delegate.cc
index 82cdf33..d0cc96d2 100644
--- a/headless/lib/headless_content_main_delegate.cc
+++ b/headless/lib/headless_content_main_delegate.cc
@@ -47,12 +47,6 @@
 #include "headless/embedded_resource_pak.h"
 #endif
 
-#if defined(HEADLESS_USE_PREFS)
-#include "components/os_crypt/os_crypt.h"
-#include "components/prefs/json_pref_store.h"
-#include "components/prefs/pref_service_factory.h"
-#endif
-
 #if defined(OS_MAC) || defined(OS_WIN)
 #include "components/crash/core/app/crashpad.h"
 #endif
@@ -75,11 +69,6 @@
 const base::FilePath::CharType kDefaultProfileName[] =
     FILE_PATH_LITERAL("Default");
 
-#if defined(HEADLESS_USE_PREFS)
-const base::FilePath::CharType kLocalStateFilename[] =
-    FILE_PATH_LITERAL("Local State");
-#endif
-
 namespace {
 
 // Keep in sync with content/common/content_constants_internal.h.
@@ -495,9 +484,6 @@
 
 void HeadlessContentMainDelegate::PostEarlyInitialization(
     bool is_running_tests) {
-#if defined(HEADLESS_USE_PREFS)
-  CreatePrefService();
-#endif
   if (base::FeatureList::IsEnabled(features::kVirtualTime)) {
     // Only pass viz flags into the virtual time mode.
     const char* const switches[] = {
@@ -524,33 +510,4 @@
   }
 }
 
-#if defined(HEADLESS_USE_PREFS)
-void HeadlessContentMainDelegate::CreatePrefService() {
-  if (options()->user_data_dir.empty()) {
-    LOG(WARNING) << "Cannot create Pref Service with no user data dir.";
-    return;
-  }
-
-  base::FilePath local_state_file =
-      options()->user_data_dir.Append(kLocalStateFilename);
-  auto pref_store = base::MakeRefCounted<JsonPrefStore>(local_state_file);
-  auto result = pref_store->ReadPrefs();
-  CHECK(result == JsonPrefStore::PREF_READ_ERROR_NONE ||
-        result == JsonPrefStore::PREF_READ_ERROR_NO_FILE);
-
-  auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
-#if defined(OS_WIN)
-  OSCrypt::RegisterLocalPrefs(pref_registry.get());
-#endif
-
-  PrefServiceFactory factory;
-  factory.set_user_prefs(pref_store);
-  local_state_ = factory.Create(std::move(pref_registry));
-
-#if defined(OS_WIN)
-  CHECK(OSCrypt::Init(local_state_.get()));
-#endif
-}
-#endif  // defined(HEADLESS_USE_PREFS)
-
 }  // namespace headless
diff --git a/headless/lib/headless_content_main_delegate.h b/headless/lib/headless_content_main_delegate.h
index a2cf6a11..914c3b0f 100644
--- a/headless/lib/headless_content_main_delegate.h
+++ b/headless/lib/headless_content_main_delegate.h
@@ -19,11 +19,6 @@
 #include "headless/public/headless_browser.h"
 #include "headless/public/headless_export.h"
 
-#if defined(HEADLESS_USE_PREFS)
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
-#endif
-
 namespace base {
 namespace debug {
 struct CrashKeyString;
@@ -78,10 +73,6 @@
   void InitLogging(const base::CommandLine& command_line);
   void InitCrashReporter(const base::CommandLine& command_line);
 
-#if defined(HEADLESS_USE_PREFS)
-  void CreatePrefService();
-#endif
-
   std::unique_ptr<content::ContentRendererClient> renderer_client_;
   std::unique_ptr<content::ContentBrowserClient> browser_client_;
   std::unique_ptr<content::ContentUtilityClient> utility_client_;
@@ -91,10 +82,6 @@
   std::unique_ptr<HeadlessBrowserImpl> browser_;
   std::unique_ptr<HeadlessBrowser::Options> options_;
 
-#if defined(HEADLESS_USE_PREFS)
-  std::unique_ptr<PrefService> local_state_;
-#endif
-
   base::debug::CrashKeyString* headless_crash_key_;  // Note: never deallocated.
 
   DISALLOW_COPY_AND_ASSIGN(HeadlessContentMainDelegate);
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/OWNERS b/ios/chrome/browser/crash_report/breadcrumbs/OWNERS
index a01ab6c..49ba79e 100644
--- a/ios/chrome/browser/crash_report/breadcrumbs/OWNERS
+++ b/ios/chrome/browser/crash_report/breadcrumbs/OWNERS
@@ -1,2 +1 @@
-eugenebut@chromium.org
 michaeldo@chromium.org
diff --git a/ios/chrome/browser/ui/webui/OWNERS b/ios/chrome/browser/ui/webui/OWNERS
index be9def2..9f34ba0 100644
--- a/ios/chrome/browser/ui/webui/OWNERS
+++ b/ios/chrome/browser/ui/webui/OWNERS
@@ -1,4 +1,3 @@
-eugenebut@chromium.org
 michaeldo@chromium.org
 
 per-file ntp_tiles_internals_ui.*=file://components/ntp_tiles/OWNERS
diff --git a/ios/chrome/browser/webui/OWNERS b/ios/chrome/browser/webui/OWNERS
index a01ab6c..49ba79e 100644
--- a/ios/chrome/browser/webui/OWNERS
+++ b/ios/chrome/browser/webui/OWNERS
@@ -1,2 +1 @@
-eugenebut@chromium.org
 michaeldo@chromium.org
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 b4c7192..e1660b9b 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 @@
-61a41247c8b575d32eff6adffe980e7cfa9d94a0
\ No newline at end of file
+58355486e162e5a13e4ddfdadd0ad5e73bfa82e6
\ 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 22d8da4..284cf79 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 @@
-8f996fd0345acb838f118456aaad0ecc665a8de0
\ No newline at end of file
+eff1c35d73712436168f81db6b17403933f6245c
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
index 958afcf..f65c9594 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-87baf92549d20f860376b60811632a7e7e87b96b
\ No newline at end of file
+4ab58e748a4d05da3f6b34b0f207f13faf2a89f7
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
index 77e1be2..c2d6387 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-1b48a2b1fac3c8e2dcbc5e8b6fad3f435caa72c1
\ No newline at end of file
+45adaab859b4b79c7381eb4a96f5e9fd7e2636f2
\ 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 8c6251e..43c0c24d 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 @@
-e4881473abd22e7525e80bd1dccb6771e4c94a59
\ No newline at end of file
+d9e5b55ec25c9c77d65a1011f37d8db412578d0a
\ 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 0365200..e2198208 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 @@
-31d62a5cdd8095e35d21a554bc6128c2b7d31098
\ No newline at end of file
+d520eddf76b096e84ebade69916436ec837e66ae
\ 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 5eefab06..0a2cbbc 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 @@
-f04137a2f2e2f345ac40e19ed2aedbab39cc6118
\ No newline at end of file
+b543993be9b500c4ebe6a8b212f1169eb88fc597
\ 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 7c1b4e87..36982084 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 @@
-cf822754cc1f255ae007a113391174d53840c3cb
\ No newline at end of file
+60cfa56d81f98f7f1dda6eb8764a84e5af000a31
\ 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 4623d86..576e2d2 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 @@
-f1e32c4dfa94487c7284f045dadc5495aaf27d7e
\ No newline at end of file
+57d3ad3520ccc9482bdd3badccf0011ed47fe664
\ 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 5fe8059..52c4c5e 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 @@
-afafe02d61dd32d27aecf37cdb526c8bd5c7dd6e
\ No newline at end of file
+07082bf638e4331c2dc7577d98ab5deecd6f3918
\ No newline at end of file
diff --git a/ios/web_view/OWNERS b/ios/web_view/OWNERS
index a0fe38a..b231a11 100644
--- a/ios/web_view/OWNERS
+++ b/ios/web_view/OWNERS
@@ -1,4 +1,3 @@
-eugenebut@chromium.org
 ichikawa@chromium.org
 jzw@chromium.org
 michaeldo@chromium.org
diff --git a/media/gpu/chromeos/chromeos_video_decoder_factory.cc b/media/gpu/chromeos/chromeos_video_decoder_factory.cc
index 8a2d1933..04b8f52b 100644
--- a/media/gpu/chromeos/chromeos_video_decoder_factory.cc
+++ b/media/gpu/chromeos/chromeos_video_decoder_factory.cc
@@ -27,14 +27,17 @@
 
 // Gets a list of the available functions for creating VideoDecoders.
 VideoDecoderPipeline::CreateDecoderFunctions GetCreateDecoderFunctions() {
+  // Usually only one of USE_VAAPI or USE_V4L2_CODEC is defined on ChromeOS,
+  // except for Chromeboxes with companion video acceleration chips, which have
+  // both. In those cases prefer the V4L2 creation function.
   constexpr VideoDecoderPipeline::CreateDecoderFunction kCreateVDFuncs[] = {
-#if BUILDFLAG(USE_VAAPI)
-    &VaapiVideoDecoder::Create,
-#endif  // BUILDFLAG(USE_VAAPI)
-
 #if BUILDFLAG(USE_V4L2_CODEC)
     &V4L2VideoDecoder::Create,
 #endif  // BUILDFLAG(USE_V4L2_CODEC)
+
+#if BUILDFLAG(USE_VAAPI)
+    &VaapiVideoDecoder::Create,
+#endif  // BUILDFLAG(USE_VAAPI)
   };
 
   return VideoDecoderPipeline::CreateDecoderFunctions(
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc
index 37cf3a0..7f4e0eb 100644
--- a/media/gpu/gpu_video_decode_accelerator_factory.cc
+++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
@@ -142,13 +142,17 @@
 #if defined(OS_WIN)
     &GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA,
 #endif
-#if BUILDFLAG(USE_VAAPI)
-    &GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA,
-#endif
+  // Usually only one of USE_VAAPI or USE_V4L2_CODEC is defined on ChromeOS,
+  // except for Chromeboxes with companion video acceleration chips, which have
+  // both. In those cases prefer the V4L2 creation function.
 #if BUILDFLAG(USE_V4L2_CODEC)
     &GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA,
     &GpuVideoDecodeAcceleratorFactory::CreateV4L2SVDA,
 #endif
+#if BUILDFLAG(USE_VAAPI)
+    &GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA,
+#endif
+
 #if defined(OS_MAC)
     &GpuVideoDecodeAcceleratorFactory::CreateVTVDA,
 #endif
diff --git a/net/base/mock_network_change_notifier.cc b/net/base/mock_network_change_notifier.cc
index 32582e1c..ec0c271 100644
--- a/net/base/mock_network_change_notifier.cc
+++ b/net/base/mock_network_change_notifier.cc
@@ -93,12 +93,20 @@
   base::RunLoop().RunUntilIdle();
 }
 
+MockNetworkChangeNotifier::ConnectionCost
+MockNetworkChangeNotifier::GetCurrentConnectionCost() {
+  if (use_default_connection_cost_implementation_)
+    return NetworkChangeNotifier::GetCurrentConnectionCost();
+  return connection_cost_;
+}
+
 MockNetworkChangeNotifier::MockNetworkChangeNotifier(
     std::unique_ptr<SystemDnsConfigChangeNotifier> dns_config_notifier)
     : NetworkChangeNotifier(NetworkChangeCalculatorParams(),
                             dns_config_notifier.get()),
       force_network_handles_supported_(false),
       connection_type_(CONNECTION_UNKNOWN),
+      connection_cost_(CONNECTION_COST_UNKNOWN),
       dns_config_notifier_(std::move(dns_config_notifier)) {}
 
 ScopedMockNetworkChangeNotifier::ScopedMockNetworkChangeNotifier()
diff --git a/net/base/mock_network_change_notifier.h b/net/base/mock_network_change_notifier.h
index cd939b3..24e01598 100644
--- a/net/base/mock_network_change_notifier.h
+++ b/net/base/mock_network_change_notifier.h
@@ -53,6 +53,30 @@
 
   void SetConnectionTypeAndNotifyObservers(ConnectionType connection_type);
 
+  // Sets the cached value of the connection cost. If
+  // use_default_connection_cost_implementation is set to true, this value gets
+  // ignored.
+  void SetConnectionCost(ConnectionCost connection_cost) {
+    connection_cost_ = connection_cost;
+  }
+
+  // Tells this class to ignore its cached connection cost value and instead
+  // call the base class's implementation. This is intended to allow tests to
+  // mock the product code's fallback to the default implementation in certain
+  // situations. For example, the APIs to support this functionality exist on
+  // Win10 only so it falls back to the default on Win7, so this function allows
+  // tests to validate the default implementation's behavior on Win10 machines.
+  void SetUseDefaultConnectionCostImplementation(
+      bool use_default_connection_cost_implementation) {
+    use_default_connection_cost_implementation_ =
+        use_default_connection_cost_implementation;
+  }
+
+  // Returns either the cached connection cost value or the default
+  // implementation's result, depending on whether
+  // use_default_connection_cost_implementation is set to true.
+  ConnectionCost GetCurrentConnectionCost() override;
+
  private:
   // Create using MockNetworkChangeNotifier::Create().
   MockNetworkChangeNotifier(
@@ -60,6 +84,8 @@
 
   bool force_network_handles_supported_;
   ConnectionType connection_type_;
+  ConnectionCost connection_cost_;
+  bool use_default_connection_cost_implementation_ = false;
   NetworkChangeNotifier::NetworkList connected_networks_;
   std::unique_ptr<SystemDnsConfigChangeNotifier> dns_config_notifier_;
 };
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
index d786914..7e7c64c 100644
--- a/net/base/network_change_notifier.cc
+++ b/net/base/network_change_notifier.cc
@@ -259,6 +259,14 @@
 }
 
 // static
+NetworkChangeNotifier::ConnectionCost
+NetworkChangeNotifier::GetConnectionCost() {
+  return g_network_change_notifier
+             ? g_network_change_notifier->GetCurrentConnectionCost()
+             : CONNECTION_COST_UNKNOWN;
+}
+
+// static
 NetworkChangeNotifier::ConnectionType
 NetworkChangeNotifier::GetConnectionType() {
   return g_network_change_notifier ?
@@ -541,6 +549,11 @@
 NetworkChangeNotifier::NetworkObserver::NetworkObserver() = default;
 NetworkChangeNotifier::NetworkObserver::~NetworkObserver() = default;
 
+NetworkChangeNotifier::ConnectionCostObserver::ConnectionCostObserver() =
+    default;
+NetworkChangeNotifier::ConnectionCostObserver::~ConnectionCostObserver() =
+    default;
+
 void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver* observer) {
   if (g_network_change_notifier &&
       g_network_change_notifier->can_add_observers_) {
@@ -599,6 +612,17 @@
   }
 }
 
+void NetworkChangeNotifier::AddConnectionCostObserver(
+    ConnectionCostObserver* observer) {
+  if (g_network_change_notifier &&
+      g_network_change_notifier->can_add_observers_) {
+    observer->observer_list_ =
+        g_network_change_notifier->connection_cost_observer_list_;
+    observer->observer_list_->AddObserver(observer);
+    g_network_change_notifier->ConnectionCostObserverAdded();
+  }
+}
+
 void NetworkChangeNotifier::RemoveIPAddressObserver(
     IPAddressObserver* observer) {
   if (observer->observer_list_) {
@@ -645,6 +669,14 @@
   }
 }
 
+void NetworkChangeNotifier::RemoveConnectionCostObserver(
+    ConnectionCostObserver* observer) {
+  if (observer->observer_list_) {
+    observer->observer_list_->RemoveObserver(observer);
+    observer->observer_list_.reset();
+  }
+}
+
 void NetworkChangeNotifier::TriggerNonSystemDnsChange() {
   NetworkChangeNotifier::NotifyObserversOfDNSChange();
 }
@@ -686,6 +718,13 @@
 }
 
 // static
+void NetworkChangeNotifier::NotifyObserversOfConnectionCostChangeForTests(
+    ConnectionCost cost) {
+  if (g_network_change_notifier)
+    g_network_change_notifier->NotifyObserversOfConnectionCostChangeImpl(cost);
+}
+
+// static
 void NetworkChangeNotifier::SetTestNotificationsOnly(bool test_only) {
   DCHECK(!g_network_change_notifier);
   NetworkChangeNotifier::test_notifications_only_ = test_only;
@@ -713,6 +752,9 @@
               base::ObserverListPolicy::EXISTING_ONLY)),
       network_observer_list_(new base::ObserverListThreadSafe<NetworkObserver>(
           base::ObserverListPolicy::EXISTING_ONLY)),
+      connection_cost_observer_list_(
+          new base::ObserverListThreadSafe<ConnectionCostObserver>(
+              base::ObserverListPolicy::EXISTING_ONLY)),
       system_dns_config_notifier_(system_dns_config_notifier),
       system_dns_config_observer_(std::make_unique<SystemDnsConfigObserver>()),
       network_change_calculator_(new NetworkChangeCalculator(params)),
@@ -738,6 +780,16 @@
 }
 #endif
 
+NetworkChangeNotifier::ConnectionCost
+NetworkChangeNotifier::GetCurrentConnectionCost() {
+  // This is the default non-platform specific implementation and assumes that
+  // cellular connectivity is metered and non-cellular is not. The function can
+  // be specialized on each platform specific notifier implementation.
+  return IsConnectionCellular(GetCurrentConnectionType())
+             ? CONNECTION_COST_METERED
+             : CONNECTION_COST_UNMETERED;
+}
+
 NetworkChangeNotifier::ConnectionSubtype
 NetworkChangeNotifier::GetCurrentConnectionSubtype() const {
   return SUBTYPE_UNKNOWN;
@@ -838,6 +890,15 @@
   }
 }
 
+// static
+void NetworkChangeNotifier::NotifyObserversOfConnectionCostChange() {
+  if (g_network_change_notifier &&
+      !NetworkChangeNotifier::test_notifications_only_) {
+    g_network_change_notifier->NotifyObserversOfConnectionCostChangeImpl(
+        GetConnectionCost());
+  }
+}
+
 void NetworkChangeNotifier::StopSystemDnsConfigNotifier() {
   if (!system_dns_config_notifier_)
     return;
@@ -900,6 +961,12 @@
   }
 }
 
+void NetworkChangeNotifier::NotifyObserversOfConnectionCostChangeImpl(
+    ConnectionCost cost) {
+  connection_cost_observer_list_->Notify(
+      FROM_HERE, &ConnectionCostObserver::OnConnectionCostChanged, cost);
+}
+
 NetworkChangeNotifier::DisableForTest::DisableForTest()
     : network_change_notifier_(g_network_change_notifier) {
   DCHECK(g_network_change_notifier);
diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h
index 6f36e194..577c2bc 100644
--- a/net/base/network_change_notifier.h
+++ b/net/base/network_change_notifier.h
@@ -105,6 +105,12 @@
     SUBTYPE_LAST = SUBTYPE_WIFI_AD
   };
 
+  enum ConnectionCost {
+    CONNECTION_COST_UNKNOWN = 0,
+    CONNECTION_COST_UNMETERED,
+    CONNECTION_COST_METERED,
+  };
+
   // DEPRECATED. Please use NetworkChangeObserver instead. crbug.com/754695.
   class NET_EXPORT IPAddressObserver {
    public:
@@ -228,6 +234,33 @@
         observer_list_;
   };
 
+  class NET_EXPORT ConnectionCostObserver {
+   public:
+    // Not copyable or movable
+    ConnectionCostObserver(const ConnectionCostObserver&) = delete;
+    ConnectionCostObserver& operator=(const ConnectionCostObserver&) = delete;
+
+    // Will be called when the connection cost of the default network connection
+    // of the system has changed. This will only fire if the connection cost
+    // actually changes, regardless of any other network-related changes that
+    // might have occurred (for example, changing from ethernet to wifi won't
+    // update this unless that change also results in a cost change). The cost
+    // is not tied directly to any other network-related states, as you could
+    // simply change the current connection from unmetered to metered. It is
+    // safe to assume that network traffic will default to this cost once this
+    // has fired.
+    virtual void OnConnectionCostChanged(ConnectionCost Cost) = 0;
+
+   protected:
+    ConnectionCostObserver();
+    virtual ~ConnectionCostObserver();
+
+   private:
+    friend NetworkChangeNotifier;
+    scoped_refptr<base::ObserverListThreadSafe<ConnectionCostObserver>>
+        observer_list_;
+  };
+
   // Opaque handle for device-wide connection to a particular network. For
   // example an association with a particular WiFi network with a particular
   // SSID or a connection to particular cellular network.
@@ -300,6 +333,12 @@
       NetworkChangeNotifier::ConnectionType initial_type = CONNECTION_NONE,
       NetworkChangeNotifier::ConnectionSubtype initial_subtype = SUBTYPE_NONE);
 
+  // Returns the most likely cost attribute for the default network connection.
+  // The value does not indicate with absolute certainty if using the connection
+  // will or will not incur a monetary cost to the user. It is a best guess
+  // based on Operating System information and network interface type.
+  static ConnectionCost GetConnectionCost();
+
   // Returns the connection type.
   // A return value of |CONNECTION_NONE| is a pretty strong indicator that the
   // user won't be able to connect to remote sites. However, another return
@@ -425,6 +464,7 @@
   static void AddNetworkChangeObserver(NetworkChangeObserver* observer);
   static void AddMaxBandwidthObserver(MaxBandwidthObserver* observer);
   static void AddNetworkObserver(NetworkObserver* observer);
+  static void AddConnectionCostObserver(ConnectionCostObserver* observer);
 
   // Unregisters |observer| from receiving notifications.  This must be called
   // on the same thread on which AddObserver() was called.  Like AddObserver(),
@@ -444,6 +484,7 @@
   static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer);
   static void RemoveMaxBandwidthObserver(MaxBandwidthObserver* observer);
   static void RemoveNetworkObserver(NetworkObserver* observer);
+  static void RemoveConnectionCostObserver(ConnectionCostObserver* observer);
 
   // Called to signify a non-system DNS config change.
   static void TriggerNonSystemDnsChange();
@@ -457,6 +498,8 @@
   static void NotifyObserversOfMaxBandwidthChangeForTests(
       double max_bandwidth_mbps,
       ConnectionType type);
+  static void NotifyObserversOfConnectionCostChangeForTests(
+      ConnectionCost cost);
 
   // Enable or disable notifications from the host. After setting to true, be
   // sure to pump the RunLoop until idle to finish any preexisting
@@ -539,6 +582,7 @@
   // See the description of the corresponding functions named without "Current".
   // Implementations must be thread-safe. Implementations must also be
   // cheap as they are called often.
+  virtual ConnectionCost GetCurrentConnectionCost();
   virtual ConnectionType GetCurrentConnectionType() const = 0;
   virtual ConnectionSubtype GetCurrentConnectionSubtype() const;
   virtual void GetCurrentMaxBandwidthAndConnectionType(
@@ -562,6 +606,7 @@
                                                   ConnectionType type);
   static void NotifyObserversOfSpecificNetworkChange(NetworkChangeType type,
                                                      NetworkHandle network);
+  static void NotifyObserversOfConnectionCostChange();
 
   // Infer connection type from |GetNetworkList|. If all network interfaces
   // have the same type, return it, otherwise return CONNECTION_UNKNOWN.
@@ -575,6 +620,13 @@
   // as early as possible in the destructor to prevent races.
   void ClearGlobalPointer();
 
+  // Called whenever a new ConnectionCostObserver is added. This method is
+  // needed so that the implementation class can be notified and
+  // potentially take action when an observer gets added. Since the act of
+  // adding an observer and the observer list itself are both static, the
+  // implementation class has no direct capability to watch for changes.
+  virtual void ConnectionCostObserverAdded() {}
+
  private:
   friend class HostResolverManagerDnsTest;
   friend class NetworkChangeNotifierAndroidTest;
@@ -592,6 +644,7 @@
                                                ConnectionType type);
   void NotifyObserversOfSpecificNetworkChangeImpl(NetworkChangeType type,
                                                   NetworkHandle network);
+  void NotifyObserversOfConnectionCostChangeImpl(ConnectionCost cost);
 
   const scoped_refptr<base::ObserverListThreadSafe<IPAddressObserver>>
       ip_address_observer_list_;
@@ -605,6 +658,8 @@
       max_bandwidth_observer_list_;
   const scoped_refptr<base::ObserverListThreadSafe<NetworkObserver>>
       network_observer_list_;
+  const scoped_refptr<base::ObserverListThreadSafe<ConnectionCostObserver>>
+      connection_cost_observer_list_;
 
   SystemDnsConfigChangeNotifier* system_dns_config_notifier_;
   std::unique_ptr<SystemDnsConfigObserver> system_dns_config_observer_;
diff --git a/net/base/network_change_notifier_unittest.cc b/net/base/network_change_notifier_unittest.cc
index b5c2d86..81b5b49 100644
--- a/net/base/network_change_notifier_unittest.cc
+++ b/net/base/network_change_notifier_unittest.cc
@@ -198,7 +198,7 @@
 }
 
 class NetworkChangeNotifierMockedTest : public TestWithTaskEnvironment {
- private:
+ protected:
   test::ScopedMockNetworkChangeNotifier mock_notifier_;
 };
 
@@ -226,4 +226,92 @@
   NetworkChangeNotifier::RemoveDNSObserver(&observer);
 }
 
+class TestConnectionCostObserver
+    : public NetworkChangeNotifier::ConnectionCostObserver {
+ public:
+  void OnConnectionCostChanged(
+      NetworkChangeNotifier::ConnectionCost cost) override {
+    cost_changed_inputs_.push_back(cost);
+    ++cost_changed_calls_;
+  }
+
+  int cost_changed_calls() const { return cost_changed_calls_; }
+  std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs()
+      const {
+    return cost_changed_inputs_;
+  }
+
+ private:
+  int cost_changed_calls_ = 0;
+  std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs_;
+};
+
+TEST_F(NetworkChangeNotifierMockedTest, TriggerConnectionCostChange) {
+  TestConnectionCostObserver observer;
+  NetworkChangeNotifier::AddConnectionCostObserver(&observer);
+
+  ASSERT_EQ(0, observer.cost_changed_calls());
+
+  NetworkChangeNotifier::NotifyObserversOfConnectionCostChangeForTests(
+      NetworkChangeNotifier::CONNECTION_COST_METERED);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(1, observer.cost_changed_calls());
+  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_COST_METERED,
+            observer.cost_changed_inputs()[0]);
+
+  NetworkChangeNotifier::RemoveConnectionCostObserver(&observer);
+  NetworkChangeNotifier::NotifyObserversOfConnectionCostChangeForTests(
+      NetworkChangeNotifier::CONNECTION_COST_UNMETERED);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(1, observer.cost_changed_calls());
+}
+
+TEST_F(NetworkChangeNotifierMockedTest, ConnectionCostDefaultsToCellular) {
+  mock_notifier_.mock_network_change_notifier()
+      ->SetUseDefaultConnectionCostImplementation(true);
+
+  mock_notifier_.mock_network_change_notifier()->SetConnectionType(
+      NetworkChangeNotifier::CONNECTION_4G);
+  EXPECT_TRUE(NetworkChangeNotifier::IsConnectionCellular(
+      NetworkChangeNotifier::GetConnectionType()));
+  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_COST_METERED,
+            NetworkChangeNotifier::GetConnectionCost());
+
+  mock_notifier_.mock_network_change_notifier()->SetConnectionType(
+      NetworkChangeNotifier::CONNECTION_WIFI);
+  EXPECT_FALSE(NetworkChangeNotifier::IsConnectionCellular(
+      NetworkChangeNotifier::GetConnectionType()));
+  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_COST_UNMETERED,
+            NetworkChangeNotifier::GetConnectionCost());
+}
+
+class NetworkChangeNotifierConnectionCostTest : public TestWithTaskEnvironment {
+ public:
+  void SetUp() override {
+    network_change_notifier_ = NetworkChangeNotifier::CreateIfNeeded();
+  }
+
+ private:
+  // Allows creating a new NetworkChangeNotifier.  Must be created before
+  // |network_change_notifier_| and destroyed after it to avoid DCHECK failures.
+  NetworkChangeNotifier::DisableForTest disable_for_test_;
+  std::unique_ptr<NetworkChangeNotifier> network_change_notifier_;
+};
+
+TEST_F(NetworkChangeNotifierConnectionCostTest, GetConnectionCost) {
+  EXPECT_NE(NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN,
+            NetworkChangeNotifier::GetConnectionCost());
+}
+
+TEST_F(NetworkChangeNotifierConnectionCostTest, AddObserver) {
+  TestConnectionCostObserver observer;
+  EXPECT_NO_FATAL_FAILURE(
+      NetworkChangeNotifier::AddConnectionCostObserver(&observer));
+  // RunUntilIdle because the secondary work resulting from adding an observer
+  // may be posted to a task queue.
+  base::RunLoop().RunUntilIdle();
+}
+
 }  // namespace net
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc
index 6eb46ef..973b276b 100644
--- a/net/base/network_change_notifier_win.cc
+++ b/net/base/network_change_notifier_win.cc
@@ -23,6 +23,7 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "base/win/windows_version.h"
 #include "net/base/winsock_init.h"
 #include "net/base/winsock_util.h"
 
@@ -33,15 +34,98 @@
 // Time between NotifyAddrChange retries, on failure.
 const int kWatchForAddressChangeRetryIntervalMs = 500;
 
+HRESULT GetConnectionPoints(IUnknown* manager,
+                            REFIID IIDSyncInterface,
+                            IConnectionPoint** connection_point_raw) {
+  *connection_point_raw = nullptr;
+  Microsoft::WRL::ComPtr<IConnectionPointContainer> connection_point_container;
+  HRESULT hr =
+      manager->QueryInterface(IID_PPV_ARGS(&connection_point_container));
+  if (FAILED(hr))
+    return hr;
+
+  // Find the interface
+  Microsoft::WRL::ComPtr<IConnectionPoint> connection_point;
+  hr = connection_point_container->FindConnectionPoint(IIDSyncInterface,
+                                                       &connection_point);
+  if (FAILED(hr))
+    return hr;
+
+  *connection_point_raw = connection_point.Get();
+  (*connection_point_raw)->AddRef();
+
+  return hr;
+}
+
 }  // namespace
 
+// This class is used as an event sink to register for notifications from the
+// INetworkCostManagerEvents interface. In particular, we are focused on getting
+// notified when the Connection Cost changes. This is only supported on Win10+.
+class NetworkCostManagerEventSink
+    : public Microsoft::WRL::RuntimeClass<
+          Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
+          INetworkCostManagerEvents> {
+ public:
+  using CostChangedCallback = base::RepeatingCallback<void()>;
+
+  NetworkCostManagerEventSink(INetworkCostManager* cost_manager,
+                              const CostChangedCallback& callback)
+      : network_cost_manager_(cost_manager), cost_changed_callback_(callback) {}
+  ~NetworkCostManagerEventSink() override {}
+
+  // INetworkCostManagerEvents members
+  IFACEMETHODIMP CostChanged(_In_ DWORD cost,
+                             _In_opt_ NLM_SOCKADDR* /*pSockAddr*/) override {
+    cost_changed_callback_.Run();
+    return S_OK;
+  }
+
+  IFACEMETHODIMP DataPlanStatusChanged(
+      _In_opt_ NLM_SOCKADDR* /*pSockAddr*/) override {
+    return S_OK;
+  }
+
+  HRESULT RegisterForNotifications() {
+    Microsoft::WRL::ComPtr<IUnknown> unknown;
+    HRESULT hr = QueryInterface(IID_PPV_ARGS(&unknown));
+    if (hr != S_OK)
+      return hr;
+
+    hr = GetConnectionPoints(network_cost_manager_.Get(),
+                             IID_INetworkCostManagerEvents, &connection_point_);
+    if (hr != S_OK)
+      return hr;
+
+    hr = connection_point_->Advise(unknown.Get(), &cookie_);
+    return hr;
+  }
+
+  void UnRegisterForNotifications() {
+    if (connection_point_) {
+      connection_point_->Unadvise(cookie_);
+      connection_point_ = nullptr;
+      cookie_ = 0;
+    }
+  }
+
+ private:
+  Microsoft::WRL::ComPtr<INetworkCostManager> network_cost_manager_;
+  Microsoft::WRL::ComPtr<IConnectionPoint> connection_point_;
+  DWORD cookie_ = 0;
+  CostChangedCallback cost_changed_callback_;
+};
+
 NetworkChangeNotifierWin::NetworkChangeNotifierWin()
     : NetworkChangeNotifier(NetworkChangeCalculatorParamsWin()),
       blocking_task_runner_(
           base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})),
       last_computed_connection_type_(RecomputeCurrentConnectionType()),
+      last_computed_connection_cost_(ConnectionCost::CONNECTION_COST_UNKNOWN),
       last_announced_offline_(last_computed_connection_type_ ==
-                              CONNECTION_NONE) {
+                              CONNECTION_NONE),
+      sequence_runner_for_registration_(
+          base::SequencedTaskRunnerHandle::Get()) {
   memset(&addr_overlapped_, 0, sizeof addr_overlapped_);
   addr_overlapped_.hEvent = WSACreateEvent();
 }
@@ -54,6 +138,11 @@
     addr_watcher_.StopWatching();
   }
   WSACloseEvent(addr_overlapped_.hEvent);
+
+  if (network_cost_manager_event_sink_) {
+    network_cost_manager_event_sink_->UnRegisterForNotifications();
+    network_cost_manager_event_sink_ = nullptr;
+  }
 }
 
 // static
@@ -135,8 +224,7 @@
   query_set.dwNameSpace = NS_NLA;
   // Initiate a client query to iterate through the
   // currently connected networks.
-  if (0 != WSALookupServiceBegin(&query_set, LUP_RETURN_ALL,
-                                 &ws_handle)) {
+  if (0 != WSALookupServiceBegin(&query_set, LUP_RETURN_ALL, &ws_handle)) {
     LOG(ERROR) << "WSALookupServiceBegin failed with: " << WSAGetLastError();
     return NetworkChangeNotifier::CONNECTION_UNKNOWN;
   }
@@ -152,11 +240,9 @@
   DWORD length = sizeof(result_buffer);
   reinterpret_cast<WSAQUERYSET*>(&result_buffer[0])->dwSize =
       sizeof(WSAQUERYSET);
-  int result = WSALookupServiceNext(
-      ws_handle,
-      LUP_RETURN_NAME,
-      &length,
-      reinterpret_cast<WSAQUERYSET*>(&result_buffer[0]));
+  int result =
+      WSALookupServiceNext(ws_handle, LUP_RETURN_NAME, &length,
+                           reinterpret_cast<WSAQUERYSET*>(&result_buffer[0]));
 
   if (result == 0) {
     // Found a connection!
@@ -180,8 +266,7 @@
   }
 
   result = WSALookupServiceEnd(ws_handle);
-  LOG_IF(ERROR, result != 0)
-      << "WSALookupServiceEnd() failed with: " << result;
+  LOG_IF(ERROR, result != 0) << "WSALookupServiceEnd() failed with: " << result;
 
   // TODO(droger): Return something more detailed than CONNECTION_UNKNOWN.
   return found_connection ? ConnectionTypeFromInterfaces()
@@ -198,6 +283,120 @@
       std::move(reply_callback));
 }
 
+NetworkChangeNotifier::ConnectionCost
+NetworkChangeNotifierWin::GetCurrentConnectionCost() {
+  InitializeConnectionCost();
+
+  // Pre-Win10 use the default logic.
+  if (base::win::GetVersion() < base::win::Version::WIN10)
+    return NetworkChangeNotifier::GetCurrentConnectionCost();
+
+  // If we don't have the event sink we aren't registered for automatic updates.
+  // In that case, we need to update the value at the time it is requested.
+  if (!network_cost_manager_event_sink_)
+    UpdateConnectionCostFromCostManager();
+
+  return last_computed_connection_cost_;
+}
+
+bool NetworkChangeNotifierWin::InitializeConnectionCostOnce() {
+  // Pre-Win10 this information cannot be retrieved and cached.
+  if (base::win::GetVersion() < base::win::Version::WIN10) {
+    SetCurrentConnectionCost(CONNECTION_COST_UNKNOWN);
+    return true;
+  }
+
+  HRESULT hr =
+      ::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL,
+                         IID_INetworkCostManager, &network_cost_manager_);
+  if (FAILED(hr)) {
+    SetCurrentConnectionCost(CONNECTION_COST_UNKNOWN);
+    return true;
+  }
+
+  UpdateConnectionCostFromCostManager();
+
+  return true;
+}
+
+void NetworkChangeNotifierWin::InitializeConnectionCost() {
+  static bool g_connection_cost_initialized = InitializeConnectionCostOnce();
+  DCHECK(g_connection_cost_initialized);
+}
+
+HRESULT NetworkChangeNotifierWin::UpdateConnectionCostFromCostManager() {
+  if (!network_cost_manager_)
+    return E_ABORT;
+
+  DWORD cost = NLM_CONNECTION_COST_UNKNOWN;
+  HRESULT hr = network_cost_manager_->GetCost(&cost, nullptr);
+  if (FAILED(hr)) {
+    SetCurrentConnectionCost(CONNECTION_COST_UNKNOWN);
+  } else {
+    SetCurrentConnectionCost(
+        ConnectionCostFromNlmCost((NLM_CONNECTION_COST)cost));
+  }
+  return hr;
+}
+
+// static
+NetworkChangeNotifier::ConnectionCost
+NetworkChangeNotifierWin::ConnectionCostFromNlmCost(NLM_CONNECTION_COST cost) {
+  if (cost == NLM_CONNECTION_COST_UNKNOWN)
+    return CONNECTION_COST_UNKNOWN;
+  else if ((cost & NLM_CONNECTION_COST_UNRESTRICTED) != 0)
+    return CONNECTION_COST_UNMETERED;
+  else
+    return CONNECTION_COST_METERED;
+}
+
+void NetworkChangeNotifierWin::SetCurrentConnectionCost(
+    ConnectionCost connection_cost) {
+  last_computed_connection_cost_ = connection_cost;
+}
+
+void NetworkChangeNotifierWin::OnCostChanged() {
+  ConnectionCost old_cost = last_computed_connection_cost_;
+  // It is possible to get multiple notifications in a short period of time.
+  // Rather than worrying about whether this notification represents the latest,
+  // just get the current value from the CostManager so we know that we're
+  // actually getting the correct value.
+  UpdateConnectionCostFromCostManager();
+  // Only notify if there's actually a change.
+  if (old_cost != GetCurrentConnectionCost())
+    NotifyObserversOfConnectionCostChange();
+}
+
+void NetworkChangeNotifierWin::ConnectionCostObserverAdded() {
+  sequence_runner_for_registration_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&NetworkChangeNotifierWin::OnConnectionCostObserverAdded,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void NetworkChangeNotifierWin::OnConnectionCostObserverAdded() {
+  DCHECK(sequence_runner_for_registration_->RunsTasksInCurrentSequence());
+  InitializeConnectionCost();
+
+  // No need to register if we don't have a cost manager or if we're already
+  // registered.
+  if (!network_cost_manager_ || network_cost_manager_event_sink_)
+    return;
+
+  network_cost_manager_event_sink_ =
+      Microsoft::WRL::Make<net::NetworkCostManagerEventSink>(
+          network_cost_manager_.Get(),
+          base::BindRepeating(&NetworkChangeNotifierWin::OnCostChanged,
+                              weak_factory_.GetWeakPtr()));
+  HRESULT hr = network_cost_manager_event_sink_->RegisterForNotifications();
+  if (hr != S_OK) {
+    // If registration failed for any reason, just destroy the event sink. The
+    // observer will remain connected but will not receive any updates. If
+    // another observer gets added later, we can re-attempt registration.
+    network_cost_manager_event_sink_ = nullptr;
+  }
+}
+
 NetworkChangeNotifier::ConnectionType
 NetworkChangeNotifierWin::GetCurrentConnectionType() const {
   base::AutoLock auto_lock(last_computed_connection_type_lock_);
diff --git a/net/base/network_change_notifier_win.h b/net/base/network_change_notifier_win.h
index 619c274..e3fced1d 100644
--- a/net/base/network_change_notifier_win.h
+++ b/net/base/network_change_notifier_win.h
@@ -5,7 +5,11 @@
 #ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_WIN_H_
 #define NET_BASE_NETWORK_CHANGE_NOTIFIER_WIN_H_
 
+#include <netlistmgr.h>
+#include <ocidl.h>
 #include <windows.h>
+#include <wrl.h>
+#include <wrl/client.h>
 
 #include <memory>
 
@@ -14,6 +18,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
+#include "base/thread_annotations.h"
 #include "base/timer/timer.h"
 #include "base/win/object_watcher.h"
 #include "net/base/net_export.h"
@@ -25,6 +30,8 @@
 
 namespace net {
 
+class NetworkCostManagerEventSink;
+
 // NetworkChangeNotifierWin uses a SequenceChecker, as all its internal
 // notification code must be called on the sequence it is created and destroyed
 // on.  All the NetworkChangeNotifier methods it implements are threadsafe.
@@ -57,6 +64,8 @@
   friend class TestNetworkChangeNotifierWin;
 
   // NetworkChangeNotifier methods:
+  ConnectionCost GetCurrentConnectionCost() override;
+
   ConnectionType GetCurrentConnectionType() const override;
 
   // ObjectWatcher::Delegate methods:
@@ -91,6 +100,26 @@
 
   static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsWin();
 
+  // Gets the current network connection cost (if possible) and caches it.
+  void InitializeConnectionCost();
+  // Does the work of initializing for thread safety.
+  bool InitializeConnectionCostOnce();
+  // Retrieves the current network connection cost from the OS's Cost Manager.
+  HRESULT UpdateConnectionCostFromCostManager();
+  // Converts the OS enum values to the enum values used in our code.
+  static ConnectionCost ConnectionCostFromNlmCost(NLM_CONNECTION_COST cost);
+  // Sets the cached network connection cost value.
+  void SetCurrentConnectionCost(ConnectionCost connection_cost);
+  // Callback method for the notification event sink.
+  void OnCostChanged();
+  // Tells this class that an observer was added and therefore this class needs
+  // to register for notifications.
+  void ConnectionCostObserverAdded() override;
+  // Since ConnectionCostObserverAdded() can be called on any thread and we
+  // don't want to do a bunch of work on an arbitrary thread, this method used
+  // to post task to do the work.
+  void OnConnectionCostObserverAdded();
+
   // All member variables may only be accessed on the sequence |this| was
   // created on.
 
@@ -112,12 +141,23 @@
   mutable base::Lock last_computed_connection_type_lock_;
   ConnectionType last_computed_connection_type_;
 
+  std::atomic<ConnectionCost> last_computed_connection_cost_;
+
   // Result of IsOffline() when NotifyObserversOfConnectionTypeChange()
   // was last called.
   bool last_announced_offline_;
   // Number of times polled to check if still offline.
   int offline_polls_;
 
+  Microsoft::WRL::ComPtr<INetworkCostManager> network_cost_manager_;
+  Microsoft::WRL::ComPtr<NetworkCostManagerEventSink>
+      network_cost_manager_event_sink_;
+
+  // Used to ensure that all registration actions are properly sequenced on the
+  // same thread regardless of which thread was used to call into the
+  // NetworkChangeNotifier API.
+  scoped_refptr<base::SequencedTaskRunner> sequence_runner_for_registration_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   // Used for calling WatchForAddressChange again on failure.
diff --git a/net/base/network_change_notifier_win_unittest.cc b/net/base/network_change_notifier_win_unittest.cc
index 4c4a1bf..b35504e 100644
--- a/net/base/network_change_notifier_win_unittest.cc
+++ b/net/base/network_change_notifier_win_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/win/windows_version.h"
 #include "net/base/network_change_notifier.h"
 #include "net/base/network_change_notifier_factory.h"
 #include "net/test/test_with_task_environment.h"
@@ -30,6 +31,8 @@
   TestNetworkChangeNotifierWin() {
     last_computed_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN;
     last_announced_offline_ = false;
+    last_computed_connection_cost_ = ConnectionCost::CONNECTION_COST_UNKNOWN;
+    sequence_runner_for_registration_ = base::SequencedTaskRunnerHandle::Get();
   }
 
   TestNetworkChangeNotifierWin(const TestNetworkChangeNotifierWin&) = delete;
@@ -216,6 +219,23 @@
     base::RunLoop().RunUntilIdle();
   }
 
+  bool HasNetworkCostManager() {
+    return network_change_notifier_.network_cost_manager_.Get() != nullptr;
+  }
+
+  bool HasNetworkCostManagerEventSink() {
+    return network_change_notifier_.network_cost_manager_event_sink_.Get() !=
+           nullptr;
+  }
+
+  NetworkChangeNotifier::ConnectionCost LastComputedConnectionCost() {
+    return network_change_notifier_.last_computed_connection_cost_;
+  }
+
+  NetworkChangeNotifier::ConnectionCost GetCurrentConnectionCost() {
+    return network_change_notifier_.GetCurrentConnectionCost();
+  }
+
  private:
   // Note that the order of declaration here is important.
 
@@ -267,4 +287,58 @@
   RetryAndSucceed();
 }
 
+class TestConnectionCostObserver
+    : public NetworkChangeNotifier::ConnectionCostObserver {
+ public:
+  TestConnectionCostObserver() {}
+
+  TestConnectionCostObserver(const TestConnectionCostObserver&) = delete;
+  TestConnectionCostObserver& operator=(const TestConnectionCostObserver&) =
+      delete;
+
+  ~TestConnectionCostObserver() override {
+    NetworkChangeNotifier::RemoveConnectionCostObserver(this);
+  }
+
+  void OnConnectionCostChanged(NetworkChangeNotifier::ConnectionCost) override {
+  }
+
+  void Register() { NetworkChangeNotifier::AddConnectionCostObserver(this); }
+};
+
+TEST_F(NetworkChangeNotifierWinTest, NetworkCostManagerIntegration) {
+  // NetworkCostManager integration only exist on Win10+.
+  if (base::win::GetVersion() < base::win::Version::WIN10)
+    return;
+
+  // Upon creation, none of the NetworkCostManager integration should be
+  // initialized yet.
+  ASSERT_FALSE(HasNetworkCostManager());
+  ASSERT_FALSE(HasNetworkCostManagerEventSink());
+  ASSERT_EQ(NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN,
+            LastComputedConnectionCost());
+
+  // Asking for the current connection cost should initialize the
+  // NetworkCostManager integration, but not the event sink.
+  // Note that the actual ConnectionCost value return is irrelevant beyond the
+  // fact that it shouldn't be UNKNOWN anymore if the integration is initialized
+  // properly.
+  NetworkChangeNotifier::ConnectionCost current_connection_cost =
+      GetCurrentConnectionCost();
+  EXPECT_NE(NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN,
+            current_connection_cost);
+  EXPECT_EQ(current_connection_cost, LastComputedConnectionCost());
+  EXPECT_TRUE(HasNetworkCostManager());
+  EXPECT_FALSE(HasNetworkCostManagerEventSink());
+
+  // Adding a ConnectionCostObserver should initialize the event sink. If the
+  // subsequent registration for updates fails, the event sink will get
+  // destroyed.
+  TestConnectionCostObserver test_connection_cost_observer;
+  test_connection_cost_observer.Register();
+  // The actual registration happens on a callback, so need to run until idle.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(HasNetworkCostManagerEventSink());
+}
+
 }  // namespace net
diff --git a/services/device/generic_sensor/platform_sensor_provider_chromeos.cc b/services/device/generic_sensor/platform_sensor_provider_chromeos.cc
index 5a731584f..36fa812b 100644
--- a/services/device/generic_sensor/platform_sensor_provider_chromeos.cc
+++ b/services/device/generic_sensor/platform_sensor_provider_chromeos.cc
@@ -13,19 +13,11 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
 #include "base/task/post_task.h"
-#include "base/task/thread_pool.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "base/time/time.h"
 #include "chromeos/components/sensors/sensor_hal_dispatcher.h"
-#include "services/device/generic_sensor/absolute_orientation_euler_angles_fusion_algorithm_using_accelerometer_and_magnetometer.h"
-#include "services/device/generic_sensor/linear_acceleration_fusion_algorithm_using_accelerometer.h"
-#include "services/device/generic_sensor/linux/sensor_data_linux.h"
-#include "services/device/generic_sensor/orientation_quaternion_fusion_algorithm_using_euler_angles.h"
 #include "services/device/generic_sensor/platform_sensor_chromeos.h"
-#include "services/device/generic_sensor/platform_sensor_fusion.h"
-#include "services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer.h"
-#include "services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer_and_gyroscope.h"
 
 namespace device {
 namespace {
diff --git a/services/device/generic_sensor/platform_sensor_provider_chromeos_unittest.cc b/services/device/generic_sensor/platform_sensor_provider_chromeos_unittest.cc
index 67ee7325a..d0bd74fe 100644
--- a/services/device/generic_sensor/platform_sensor_provider_chromeos_unittest.cc
+++ b/services/device/generic_sensor/platform_sensor_provider_chromeos_unittest.cc
@@ -343,7 +343,7 @@
   EXPECT_TRUE(CreateSensor(mojom::SensorType::GYROSCOPE));
 
   // Simulate a disconnection of IIO Service.
-  sensor_hal_server_->GetSensorService()->OnServiceDisconnect();
+  sensor_hal_server_->GetSensorService()->ClearReceivers();
   sensor_hal_server_->OnServerDisconnect();
   // Remove the stored Mojo remote of the ambient light sensor.
   sensor_devices_.back()->ClearReceivers();
diff --git a/services/network/url_loader_factory.cc b/services/network/url_loader_factory.cc
index adf7d7e..13602090 100644
--- a/services/network/url_loader_factory.cc
+++ b/services/network/url_loader_factory.cc
@@ -136,7 +136,7 @@
     // Load a subresource from a WebBundle.
     base::WeakPtr<WebBundleURLLoaderFactory> web_bundle_url_loader_factory =
         context_->GetWebBundleManager().GetWebBundleURLLoaderFactory(
-            url_request.web_bundle_token_params->token);
+            url_request.web_bundle_token_params->token, params_->process_id);
     if (web_bundle_url_loader_factory) {
       web_bundle_url_loader_factory->CreateLoaderAndStart(
           std::move(receiver), routing_id, request_id, options, url_request,
diff --git a/services/network/web_bundle_manager.cc b/services/network/web_bundle_manager.cc
index 3538c889..46eea6a 100644
--- a/services/network/web_bundle_manager.cc
+++ b/services/network/web_bundle_manager.cc
@@ -21,7 +21,8 @@
     const GURL& bundle_url,
     const ResourceRequest::WebBundleTokenParams& web_bundle_token_params,
     const mojom::URLLoaderFactoryParamsPtr& factory_params) {
-  DCHECK(factories_.find(web_bundle_token_params.token) == factories_.end());
+  DCHECK(factories_.find({factory_params->process_id,
+                          web_bundle_token_params.token}) == factories_.end());
 
   mojo::Remote<mojom::WebBundleHandle> remote(
       web_bundle_token_params.CloneHandle());
@@ -32,21 +33,25 @@
   remote.set_disconnect_handler(
       base::BindOnce(&WebBundleManager::DisconnectHandler,
                      // |this| outlives |remote|.
-                     base::Unretained(this), web_bundle_token_params.token));
+                     base::Unretained(this), web_bundle_token_params.token,
+                     factory_params->process_id));
 
   auto factory = std::make_unique<WebBundleURLLoaderFactory>(
       bundle_url, std::move(remote),
       factory_params->request_initiator_origin_lock);
   auto weak_factory = factory->GetWeakPtr();
-  factories_.insert({web_bundle_token_params.token, std::move(factory)});
+  factories_.insert({std::make_pair(factory_params->process_id,
+                                    web_bundle_token_params.token),
+                     std::move(factory)});
 
   return weak_factory;
 }
 
 base::WeakPtr<WebBundleURLLoaderFactory>
 WebBundleManager::GetWebBundleURLLoaderFactory(
-    const base::UnguessableToken& web_bundle_token) {
-  auto it = factories_.find(web_bundle_token);
+    const base::UnguessableToken& web_bundle_token,
+    int32_t process_id) {
+  auto it = factories_.find({process_id, web_bundle_token});
   if (it == factories_.end()) {
     return nullptr;
   }
@@ -54,8 +59,9 @@
 }
 
 void WebBundleManager::DisconnectHandler(
-    base::UnguessableToken web_bundle_token) {
-  factories_.erase(web_bundle_token);
+    base::UnguessableToken web_bundle_token,
+    int32_t process_id) {
+  factories_.erase({process_id, web_bundle_token});
 }
 
 }  // namespace network
diff --git a/services/network/web_bundle_manager.h b/services/network/web_bundle_manager.h
index 50e7320..a73d0ac0e 100644
--- a/services/network/web_bundle_manager.h
+++ b/services/network/web_bundle_manager.h
@@ -33,14 +33,15 @@
       const mojom::URLLoaderFactoryParamsPtr& factory_params);
 
   base::WeakPtr<WebBundleURLLoaderFactory> GetWebBundleURLLoaderFactory(
-      const base::UnguessableToken& token);
+      const base::UnguessableToken& token,
+      int32_t process_id);
 
  private:
-  void DisconnectHandler(base::UnguessableToken token);
+  void DisconnectHandler(base::UnguessableToken token, int32_t process_id);
 
-  // Maps a WebBundle token to a WebBundleURLLoaderFactory.
-  // TODO(crbug.com/1149255): Use a tuple of (PID, token) as a key.
-  std::map<base::UnguessableToken, std::unique_ptr<WebBundleURLLoaderFactory>>
+  // Maps a tuple (PID, WebBundle token) to a WebBundleURLLoaderFactory.
+  std::map<std::pair<int32_t, base::UnguessableToken>,
+           std::unique_ptr<WebBundleURLLoaderFactory>>
       factories_;
 };
 
diff --git a/services/network/web_bundle_manager_unittest.cc b/services/network/web_bundle_manager_unittest.cc
index af804aea..a57e26d5 100644
--- a/services/network/web_bundle_manager_unittest.cc
+++ b/services/network/web_bundle_manager_unittest.cc
@@ -16,6 +16,8 @@
 namespace {
 
 const char kBundleUrl[] = "https://example.com/bundle.wbn";
+const int32_t process_id1 = 100;
+const int32_t process_id2 = 200;
 
 }  // namespace
 
@@ -28,9 +30,30 @@
   base::test::TaskEnvironment task_environment_;
 };
 
+TEST_F(WebBundleManagerTest, NoFactoryExistsForDifferentProcessId) {
+  WebBundleManager manager;
+  base::UnguessableToken token = base::UnguessableToken::Create();
+  auto factory_params = mojom::URLLoaderFactoryParams::New();
+  factory_params->process_id = process_id1;
+  mojo::PendingRemote<network::mojom::WebBundleHandle> handle;
+  mojo::PendingReceiver<network::mojom::WebBundleHandle> receiver =
+      handle.InitWithNewPipeAndPassReceiver();
+  auto token_params =
+      ResourceRequest::WebBundleTokenParams(token, std::move(handle));
+
+  auto factory = manager.CreateWebBundleURLLoaderFactory(
+      GURL(kBundleUrl), token_params, factory_params);
+  ASSERT_TRUE(factory);
+  ASSERT_TRUE(
+      manager.GetWebBundleURLLoaderFactory(token, factory_params->process_id));
+  ASSERT_FALSE(manager.GetWebBundleURLLoaderFactory(token, process_id2));
+}
+
 TEST_F(WebBundleManagerTest, RemoveFactoryWhenDisconnected) {
   WebBundleManager manager;
   base::UnguessableToken token = base::UnguessableToken::Create();
+  auto factory_params = mojom::URLLoaderFactoryParams::New();
+  factory_params->process_id = 123;
   {
     mojo::PendingRemote<network::mojom::WebBundleHandle> handle;
     mojo::PendingReceiver<network::mojom::WebBundleHandle> receiver =
@@ -39,13 +62,15 @@
         ResourceRequest::WebBundleTokenParams(token, std::move(handle));
 
     auto factory = manager.CreateWebBundleURLLoaderFactory(
-        GURL(kBundleUrl), token_params, mojom::URLLoaderFactoryParams::New());
+        GURL(kBundleUrl), token_params, factory_params);
     ASSERT_TRUE(factory);
-    ASSERT_TRUE(manager.GetWebBundleURLLoaderFactory(token));
+    ASSERT_TRUE(manager.GetWebBundleURLLoaderFactory(
+        token, factory_params->process_id));
     // Getting out of scope to delete |receiver|.
   }
   base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(manager.GetWebBundleURLLoaderFactory(token))
+  EXPECT_FALSE(
+      manager.GetWebBundleURLLoaderFactory(token, factory_params->process_id))
       << "The manager should remove a factory when the handle is disconnected.";
 }
 
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 282344f4..b9a7d3e1 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -214,10 +214,6 @@
 #define SK_DISABLE_REDUCE_OPLIST_SPLITTING
 #endif
 
-#ifndef SK_SUPPORT_LEGACY_INHERITED_PICTURE_SHADER_FILTER
-#define SK_SUPPORT_LEGACY_INHERITED_PICTURE_SHADER_FILTER
-#endif
-
 // Max. verb count for paths rendered by the edge-AA tessellating path renderer.
 #define GR_AA_TESSELLATOR_MAX_VERB_COUNT 100
 
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 57a6aa7..4e8462f3 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -5268,21 +5268,6 @@
             ]
         }
     ],
-    "PermissionPromptUICocoa": [
-        {
-            "platforms": [
-                "mac"
-            ],
-            "experiments": [
-                {
-                    "name": "BlockPromptsEnabled",
-                    "enable_features": [
-                        "BlockPromptsIfDismissedOften"
-                    ]
-                }
-            ]
-        }
-    ],
     "PersistentHistograms": [
         {
             "platforms": [
@@ -5586,9 +5571,10 @@
                     "name": "EnabledStitchAndTrending",
                     "params": {
                         "base_url": "https://chromeupboarding-pa.googleapis.com",
-                        "experiment_tag": "{enableTrending: true}",
+                        "experiment_tag": "{enableTrending: true, maxTrendingQueries: 8}",
                         "image_prefetch_mode": "top",
                         "is_unmetered_network_required": "false",
+                        "max_trending_tile_impressions": "1",
                         "most_visited_max_rows_normal_screen": "2",
                         "most_visited_max_rows_small_screen": "1",
                         "small_screen_height_threshold_dp": "700"
@@ -5597,7 +5583,8 @@
                         "QueryTiles",
                         "QueryTilesInNTP",
                         "QueryTilesInOmnibox",
-                        "QueryTilesLocalOrdering"
+                        "QueryTilesLocalOrdering",
+                        "QueryTilesRemoveTrendingAfterInactivity"
                     ],
                     "disable_features": [
                         "QueryTilesEnableQueryEditing"
@@ -7024,28 +7011,6 @@
             ]
         }
     ],
-    "TrustedTypes": [
-        {
-            "platforms": [
-                "android",
-                "android_weblayer",
-                "chromeos",
-                "linux",
-                "mac",
-                "windows",
-                "android_weblayer",
-                "android_webview"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "TrustedDOMTypes"
-                    ]
-                }
-            ]
-        }
-    ],
     "TurnOffStreamingMediaCaching": [
         {
             "platforms": [
@@ -7158,27 +7123,6 @@
             ]
         }
     ],
-    "UsePreferredIntervalForVideo": [
-        {
-            "platforms": [
-                "chromeos",
-                "mac",
-                "windows",
-                "linux"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "NumOfFramesToToggleInterval": "6"
-                    },
-                    "enable_features": [
-                        "UsePreferredIntervalForVideo"
-                    ]
-                }
-            ]
-        }
-    ],
     "UseSkiaRenderer": [
         {
             "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index f55826e..85897914 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -813,7 +813,7 @@
 // without conversion to I420.
 const base::Feature kWebRtcLibvpxEncodeNV12 {
   "WebRtcLibvpxEncodeNV12",
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
       base::FEATURE_DISABLED_BY_DEFAULT
 #else
       base::FEATURE_ENABLED_BY_DEFAULT
diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
index bcdedf6..c7a55ff0 100644
--- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
+++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
@@ -31,6 +31,7 @@
       !data.ReadLazyImageFirstKFullyLoad(&out->lazy_image_first_k_fully_load) ||
       !data.ReadDefaultEncoding(&out->default_encoding) ||
       !data.ReadTextTrackBackgroundColor(&out->text_track_background_color) ||
+      !data.ReadTextTrackTextColor(&out->text_track_text_color) ||
       !data.ReadTextTrackTextSize(&out->text_track_text_size) ||
       !data.ReadTextTrackTextShadow(&out->text_track_text_shadow) ||
       !data.ReadTextTrackFontFamily(&out->text_track_font_family) ||
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
index 13d4fea..69231d6 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
@@ -42,7 +42,7 @@
 
  public:
   explicit ScriptPromiseResolver(ScriptState*);
-  virtual ~ScriptPromiseResolver();
+  ~ScriptPromiseResolver() override;
 
   void Dispose();
 
diff --git a/third_party/blink/renderer/bindings/core/v8/source_location.cc b/third_party/blink/renderer/bindings/core/v8/source_location.cc
index 9288c60a..642f0bb4 100644
--- a/third_party/blink/renderer/bindings/core/v8/source_location.cc
+++ b/third_party/blink/renderer/bindings/core/v8/source_location.cc
@@ -41,9 +41,10 @@
     unsigned column_number) {
   std::unique_ptr<v8_inspector::V8StackTrace> stack_trace =
       CaptureStackTrace(false);
-  if (stack_trace && !stack_trace->isEmpty())
+  if (stack_trace && !stack_trace->isEmpty()) {
     return SourceLocation::CreateFromNonEmptyV8StackTrace(
-        std::move(stack_trace), 0);
+        std::move(stack_trace));
+  }
   return std::make_unique<SourceLocation>(url, line_number, column_number,
                                           std::move(stack_trace));
 }
@@ -53,9 +54,10 @@
     ExecutionContext* execution_context) {
   std::unique_ptr<v8_inspector::V8StackTrace> stack_trace =
       CaptureStackTrace(false);
-  if (stack_trace && !stack_trace->isEmpty())
+  if (stack_trace && !stack_trace->isEmpty()) {
     return SourceLocation::CreateFromNonEmptyV8StackTrace(
-        std::move(stack_trace), 0);
+        std::move(stack_trace));
+  }
 
   if (LocalDOMWindow* window = DynamicTo<LocalDOMWindow>(execution_context)) {
     Document* document = window->document();
@@ -99,9 +101,10 @@
       message->GetStartColumn(isolate->GetCurrentContext()).To(&column_number))
     ++column_number;
 
-  if ((!script_id || !line_number) && stack_trace && !stack_trace->isEmpty())
+  if ((!script_id || !line_number) && stack_trace && !stack_trace->isEmpty()) {
     return SourceLocation::CreateFromNonEmptyV8StackTrace(
-        std::move(stack_trace), 0);
+        std::move(stack_trace));
+  }
 
   String url = ToCoreStringWithUndefinedOrNullCheck(
       message->GetScriptOrigin().ResourceName());
@@ -113,12 +116,12 @@
 
 // static
 std::unique_ptr<SourceLocation> SourceLocation::CreateFromNonEmptyV8StackTrace(
-    std::unique_ptr<v8_inspector::V8StackTrace> stack_trace,
-    int script_id) {
+    std::unique_ptr<v8_inspector::V8StackTrace> stack_trace) {
   // Retrieve the data before passing the ownership to SourceLocation.
   String url = ToCoreString(stack_trace->topSourceURL());
   unsigned line_number = stack_trace->topLineNumber();
   unsigned column_number = stack_trace->topColumnNumber();
+  int script_id = stack_trace->topScriptIdAsInteger();
   return base::WrapUnique(new SourceLocation(
       url, line_number, column_number, std::move(stack_trace), script_id));
 }
@@ -139,9 +142,10 @@
 std::unique_ptr<SourceLocation> SourceLocation::CaptureWithFullStackTrace() {
   std::unique_ptr<v8_inspector::V8StackTrace> stack_trace =
       CaptureStackTrace(true);
-  if (stack_trace && !stack_trace->isEmpty())
+  if (stack_trace && !stack_trace->isEmpty()) {
     return SourceLocation::CreateFromNonEmptyV8StackTrace(
-        std::move(stack_trace), 0);
+        std::move(stack_trace));
+  }
   return std::make_unique<SourceLocation>(String(), 0, 0, nullptr, 0);
 }
 
@@ -166,7 +170,7 @@
   value->BeginDictionary();
   value->SetString("functionName",
                    ToCoreString(stack_trace_->topFunctionName()));
-  value->SetString("scriptId", ToCoreString(stack_trace_->topScriptId()));
+  value->SetInteger("scriptId", stack_trace_->topScriptIdAsInteger());
   value->SetString("url", ToCoreString(stack_trace_->topSourceURL()));
   value->SetInteger("lineNumber", stack_trace_->topLineNumber());
   value->SetInteger("columnNumber", stack_trace_->topColumnNumber());
diff --git a/third_party/blink/renderer/bindings/core/v8/source_location.h b/third_party/blink/renderer/bindings/core/v8/source_location.h
index 3126e049..5f7f0bd2 100644
--- a/third_party/blink/renderer/bindings/core/v8/source_location.h
+++ b/third_party/blink/renderer/bindings/core/v8/source_location.h
@@ -76,8 +76,7 @@
 
  private:
   static std::unique_ptr<SourceLocation> CreateFromNonEmptyV8StackTrace(
-      std::unique_ptr<v8_inspector::V8StackTrace>,
-      int script_id);
+      std::unique_ptr<v8_inspector::V8StackTrace>);
 
   String url_;
   unsigned line_number_;
diff --git a/third_party/blink/renderer/core/dom/events/event_queue.h b/third_party/blink/renderer/core/dom/events/event_queue.h
index e127921..120ac0f 100644
--- a/third_party/blink/renderer/core/dom/events/event_queue.h
+++ b/third_party/blink/renderer/core/dom/events/event_queue.h
@@ -40,7 +40,7 @@
                                      public ExecutionContextLifecycleObserver {
  public:
   EventQueue(ExecutionContext*, TaskType);
-  ~EventQueue();
+  ~EventQueue() override;
 
   void Trace(Visitor*) const override;
   bool EnqueueEvent(const base::Location&, Event&);
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc
index 01614fc5..eebda915 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -968,9 +968,12 @@
   // subframes as well.
   for (Frame* frame = GetFrame()->Tree().TraverseNext(GetFrame()); frame;
        frame = frame->Tree().TraverseNext(GetFrame())) {
+    // TODO(https://crbug.com/1147796) In OOPIFs mode, the text finder
+    // corresponding to the remote frame also needs to be notified, the
+    // match rects are invalid and need to be recalculated.
     auto* web_local_frame_impl =
-        WebLocalFrameImpl::FromFrame(To<LocalFrame>(frame));
-    if (web_local_frame_impl->GetTextFinder() &&
+        WebLocalFrameImpl::FromFrame(DynamicTo<LocalFrame>(frame));
+    if (web_local_frame_impl && web_local_frame_impl->GetTextFinder() &&
         web_local_frame_impl->GetTextFinder()->TotalMatchCount() > 0) {
       web_local_frame_impl->GetTextFinder()->InvalidateFindMatchRects();
     }
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.h b/third_party/blink/renderer/core/editing/ime/input_method_controller.h
index de76cd2..4f52b15 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller.h
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.h
@@ -61,7 +61,7 @@
   };
 
   explicit InputMethodController(LocalDOMWindow&, LocalFrame&);
-  virtual ~InputMethodController();
+  ~InputMethodController() override;
   void Trace(Visitor*) const override;
 
   // international text input composition
diff --git a/third_party/blink/renderer/core/editing/selection_controller.h b/third_party/blink/renderer/core/editing/selection_controller.h
index b514f295..2f68d8f6 100644
--- a/third_party/blink/renderer/core/editing/selection_controller.h
+++ b/third_party/blink/renderer/core/editing/selection_controller.h
@@ -47,7 +47,7 @@
       public ExecutionContextLifecycleObserver {
  public:
   explicit SelectionController(LocalFrame&);
-  virtual ~SelectionController();
+  ~SelectionController() override;
   void Trace(Visitor*) const override;
 
   bool HandleMousePressEvent(const MouseEventWithHitTestResults&);
diff --git a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
index 4d30c47c..2593305 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
+++ b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
@@ -34,7 +34,7 @@
 
  public:
   explicit IdleSpellCheckController(LocalDOMWindow&, SpellCheckRequester&);
-  ~IdleSpellCheckController();
+  ~IdleSpellCheckController() override;
 
   enum class State {
 #define V(state) k##state,
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 7d316ea..6848d8c 100644
--- a/third_party/blink/renderer/core/execution_context/execution_context.cc
+++ b/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -148,8 +148,7 @@
   is_context_destroyed_ = true;
   context_lifecycle_observer_set_.ForEachObserver(
       [](ContextLifecycleObserver* observer) {
-        observer->ContextDestroyed();
-        observer->ObserverSetWillBeCleared();
+        observer->NotifyContextDestroyed();
       });
   context_lifecycle_observer_set_.Clear();
 }
diff --git a/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h b/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
index f8f23a4..edc7a21 100644
--- a/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
+++ b/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
@@ -72,7 +72,7 @@
   void SetExecutionContext(ExecutionContext*) override;
 
  protected:
-  virtual ~ExecutionContextLifecycleStateObserver();
+  ~ExecutionContextLifecycleStateObserver() override;
 
  private:
 #if DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/core/exported/BUILD.gn b/third_party/blink/renderer/core/exported/BUILD.gn
index 85225e6..e91874d8 100644
--- a/third_party/blink/renderer/core/exported/BUILD.gn
+++ b/third_party/blink/renderer/core/exported/BUILD.gn
@@ -83,6 +83,7 @@
   }
 
   deps = [
+    "//build:chromeos_buildflags",
     "//third_party/blink/renderer/core:core_generated",
     "//third_party/blink/renderer/core/probe",
     "//third_party/blink/renderer/core/typed_arrays:typed_arrays",
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 68688f0..ff1f422 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -189,6 +189,8 @@
 #undef pow
 #include <cmath>  // for std::pow
 
+#include "build/chromeos_buildflags.h"
+
 // The following constants control parameters for automated scaling of webpages
 // (such as due to a double tap gesture or find in page etc.). These are
 // experimentally determined.
@@ -410,7 +412,9 @@
 #if !defined(OS_MAC) && !defined(OS_WIN)
 SkFontHinting RendererPreferencesToSkiaHinting(
     const blink::RendererPreferences& prefs) {
-#if defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   if (!prefs.should_antialias_text) {
     // When anti-aliasing is off, GTK maps all non-zero hinting settings to
     // 'Normal' hinting so we do the same. Otherwise, folks who have 'Slight'
@@ -3067,12 +3071,15 @@
       gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE);
   WebFontRenderStyle::SetSubpixelPositioning(
       renderer_preferences_.use_subpixel_positioning);
-#if defined(OS_LINUX) && !defined(OS_ANDROID)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(OS_ANDROID)
   if (!renderer_preferences_.system_font_family_name.empty()) {
     WebFontRenderStyle::SetSystemFontFamily(blink::WebString::FromUTF8(
         renderer_preferences_.system_font_family_name));
   }
-#endif  // defined(OS_LINUX) && !defined(OS_ANDROID)
+#endif  // (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) &&
+        // !defined(OS_ANDROID)
 #endif  // defined(OS_WIN)
 #endif  // !defined(OS_MAC)
 }
diff --git a/third_party/blink/renderer/core/frame/dom_timer.cc b/third_party/blink/renderer/core/frame/dom_timer.cc
index 4330003..afa9cf7 100644
--- a/third_party/blink/renderer/core/frame/dom_timer.cc
+++ b/third_party/blink/renderer/core/frame/dom_timer.cc
@@ -108,13 +108,13 @@
   }
   MoveToNewTaskRunner(context->GetTaskRunner(task_type));
 
-  // Clamping up to 1ms for historical reasons crbug.com/402694.
-  timeout = std::max(timeout, base::TimeDelta::FromMilliseconds(1));
-
-  if (single_shot)
+  if (single_shot) {
     StartOneShot(timeout, FROM_HERE);
-  else
+  } else {
+    // TODO(crbug.com/402694): Don't clamp interval timers to 1ms here
+    timeout = std::max(timeout, base::TimeDelta::FromMilliseconds(1));
     StartRepeating(timeout, FROM_HERE);
+  }
 
   TRACE_EVENT_INSTANT1("devtools.timeline", "TimerInstall",
                        TRACE_EVENT_SCOPE_THREAD, "data",
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.h b/third_party/blink/renderer/core/frame/pausable_script_executor.h
index 708cc814..508d97d4 100644
--- a/third_party/blink/renderer/core/frame/pausable_script_executor.h
+++ b/third_party/blink/renderer/core/frame/pausable_script_executor.h
@@ -53,7 +53,7 @@
                          ScriptState*,
                          WebScriptExecutionCallback*,
                          Executor*);
-  virtual ~PausableScriptExecutor();
+  ~PausableScriptExecutor() override;
 
   void Run();
   void RunAsync(BlockingOption);
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.h b/third_party/blink/renderer/core/fullscreen/fullscreen.h
index 8445c473..34c1d12 100644
--- a/third_party/blink/renderer/core/fullscreen/fullscreen.h
+++ b/third_party/blink/renderer/core/fullscreen/fullscreen.h
@@ -59,7 +59,7 @@
   static const char kSupplementName[];
 
   explicit Fullscreen(LocalDOMWindow&);
-  virtual ~Fullscreen();
+  ~Fullscreen() override;
 
   static Element* FullscreenElementFrom(Document&);
   static Element* FullscreenElementForBindingFrom(TreeScope&);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
index e735245..f3120394 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
@@ -244,6 +244,10 @@
     // |line_width| and/or InlineOffset() might be saturated.
     if (line_width <= item.InlineOffset())
       return line_width;
+    // We can do nothing if the right-side static item sticks out to the both
+    // sides.
+    if (item.InlineOffset() < 0)
+      return line_width;
     static_width_right =
         line_width - item.InlineOffset() + item.margin_line_left;
   }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
index a084c9f..dcd82490e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
@@ -38,6 +38,22 @@
   return nullptr;
 }
 
+std::ostream& operator<<(std::ostream& stream, const NGLogicalLineItem& item) {
+  stream << "NGLogicalLineItem(";
+  if (item.IsPlaceholder())
+    stream << " placeholder";
+  stream << " inline_size=" << item.inline_size;
+  if (item.inline_item)
+    stream << " " << item.inline_item->ToString().Utf8().c_str();
+  if (item.PhysicalFragment())
+    stream << " Fragment=" << *item.PhysicalFragment();
+  if (item.GetLayoutObject())
+    stream << " LayoutObject=" << *item.GetLayoutObject();
+  stream << ")";
+  // Feel free to add more information.
+  return stream;
+}
+
 NGLogicalLineItem* NGLogicalLineItems::FirstInFlowChild() {
   for (auto& child : *this) {
     if (child.HasInFlowFragment())
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
index ca9ab20..3a604e4 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
@@ -244,6 +244,9 @@
   bool is_hidden_for_paint = false;
 };
 
+CORE_EXPORT std::ostream& operator<<(std::ostream& stream,
+                                     const NGLogicalLineItem& item);
+
 // A vector of Child.
 // Unlike the fragment builder, chlidren are mutable.
 // Callers can add to the fragment builder in a batch once finalized.
diff --git a/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc b/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc
index de31c75..d9f8ff22 100644
--- a/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc
+++ b/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc
@@ -195,13 +195,7 @@
                      console_message.Utf8().c_str()));
   GetDocument().GetPage()->GetPageScheduler()->SetPageVisible(false);
 
-  platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
-  EXPECT_THAT(FilteredConsoleMessages(), Vector<String>(1, console_message));
-  platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
-  EXPECT_THAT(FilteredConsoleMessages(), Vector<String>(2, console_message));
-  platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
-  EXPECT_THAT(FilteredConsoleMessages(), Vector<String>(3, console_message));
-  platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
+  platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(4));
   EXPECT_THAT(FilteredConsoleMessages(), Vector<String>(4, console_message));
   platform_->RunForPeriod(base::TimeDelta::FromMilliseconds(995));
   EXPECT_THAT(FilteredConsoleMessages(), Vector<String>(4, console_message));
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
index 75baf5d..f6e5221 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
@@ -31,6 +31,7 @@
 #include "third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h"
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "cc/input/scrollbar.h"
 #include "third_party/blink/public/common/input/web_mouse_event.h"
 #include "third_party/blink/public/platform/platform.h"
@@ -137,7 +138,9 @@
 // Disable snapback on desktop Linux to better integrate with the desktop
 // behavior. Typically, Linux apps do not implement scrollbar snapback (this
 // is true for at least GTK and QT apps).
-#if defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   return false;
 #else
   return true;
@@ -303,7 +306,9 @@
 
 bool ScrollbarThemeAura::ShouldCenterOnThumb(const Scrollbar& scrollbar,
                                              const WebMouseEvent& event) {
-#if defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   if (event.button == WebPointerProperties::Button::kMiddle)
     return true;
 #endif
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
index dbf683a..62abb810 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -42,7 +42,7 @@
                                           const String&);
 
   ClipboardPromise(ExecutionContext*, ScriptState*);
-  virtual ~ClipboardPromise();
+  ~ClipboardPromise() override;
 
   // Completes current write and starts next write.
   void CompleteWriteRepresentation();
diff --git a/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc b/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc
index 0d3e265..a29c0fe3 100644
--- a/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc
+++ b/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache.cc
@@ -39,7 +39,7 @@
   explicit WindowObserver(LocalDOMWindow& window)
       : Supplement<LocalDOMWindow>(window),
         ExecutionContextLifecycleObserver(&window) {}
-  ~WindowObserver() = default;
+  ~WindowObserver() override = default;
 
   void Trace(Visitor* visitor) const final {
     Supplement<LocalDOMWindow>::Trace(visitor);
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_request.h b/third_party/blink/renderer/modules/mediastream/user_media_request.h
index 5f902043..6e58987 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_request.h
+++ b/third_party/blink/renderer/modules/mediastream/user_media_request.h
@@ -115,7 +115,7 @@
                    MediaConstraints video,
                    Callbacks*,
                    IdentifiableSurface surface);
-  virtual ~UserMediaRequest();
+  ~UserMediaRequest() override;
 
   LocalDOMWindow* GetWindow();
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
index bc5de51d..c791d0b 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/testing/null_execution_context.h"
 #include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap.h"
 #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
 #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
 #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
@@ -214,11 +215,18 @@
 class RTCDataChannelTest : public ::testing::Test {
  public:
   RTCDataChannelTest() : signaling_thread_(new base::TestSimpleTaskRunner()) {}
+  ~RTCDataChannelTest() override {
+    execution_context_->NotifyContextDestroyed();
+  }
 
   scoped_refptr<base::TestSimpleTaskRunner> signaling_thread() {
     return signaling_thread_;
   }
 
+ protected:
+  Persistent<NullExecutionContext> execution_context_ =
+      MakeGarbageCollected<NullExecutionContext>();
+
  private:
   scoped_refptr<base::TestSimpleTaskRunner> signaling_thread_;
 
@@ -237,8 +245,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
 
   // In RTCDataChannel::Create, the state change update is posted from the
   // signaling thread to the main thread. Wait for posted the task to be
@@ -255,8 +262,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
   webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen);
 
   String message(std::string(100, 'A').c_str());
@@ -273,8 +279,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
   webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen);
 
   channel->setBufferedAmountLowThreshold(1);
@@ -295,8 +300,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
   channel->OnStateChange(webrtc::DataChannelInterface::kOpen);
   EXPECT_EQ("open", channel->readyState());
 }
@@ -307,8 +311,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
   channel->OnStateChange(webrtc::DataChannelInterface::kClosed);
   EXPECT_EQ("closed", channel->readyState());
 }
@@ -319,8 +322,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
 
   std::unique_ptr<webrtc::DataBuffer> message(new webrtc::DataBuffer("A"));
   channel->OnMessage(std::move(message));
@@ -334,8 +336,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
   webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen);
 
   channel->ContextDestroyed();
@@ -353,8 +354,7 @@
   std::unique_ptr<MockPeerConnectionHandler> pc(
       new MockPeerConnectionHandler(signaling_thread()));
   auto* channel = MakeGarbageCollected<RTCDataChannel>(
-      MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(),
-      pc.get());
+      execution_context_, webrtc_channel.get(), pc.get());
   webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen);
 
   channel->ContextDestroyed();
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h
index d7a24e9..7adce74 100644
--- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h
+++ b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h
@@ -32,7 +32,7 @@
       public Supplement<LocalDOMWindow> {
  public:
   explicit ScreenOrientationController(LocalDOMWindow&);
-  ~ScreenOrientationController();
+  ~ScreenOrientationController() override;
 
   void SetOrientation(ScreenOrientation*);
   void NotifyOrientationChanged();
diff --git a/third_party/blink/renderer/modules/vibration/vibration_controller.h b/third_party/blink/renderer/modules/vibration/vibration_controller.h
index 452ad8d..ffb917b 100644
--- a/third_party/blink/renderer/modules/vibration/vibration_controller.h
+++ b/third_party/blink/renderer/modules/vibration/vibration_controller.h
@@ -52,7 +52,7 @@
   static bool vibrate(Navigator&, const VibrationPattern&);
 
   explicit VibrationController(Navigator&);
-  virtual ~VibrationController();
+  ~VibrationController() override;
 
   static VibrationPattern SanitizeVibrationPattern(
       const UnsignedLongOrUnsignedLongSequence&);
diff --git a/third_party/blink/renderer/modules/webdatabase/database_context.h b/third_party/blink/renderer/modules/webdatabase/database_context.h
index 3b6daba..d3c0caa 100644
--- a/third_party/blink/renderer/modules/webdatabase/database_context.h
+++ b/third_party/blink/renderer/modules/webdatabase/database_context.h
@@ -46,7 +46,7 @@
   static DatabaseContext* Create(ExecutionContext*);
 
   explicit DatabaseContext(ExecutionContext*);
-  ~DatabaseContext();
+  ~DatabaseContext() override;
   void Trace(Visitor*) const override;
 
   // For life-cycle management (inherited from
diff --git a/third_party/blink/renderer/modules/webgl/BUILD.gn b/third_party/blink/renderer/modules/webgl/BUILD.gn
index 11bb856..05f58350 100644
--- a/third_party/blink/renderer/modules/webgl/BUILD.gn
+++ b/third_party/blink/renderer/modules/webgl/BUILD.gn
@@ -166,7 +166,10 @@
   configs += [ "//third_party/blink/renderer/core:blink_core_pch" ]
 
   public_deps = [ "//device/vr/public/mojom:vr_service_blink" ]
-  deps = [ "//third_party/blink/renderer/modules/xr:xr" ]
+  deps = [
+    "//build:chromeos_buildflags",
+    "//third_party/blink/renderer/modules/xr:xr"
+  ]
   deps += [ "//third_party/blink/renderer/modules/webcodecs:webcodecs" ]
   allow_circular_includes_from = deps
 }
diff --git a/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc b/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc
index cf82e9b2..32a1a15 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/webgl/webgl_webcodecs_video_frame.h"
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "media/base/wait_and_replace_sync_token_client.h"
 #include "media/video/gpu_memory_buffer_video_frame_pool.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_color_space.h"
@@ -26,7 +27,7 @@
 const char kRequiredExtension[] = "GL_NV_EGL_stream_consumer_external";
 #elif defined(OS_MAC)
 const char kRequiredExtension[] = "GL_ANGLE_texture_rectangle";
-#elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#elif defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
 const char kRequiredExtension[] = "GL_OES_EGL_image_external";
 #else
 const char kRequiredExtension[] = "";
@@ -216,7 +217,7 @@
   auto& components_nv12 = format_to_components_map_[media::PIXEL_FORMAT_NV12];
   components_nv12[media::VideoFrame::kYPlane] = "r";
   components_nv12[media::VideoFrame::kUPlane] = "rg";
-#elif defined(OS_CHROMEOS)
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
   formats_supported[media::PIXEL_FORMAT_ABGR] = true;
   auto& components_abgr = format_to_components_map_[media::PIXEL_FORMAT_ABGR];
   components_abgr[media::VideoFrame::kYPlane] = "rgb";
@@ -235,7 +236,9 @@
 }
 
 bool WebGLWebCodecsVideoFrame::Supported(WebGLRenderingContextBase* context) {
-#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) || defined(OS_FUCHSIA)
   // TODO(jie.a.chen@intel.com): Add Linux support.
   return false;
 #else
@@ -270,7 +273,7 @@
   sampler_type = "sampler2DRect";
   sampler_func = "texture2DRect";
   pixel_format = media::PIXEL_FORMAT_XRGB;
-#elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#elif defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
   sampler_type = "samplerExternalOES";
   pixel_format = media::PIXEL_FORMAT_ABGR;
   src_color_space = gfx::ColorSpace::CreateSRGB();
diff --git a/third_party/blink/renderer/platform/context_lifecycle_observer.cc b/third_party/blink/renderer/platform/context_lifecycle_observer.cc
index 9beb179..c1f2695 100644
--- a/third_party/blink/renderer/platform/context_lifecycle_observer.cc
+++ b/third_party/blink/renderer/platform/context_lifecycle_observer.cc
@@ -8,8 +8,15 @@
 
 namespace blink {
 
-void ContextLifecycleObserver::ObserverSetWillBeCleared() {
-  notifier_ = nullptr;
+ContextLifecycleObserver::~ContextLifecycleObserver() {
+#if DCHECK_IS_ON()
+  // We want to make sure that if we are still waiting for a notification,
+  // then the context hasn't been GC'ed (or, in other words, if the WeakPtr is
+  // reset then `ContextDestroyed()` has been called).
+  // waiting_for_context_destroyed_ -> notifier_
+  // !waiting_for_context_destroyed_ || notifier_
+  DCHECK(!waiting_for_context_destroyed_ || notifier_);
+#endif
 }
 
 void ContextLifecycleObserver::SetContextLifecycleNotifier(
@@ -22,10 +29,24 @@
 
   notifier_ = notifier;
 
+#if DCHECK_IS_ON()
+  // If the notifier is not null we expect it to notify us when it is destroyed.
+  waiting_for_context_destroyed_ = !!notifier_;
+#endif
+
   if (notifier_)
     notifier_->AddContextLifecycleObserver(this);
 }
 
+void ContextLifecycleObserver::NotifyContextDestroyed() {
+#if DCHECK_IS_ON()
+  DCHECK(waiting_for_context_destroyed_);
+  waiting_for_context_destroyed_ = false;
+#endif
+  ContextDestroyed();
+  notifier_ = nullptr;
+}
+
 void ContextLifecycleObserver::Trace(Visitor* visitor) const {
   visitor->Trace(notifier_);
 }
diff --git a/third_party/blink/renderer/platform/context_lifecycle_observer.h b/third_party/blink/renderer/platform/context_lifecycle_observer.h
index bc034a9..776ccb5 100644
--- a/third_party/blink/renderer/platform/context_lifecycle_observer.h
+++ b/third_party/blink/renderer/platform/context_lifecycle_observer.h
@@ -15,10 +15,8 @@
 // ExecutionContext from platform/.
 class PLATFORM_EXPORT ContextLifecycleObserver : public GarbageCollectedMixin {
  public:
-  virtual void ContextDestroyed() = 0;
-
-  // Call before clearing an observer list.
-  void ObserverSetWillBeCleared();
+  virtual ~ContextLifecycleObserver();
+  void NotifyContextDestroyed();
 
   ContextLifecycleNotifier* GetContextLifecycleNotifier() const {
     return notifier_;
@@ -32,8 +30,13 @@
  protected:
   ContextLifecycleObserver() = default;
 
+  virtual void ContextDestroyed() = 0;
+
  private:
   WeakMember<ContextLifecycleNotifier> notifier_;
+#if DCHECK_IS_ON()
+  bool waiting_for_context_destroyed_ = false;
+#endif
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
index 24efa5bf..f2937a1 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
@@ -109,15 +109,16 @@
     unsigned offset) const {
   if (offset >= NumCharacters())
     return NumCharacters();
+  offset += offset_;
   if (!Rtl()) {
     for (const auto& glyph : base::Reversed(*this)) {
       if (glyph.safe_to_break_before && glyph.character_index <= offset)
-        return glyph.character_index;
+        return glyph.character_index - offset_;
     }
   } else {
     for (const auto& glyph : *this) {
       if (glyph.safe_to_break_before && glyph.character_index <= offset)
-        return glyph.character_index;
+        return glyph.character_index - offset_;
     }
   }
 
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
index 85c4605..62fbee4 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
@@ -125,6 +125,47 @@
   EXPECT_EQ(last_glyphs.size(), 3u);
 }
 
+TEST_F(ShapeResultViewTest, PreviousSafeToBreak) {
+  String string =
+      u"\u0028\u05D1\u0029\u0020\u05D4\u05D1\u05DC\u0020\u05D0\u05DE\u05E8"
+      u"\u0020\u05E2\u05DC\u0020"
+      u"\u05D3\u05D1\u05E8\u05D9\u0020\u05D4\u05D1\u05DC\u05D9\u0020\u05D4"
+      u"\u05E2\u05D5\u05DC\u05DD\u002C"
+      u"\u0020\u05D5\u05E1\u05DE\u05DA\u0020\u05D4\u05B2\u05D1\u05B5\u05DC"
+      u"\u0020\u05D0\u05DC\u0020\u05D4"
+      u"\u05D1\u05DC\u05D9\u05DD\u0020\u05D5\u05D0\u05DD\u0020\u05DC\u05D0"
+      u"\u0020\u05D9\u05DE\u05E6\u05D0"
+      u"\u0020\u05DE\u05D4\u05E9\u05DE\u05D5\u05EA\u0020\u05E9\u05D4\u05DD"
+      u"\u0020\u05E2\u05DC\u0020\u05DE"
+      u"\u05E9\u05E7\u05DC\u0020\u05D0\u05E8\u05E5\u0020\u05E9\u05D9\u05E9"
+      u"\u05EA\u05E0\u05D4\u0020\u05D7"
+      u"\u05D5\u05E5\u0020\u05DE\u05B5\u05D7\u05B2\u05D3\u05B7\u05E8\u0020"
+      u"\u05DE\u05B4\u05E9\u05B0\u05C1"
+      u"\u05DB\u05B8\u05D1\u05B0\u05DA\u05B8\u0020\u0028\u05E9\u05DE\u05D5"
+      u"\u05EA\u0020\u05D6\u05F3\u003A"
+      u"\u05DB\u05F4\u05D7\u0029";
+  TextDirection direction = TextDirection::kRtl;
+  HarfBuzzShaper shaper(string);
+  const RunSegmenter::RunSegmenterRange range = {
+      51, 131, USCRIPT_HEBREW, blink::OrientationIterator::kOrientationKeep,
+      blink::FontFallbackPriority::kText};
+  scoped_refptr<ShapeResult> shape_result =
+      shaper.Shape(&font, direction, 51, 131, range);
+
+  unsigned start_offset = 59;
+  unsigned end_offset = 118;
+  scoped_refptr<const ShapeResultView> result_view =
+      ShapeResultView::Create(shape_result.get(), start_offset, end_offset);
+  scoped_refptr<ShapeResult> result = result_view->CreateShapeResult();
+
+  unsigned offset = end_offset;
+  do {
+    unsigned safe = result_view->PreviousSafeToBreakOffset(offset);
+    unsigned cached_safe = result->CachedPreviousSafeToBreakOffset(offset);
+    EXPECT_EQ(safe, cached_safe);
+  } while (--offset > start_offset);
+}
+
 TEST_F(ShapeResultViewTest, LatinMultiRun) {
   TextDirection direction = TextDirection::kLtr;
   HarfBuzzShaper shaper_a(To16Bit("hello", 5));
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
index 3c928d3..481a403 100644
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
@@ -104,12 +104,12 @@
     global_memory_cache_ = ReplaceMemoryCacheForTesting(
         MakeGarbageCollected<MemoryCache>(platform_->test_task_runner()));
     auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
+    lifecycle_notifier_ = MakeGarbageCollected<MockContextLifecycleNotifier>();
     fetcher_ = MakeGarbageCollected<ResourceFetcher>(ResourceFetcherInit(
         properties->MakeDetachable(), MakeGarbageCollected<MockFetchContext>(),
         base::MakeRefCounted<scheduler::FakeTaskRunner>(),
         base::MakeRefCounted<scheduler::FakeTaskRunner>(),
-        MakeGarbageCollected<TestLoaderFactory>(),
-        MakeGarbageCollected<MockContextLifecycleNotifier>()));
+        MakeGarbageCollected<TestLoaderFactory>(), lifecycle_notifier_));
   }
 
   void TearDown() override {
@@ -118,6 +118,7 @@
 
   Persistent<MemoryCache> global_memory_cache_;
   Persistent<ResourceFetcher> fetcher_;
+  Persistent<MockContextLifecycleNotifier> lifecycle_notifier_;
   ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
       platform_;
 };
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
index d9bb1100..e156ae8 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
@@ -39,7 +39,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
index 95811f1..b39b70ff 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
@@ -31,7 +31,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
index f8b016d..d1719a2 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
@@ -31,7 +31,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
index c7fb431..d1a3b78 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
@@ -38,7 +38,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
index 94390be..13a7bb5 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
@@ -35,7 +35,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc
index 609eabb..d8b482c5 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc
@@ -38,7 +38,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
index 97b764b5..9a64d7d2 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
@@ -35,7 +35,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
index f3fe302..216a7ed2 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
@@ -33,7 +33,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h b/third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h
index 9328ff3..cf4578aa 100644
--- a/third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h
+++ b/third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h
@@ -28,7 +28,7 @@
 
   void NotifyContextDestroyed() {
     observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
-      observer->ContextDestroyed();
+      observer->NotifyContextDestroyed();
     });
   }
 
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn
index ea0e881..458b864 100644
--- a/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -213,6 +213,7 @@
 
   deps = [
     ":buildflags",
+    "//build:chromeos_buildflags",
 
     # TODO(tkent): WTF should not depend on it.
     "//third_party/blink/public/common:headers",
diff --git a/third_party/blink/renderer/platform/wtf/container_annotations.h b/third_party/blink/renderer/platform/wtf/container_annotations.h
index 584b905..2cf3d44d 100644
--- a/third_party/blink/renderer/platform/wtf/container_annotations.h
+++ b/third_party/blink/renderer/platform/wtf/container_annotations.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CONTAINER_ANNOTATIONS_H_
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/sanitizers.h"
 
 // TODO(ochang): Remove the ARCH_CPU_X86_64 condition to enable this for X86
@@ -36,13 +37,15 @@
   ANNOTATE_NEW_BUFFER(buffer, newCapacity, bufferSize);
 // Annotations require buffers to begin on an 8-byte boundary.
 
-#else  // ADDRESS_SANITIZER && (OS_LINUX || OS_CHROMEOS) && ARCH_CPU_X86_64
+#else  // ADDRESS_SANITIZER && (OS_LINUX || IS_CHROMEOS_ASH) &&
+       // ARCH_CPU_X86_64
 
 #define ANNOTATE_NEW_BUFFER(buffer, capacity, newSize)
 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, oldSize)
 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, oldSize, newSize)
 #define ANNOTATE_CHANGE_CAPACITY(buffer, oldCapacity, bufferSize, newCapacity)
 
-#endif  // ADDRESS_SANITIZER && (OS_LINUX || OS_CHROMEOS) && ARCH_CPU_X86_64
+#endif  // ADDRESS_SANITIZER && (OS_LINUX || IS_CHROMEOS_ASH) &&
+        // ARCH_CPU_X86_64
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CONTAINER_ANNOTATIONS_H_
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-features=BackForwardCache b/third_party/blink/web_tests/FlagExpectations/enable-features=BackForwardCache
index 05f779d..073cad1 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-features=BackForwardCache
+++ b/third_party/blink/web_tests/FlagExpectations/enable-features=BackForwardCache
@@ -13,9 +13,6 @@
 crbug.com/1132180 http/tests/navigation/forward-to-fragment-fires-onload.html [ Skip ]
 
 # TODO(peria): Make these tests work with same-site back-forward cache.
-crbug.com/1150297 http/tests/navigation/back-during-child-frame-reload.html [ Timeout ]
-crbug.com/1150297 http/tests/navigation/post-frames-goback1.html [ Timeout ]
-crbug.com/1150297 http/tests/navigation/postredirect-frames-goback1.html [ Timeout ]
 crbug.com/1155125 http/tests/history/replacestate-post-to-get-2.html [ Timeout ]
 
 # TODO(peria): Make these tests work with same-site browsing instance swap.
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/update-rendering/child-document-raf-order-expected.txt b/third_party/blink/web_tests/external/wpt/html/webappapis/update-rendering/child-document-raf-order-expected.txt
index 29fda633..f9ba495 100644
--- a/third_party/blink/web_tests/external/wpt/html/webappapis/update-rendering/child-document-raf-order-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/webappapis/update-rendering/child-document-raf-order-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Ordering of steps in "Update the Rendering" - child document requestAnimationFrame order assert_array_equals: expected order of notifications lengths differ, expected array ["parent_raf", "first_child_raf", "second_child_raf"] length 3, got ["parent_raf", "second_child_raf", "first_child_raf", "parent_raf", "second_child_raf", "first_child_raf"] length 6
+FAIL Ordering of steps in "Update the Rendering" - child document requestAnimationFrame order assert_array_equals: expected order of notifications expected property 1 to be "first_child_raf" but got "second_child_raf" (expected array ["parent_raf", "first_child_raf", "second_child_raf"] got ["parent_raf", "second_child_raf", "first_child_raf"])
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html b/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html
index 302d2a4..f87cba48 100644
--- a/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html
+++ b/third_party/blink/web_tests/fast/forms/file/file-crash-by-pseudo-after-with-padding.html
@@ -19,6 +19,17 @@
   content: 'a';
   margin-left: 2000000000%;
 }
+
+.c20 {
+  width: 640px;
+}
+.c20:after {
+  content: 'c20';
+  display: inline-block;
+  margin-right: 100%;
+  margin-left: -100000000%;
+  padding-right: 2000000000%;
+}
 </style>
 <input type="file">
 <script>
@@ -35,4 +46,12 @@
   fileInput.offsetWidth;
   // Ok if no crash.
 }, ':after with huge margin should not cause a crash.');
+
+// crbug.com/1162727
+test(() => {
+  const fileInput = document.querySelector('input');
+  fileInput.classList.add('c20');
+  fileInput.offsetWidth;
+  // Ok if no crash.
+}, ':after with huge negative margin should not cause a crash.');
 </script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt b/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt
index b3597e0..c0175b09 100644
--- a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt
@@ -21,5 +21,5 @@
     startTime : <number>
     type : "Layout"
 }
-Text details for Layout: forced-layout-in-microtask.js:21
+Text details for Layout: test://evaluations/0/forced-layout-in-microtask.js:21
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt
index ec76a2b..5df2f52 100644
--- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt
@@ -21,7 +21,7 @@
     startTime : <number>
     type : "Layout"
 }
-Text details for Layout: timeline-layout.js:40
+Text details for Layout: test://evaluations/0/timeline-layout.js:40
 Layout Properties:
 {
     data : {
@@ -43,5 +43,5 @@
     startTime : <number>
     type : "Layout"
 }
-Text details for Layout: timeline-layout.js:40
+Text details for Layout: test://evaluations/0/timeline-layout.js:40
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt
index 33e4c07..f9c7763 100644
--- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt
@@ -13,7 +13,7 @@
     startTime : <number>
     type : "RequestAnimationFrame"
 }
-Text details for RequestAnimationFrame: timeline-animation-frame.js:14
+Text details for RequestAnimationFrame: test://evaluations/0/timeline-animation-frame.js:14
 FireAnimationFrame Properties:
 {
     data : {
@@ -25,7 +25,7 @@
     startTime : <number>
     type : "FireAnimationFrame"
 }
-Text details for FireAnimationFrame: timeline-animation-frame.js:14
+Text details for FireAnimationFrame: test://evaluations/0/timeline-animation-frame.js:14
 CancelAnimationFrame Properties:
 {
     data : {
@@ -39,5 +39,5 @@
     startTime : <number>
     type : "CancelAnimationFrame"
 }
-Text details for CancelAnimationFrame: timeline-animation-frame.js:17
+Text details for CancelAnimationFrame: test://evaluations/0/timeline-animation-frame.js:17
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt
index 3297a2e..7a21102 100644
--- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt
@@ -15,7 +15,7 @@
     startTime : <number>
     type : "TimerInstall"
 }
-Text details for TimerInstall: timeline-timer.js:14
+Text details for TimerInstall: test://evaluations/0/timeline-timer.js:14
 TimerInstall Properties:
 {
     data : {
@@ -31,7 +31,7 @@
     startTime : <number>
     type : "TimerInstall"
 }
-Text details for TimerInstall: timeline-timer.js:15
+Text details for TimerInstall: test://evaluations/0/timeline-timer.js:15
 TimerFire Properties:
 {
     data : {
@@ -43,7 +43,7 @@
     startTime : <number>
     type : "TimerFire"
 }
-Text details for TimerFire: timeline-timer.js:14
+Text details for TimerFire: test://evaluations/0/timeline-timer.js:14
 TimerFire Properties:
 {
     data : {
@@ -55,7 +55,7 @@
     startTime : <number>
     type : "TimerFire"
 }
-Text details for TimerFire: timeline-timer.js:15
+Text details for TimerFire: test://evaluations/0/timeline-timer.js:15
 TimerFire Properties:
 {
     data : {
@@ -67,7 +67,7 @@
     startTime : <number>
     type : "TimerFire"
 }
-Text details for TimerFire: timeline-timer.js:15
+Text details for TimerFire: test://evaluations/0/timeline-timer.js:15
 TimerRemove Properties:
 {
     data : {
@@ -81,7 +81,7 @@
     startTime : <number>
     type : "TimerRemove"
 }
-Text details for TimerRemove: timeline-timer.js:22
+Text details for TimerRemove: test://evaluations/0/timeline-timer.js:22
 FunctionCall Properties:
 {
     data : {
diff --git a/third_party/blink/web_tests/http/tests/navigation/back-during-child-frame-reload.html b/third_party/blink/web_tests/http/tests/navigation/back-during-child-frame-reload.html
index 7ee8f25f..4542a4c 100644
--- a/third_party/blink/web_tests/http/tests/navigation/back-during-child-frame-reload.html
+++ b/third_party/blink/web_tests/http/tests/navigation/back-during-child-frame-reload.html
@@ -1,5 +1,5 @@
 <script>
-function onload() {
+onpageshow = () => {
   debugger;
   if (!localStorage['state']) {
     localStorage['state'] = 'one';
@@ -29,7 +29,7 @@
   }
 }
 </script>
-<body onload="onload()">
+<body>
   <p>
     Navigation initiated by history.back() should overwrite child frame reload,
     which was started eralier and did not finish yet.
diff --git a/third_party/blink/web_tests/http/tests/navigation/postredirect-frames-goback1.html b/third_party/blink/web_tests/http/tests/navigation/postredirect-frames-goback1.html
index e4dc3ff..96a450b5 100644
--- a/third_party/blink/web_tests/http/tests/navigation/postredirect-frames-goback1.html
+++ b/third_party/blink/web_tests/http/tests/navigation/postredirect-frames-goback1.html
@@ -9,7 +9,7 @@
     testRunner.dumpBackForwardList();
  }
    
-onload = function()
+onpageshow = function()
 {
     if (sessionStorage.didNav) {
         delete sessionStorage.didNav;
@@ -38,4 +38,4 @@
 
 <iframe name="target-frame" src="about:blank"></iframe>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
index 260422a7..b255406 100644
--- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
+++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/custom/pattern-with-transformation-expected.png b/third_party/blink/web_tests/platform/linux/svg/custom/pattern-with-transformation-expected.png
index b6f63e2..79971d5 100644
--- a/third_party/blink/web_tests/platform/linux/svg/custom/pattern-with-transformation-expected.png
+++ b/third_party/blink/web_tests/platform/linux/svg/custom/pattern-with-transformation-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/borders/border-image-rotate-transform-expected.png b/third_party/blink/web_tests/platform/mac/fast/borders/border-image-rotate-transform-expected.png
index 4d1b58c..1fd6fab5 100644
--- a/third_party/blink/web_tests/platform/mac/fast/borders/border-image-rotate-transform-expected.png
+++ b/third_party/blink/web_tests/platform/mac/fast/borders/border-image-rotate-transform-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
index 66ce694a..34b9324 100644
--- a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/custom/pattern-with-transformation-expected.png b/third_party/blink/web_tests/platform/mac/svg/custom/pattern-with-transformation-expected.png
index 7bc2ce9d..49cdadb 100644
--- a/third_party/blink/web_tests/platform/mac/svg/custom/pattern-with-transformation-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/custom/pattern-with-transformation-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/borders/border-image-rotate-transform-expected.png b/third_party/blink/web_tests/platform/win/fast/borders/border-image-rotate-transform-expected.png
index 9311caa27..a01228d 100644
--- a/third_party/blink/web_tests/platform/win/fast/borders/border-image-rotate-transform-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/borders/border-image-rotate-transform-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
index 27fb451f..e991f458 100644
--- a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1/pservers-grad-06-b-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/custom/pattern-with-transformation-expected.png b/third_party/blink/web_tests/platform/win/svg/custom/pattern-with-transformation-expected.png
index 3a5ac48..386607f 100644
--- a/third_party/blink/web_tests/platform/win/svg/custom/pattern-with-transformation-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/custom/pattern-with-transformation-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/svg/custom/non-scaling-stroke-expected.png b/third_party/blink/web_tests/svg/custom/non-scaling-stroke-expected.png
index c9d78a8..f4529c6 100644
--- a/third_party/blink/web_tests/svg/custom/non-scaling-stroke-expected.png
+++ b/third_party/blink/web_tests/svg/custom/non-scaling-stroke-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/svg/custom/pattern-skew-transformed-expected.png b/third_party/blink/web_tests/svg/custom/pattern-skew-transformed-expected.png
index 5d50fc1..3692b50 100644
--- a/third_party/blink/web_tests/svg/custom/pattern-skew-transformed-expected.png
+++ b/third_party/blink/web_tests/svg/custom/pattern-skew-transformed-expected.png
Binary files differ
diff --git a/third_party/crashpad/crashpad/util/BUILD.gn b/third_party/crashpad/crashpad/util/BUILD.gn
index adedf95..a8daea8 100644
--- a/third_party/crashpad/crashpad/util/BUILD.gn
+++ b/third_party/crashpad/crashpad/util/BUILD.gn
@@ -379,7 +379,7 @@
     ]
   }
 
-  deps = []
+  deps = [ "//build:chromeos_buildflags" ]
 
   if (crashpad_is_linux || crashpad_is_fuchsia || crashpad_is_android) {
     sources += [ "net/http_transport_socket.cc" ]
diff --git a/third_party/crashpad/crashpad/util/posix/scoped_mmap.cc b/third_party/crashpad/crashpad/util/posix/scoped_mmap.cc
index 21533d2..cdae97e 100644
--- a/third_party/crashpad/crashpad/util/posix/scoped_mmap.cc
+++ b/third_party/crashpad/crashpad/util/posix/scoped_mmap.cc
@@ -24,14 +24,19 @@
 #include "base/numerics/safe_math.h"
 #include "base/process/process_metrics.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 
-#if defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "third_party/lss/lss.h"
 #endif
 
 namespace {
 
-#if defined(OS_LINUX)
+// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
+// complete.
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
 void* CallMmap(void* addr,
                size_t len,
                int prot,
diff --git a/third_party/metrics_proto/BUILD.gn b/third_party/metrics_proto/BUILD.gn
index 52095ab..609629d 100644
--- a/third_party/metrics_proto/BUILD.gn
+++ b/third_party/metrics_proto/BUILD.gn
@@ -25,7 +25,7 @@
   "printer_event.proto",
   "reporting_info.proto",
   "sampled_profile.proto",
-  "structured_event.proto",
+  "structured_data.proto",
   "system_profile.proto",
   "trace_log.proto",
   "translate_event.proto",
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium
index fd88a19..076ea57 100644
--- a/third_party/metrics_proto/README.chromium
+++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@
 Name: Metrics Protos
 Short Name: metrics_proto
 URL: This is the canonical public repository
-Version: 346104568
-Date: 2020/12/07 UTC
+Version: 351916971
+Date: 2021/01/15 UTC
 License: BSD
 Security Critical: Yes
 
diff --git a/third_party/metrics_proto/chrome_user_metrics_extension.proto b/third_party/metrics_proto/chrome_user_metrics_extension.proto
index 6fd246e..eb4a41f 100644
--- a/third_party/metrics_proto/chrome_user_metrics_extension.proto
+++ b/third_party/metrics_proto/chrome_user_metrics_extension.proto
@@ -21,14 +21,14 @@
 import "printer_event.proto";
 import "reporting_info.proto";
 import "sampled_profile.proto";
-import "structured_event.proto";
+import "structured_data.proto";
 import "system_profile.proto";
 import "trace_log.proto";
 import "translate_event.proto";
 import "user_action_event.proto";
 import "user_demographics.proto";
 
-// Next tag: 23
+// Next tag: 24
 message ChromeUserMetricsExtension {
   // The product (i.e. end user application) for a given UMA log.
   enum Product {
@@ -89,7 +89,10 @@
   repeated PrinterEventProto printer_event = 16;
   repeated ChromeOSAppListLaunchEventProto chrome_os_app_list_launch_event = 20;
 
-  repeated StructuredEventProto structured_event = 22;
+  repeated StructuredEventProto deprecated_structured_event = 22
+      [deprecated = true];
+
+  optional StructuredDataProto structured_data = 23;
 
   // Deprecated: use |sampled_profile| instead.
   repeated PerfDataProto perf_data = 8 [deprecated = true];
diff --git a/third_party/metrics_proto/extension_install.proto b/third_party/metrics_proto/extension_install.proto
index ad96181..b6d74e1 100644
--- a/third_party/metrics_proto/extension_install.proto
+++ b/third_party/metrics_proto/extension_install.proto
@@ -149,6 +149,9 @@
     DISABLE_REMOTELY_FOR_MALWARE = 15;
     // The extension is being reinstalled.
     REINSTALL = 16;
+    // The extension has been disabled because it's not allowlisted and the Safe
+    // Browsing allowlist is enforced in the user profile.
+    NOT_ALLOWLISTED = 17;
   }
   // Any DisableReasons in effect for the extension. An empty list means the
   // extension is not disabled. Note that an extension that is not disabled may
diff --git a/third_party/metrics_proto/structured_event.proto b/third_party/metrics_proto/structured_data.proto
similarity index 87%
rename from third_party/metrics_proto/structured_event.proto
rename to third_party/metrics_proto/structured_data.proto
index 9029308..c5b9d59e 100644
--- a/third_party/metrics_proto/structured_event.proto
+++ b/third_party/metrics_proto/structured_data.proto
@@ -52,3 +52,10 @@
   }
   repeated Metric metrics = 3;
 }
+
+// The top-level proto for structured metrics. One StructuredDataProto is
+// uploaded per UMA upload containing structured metrics. Contains all
+// structured events for that upload, and any other metadata.
+message StructuredDataProto {
+  repeated StructuredEventProto events = 1;
+}
diff --git a/third_party/minigbm/BUILD.gn b/third_party/minigbm/BUILD.gn
index a611409..954d796 100644
--- a/third_party/minigbm/BUILD.gn
+++ b/third_party/minigbm/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/chromecast_build.gni")
+import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/linux/pkg_config.gni")
 
 assert(is_linux || is_chromeos)
@@ -11,7 +12,7 @@
   # Controls whether the build should use the version of minigbm library shipped
   # with the system. In release builds of desktop Linux and Chrome OS we use the
   # system version.
-  use_system_minigbm = is_linux && !is_chromecast
+  use_system_minigbm = (is_linux || is_chromeos_lacros) && !is_chromecast
 
   use_amdgpu_minigbm = false
   use_exynos_minigbm = false
diff --git a/third_party/polymer/v1_0/BUILD.gn b/third_party/polymer/v1_0/BUILD.gn
index 9870e462..46b0f94 100644
--- a/third_party/polymer/v1_0/BUILD.gn
+++ b/third_party/polymer/v1_0/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("//ui/webui/resources/tools/generate_grd.gni")
 
 generate_grd("build_grdp") {
@@ -76,7 +77,7 @@
     "polymer2/polymer.html",
   ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     input_files += [
       "html-imports/html-imports.min.js",
       "iron-dropdown/iron-dropdown-extracted.js",
diff --git a/third_party/polymer/v3_0/BUILD.gn b/third_party/polymer/v3_0/BUILD.gn
index cdd954e5..4015e239 100644
--- a/third_party/polymer/v3_0/BUILD.gn
+++ b/third_party/polymer/v3_0/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("//ui/webui/resources/tools/generate_grd.gni")
 
 generate_grd("build_grdp") {
@@ -49,7 +50,7 @@
     "polymer/polymer_bundled.min.js",
   ]
 
-  if (is_chromeos) {
+  if (is_chromeos_ash) {
     input_files += [
       "iron-dropdown/iron-dropdown.js",
       "iron-dropdown/iron-dropdown-scroll-manager.js",
diff --git a/third_party/tflite/BUILD.gn b/third_party/tflite/BUILD.gn
index be87702..1153d7ef 100644
--- a/third_party/tflite/BUILD.gn
+++ b/third_party/tflite/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/sanitizers/sanitizers.gni")
 
 config("tflite_config") {
@@ -33,7 +34,7 @@
     defines += [ "TFLITE_WITH_RUY" ]
   }
 
-  if (is_linux) {
+  if (is_linux || is_chromeos_lacros) {
     defines += [ "GEMMLOWP_ALLOW_SLOW_SCALAR_FALLBACK" ]
   }
 }
diff --git a/third_party/webrtc_overrides/BUILD.gn b/third_party/webrtc_overrides/BUILD.gn
index 2e394c5..f62ec73 100644
--- a/third_party/webrtc_overrides/BUILD.gn
+++ b/third_party/webrtc_overrides/BUILD.gn
@@ -78,7 +78,6 @@
     "//third_party/webrtc/pc:rtc_pc_base",
     "//third_party/webrtc/rtc_base",
     "//third_party/webrtc/rtc_base:async_resolver_interface",
-    "//third_party/webrtc/rtc_base:async_resolver",
     "//third_party/webrtc/rtc_base:ip_address",
     "//third_party/webrtc/rtc_base:rtc_base",
     "//third_party/webrtc/rtc_base:rtc_base_approved",
diff --git a/third_party/widevine/cdm/BUILD.gn b/third_party/widevine/cdm/BUILD.gn
index 71bc09b4..e5009f30 100644
--- a/third_party/widevine/cdm/BUILD.gn
+++ b/third_party/widevine/cdm/BUILD.gn
@@ -5,6 +5,7 @@
 import("//build/buildflag_header.gni")
 import("//build/config/chrome_build.gni")
 import("//build/config/chromeos/ui_mode.gni")
+import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/features.gni")
 import("//media/cdm/library_cdm/cdm_paths.gni")
 import("//media/media_options.gni")
@@ -35,7 +36,7 @@
     widevine_cdm_version_h_file =
         "chromeos/$widevine_arch/widevine_cdm_version.h"
     widevine_cdm_binary_files = [ "chromeos/$widevine_arch/libwidevinecdm.so" ]
-  } else if (is_linux) {
+  } else if (is_linux || is_chromeos_lacros) {
     widevine_cdm_version_h_file = "linux/$widevine_arch/widevine_cdm_version.h"
     widevine_cdm_binary_files = [ "linux/$widevine_arch/libwidevinecdm.so" ]
     widevine_cdm_manifest_and_license_files = [
diff --git a/third_party/widevine/cdm/widevine.gni b/third_party/widevine/cdm/widevine.gni
index 5f36e44..b8993da 100644
--- a/third_party/widevine/cdm/widevine.gni
+++ b/third_party/widevine/cdm/widevine.gni
@@ -4,6 +4,7 @@
 
 import("//build/config/chrome_build.gni")
 import("//build/config/chromeos/ui_mode.gni")
+import("//build/config/chromeos/ui_mode.gni")
 import("//media/media_options.gni")
 
 declare_args() {
@@ -23,8 +24,9 @@
 # architectures. Notably on Android library CDM is not used and Widevine is
 # supported via Android MediaDrm API.
 library_widevine_cdm_available =
-    (is_chromeos && (target_cpu == "x64" || target_cpu == "arm")) ||
-    (is_linux && (target_cpu == "x86" || target_cpu == "x64")) ||
+    (is_chromeos_ash && (target_cpu == "x64" || target_cpu == "arm")) ||
+    ((is_linux || is_chromeos_lacros) &&
+     (target_cpu == "x86" || target_cpu == "x64")) ||
     (is_mac && (target_cpu == "x64" || target_cpu == "arm64")) ||
     (is_win && (target_cpu == "x86" || target_cpu == "x64"))
 
@@ -39,7 +41,8 @@
 # it's a component. See below.
 # Note: Not enabled on ChromeOS. See https://crbug.com/971433
 enable_widevine_cdm_component =
-    enable_library_widevine_cdm && (is_win || is_mac || is_linux)
+    enable_library_widevine_cdm &&
+    (is_win || is_mac || is_linux || is_chromeos_lacros)
 
 # Widevine CDM is bundled as part of Google Chrome builds.
 bundle_widevine_cdm = enable_library_widevine_cdm && is_chrome_branded
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 9a53510..e5f530a 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -43952,7 +43952,6 @@
   <int value="-747919789" label="VideoToolboxVp9Decoding:enabled"/>
   <int value="-747463111" label="ContentSuggestionsNotifications:disabled"/>
   <int value="-747072690" label="NtpRepeatableQueries:disabled"/>
-  <int value="-746482855" label="GuestOsExternalProtocol:disabled"/>
   <int value="-746328467" label="ExpensiveBackgroundTimerThrottling:disabled"/>
   <int value="-745082968" label="SyncDeviceInfoInTransportMode:disabled"/>
   <int value="-744159181" label="disable-spdy-proxy-dev-auth-origin"/>
@@ -45077,7 +45076,6 @@
   <int value="351005753" label="enable-experimental-accessibility-autoclick"/>
   <int value="352191859" label="disabled-new-style-notification"/>
   <int value="352937987" label="OverflowIconsForMediaControls:disabled"/>
-  <int value="354523543" label="GuestOsExternalProtocol:enabled"/>
   <int value="354631905" label="RecoverFromNeverSaveAndroid:disabled"/>
   <int value="357138275" label="enable-floating-virtual-keyboard:disabled"/>
   <int value="358399482" label="enable-high-dpi-fixed-position-compositing"/>
@@ -74144,6 +74142,118 @@
   <int value="2" label="Selected Manage Passwords"/>
 </enum>
 
+<enum name="TPMCommandCode">
+  <int value="287" label="TPM_CC_NV_UndefineSpaceSpecial"/>
+  <int value="288" label="TPM_CC_EvictControl"/>
+  <int value="289" label="TPM_CC_HierarchyControl"/>
+  <int value="290" label="TPM_CC_NV_UndefineSpace"/>
+  <int value="292" label="TPM_CC_ChangeEPS"/>
+  <int value="293" label="TPM_CC_ChangePPS"/>
+  <int value="294" label="TPM_CC_Clear"/>
+  <int value="295" label="TPM_CC_ClearControl"/>
+  <int value="296" label="TPM_CC_ClockSet"/>
+  <int value="297" label="TPM_CC_HierarchyChangeAuth"/>
+  <int value="298" label="TPM_CC_NV_DefineSpace"/>
+  <int value="299" label="TPM_CC_PCR_Allocate"/>
+  <int value="300" label="TPM_CC_PCR_SetAuthPolicy"/>
+  <int value="301" label="TPM_CC_PP_Commands"/>
+  <int value="302" label="TPM_CC_SetPrimaryPolicy"/>
+  <int value="303" label="TPM_CC_FieldUpgradeStart"/>
+  <int value="304" label="TPM_CC_ClockRateAdjust"/>
+  <int value="305" label="TPM_CC_CreatePrimary"/>
+  <int value="306" label="TPM_CC_NV_GlobalWriteLock"/>
+  <int value="307" label="TPM_CC_GetCommandAuditDigest"/>
+  <int value="308" label="TPM_CC_NV_Increment"/>
+  <int value="309" label="TPM_CC_NV_SetBits"/>
+  <int value="310" label="TPM_CC_NV_Extend"/>
+  <int value="311" label="TPM_CC_NV_Write"/>
+  <int value="312" label="TPM_CC_NV_WriteLock"/>
+  <int value="313" label="TPM_CC_DictionaryAttackLockReset"/>
+  <int value="314" label="TPM_CC_DictionaryAttackParameters"/>
+  <int value="315" label="TPM_CC_NV_ChangeAuth"/>
+  <int value="316" label="TPM_CC_PCR_Event"/>
+  <int value="317" label="TPM_CC_PCR_Reset"/>
+  <int value="318" label="TPM_CC_SequenceComplete"/>
+  <int value="319" label="TPM_CC_SetAlgorithmSet"/>
+  <int value="320" label="TPM_CC_SetCommandCodeAuditStatus"/>
+  <int value="321" label="TPM_CC_FieldUpgradeData"/>
+  <int value="322" label="TPM_CC_IncrementalSelfTest"/>
+  <int value="323" label="TPM_CC_SelfTest"/>
+  <int value="324" label="TPM_CC_Startup"/>
+  <int value="325" label="TPM_CC_Shutdown"/>
+  <int value="326" label="TPM_CC_StirRandom"/>
+  <int value="327" label="TPM_CC_ActivateCredential"/>
+  <int value="328" label="TPM_CC_Certify"/>
+  <int value="329" label="TPM_CC_PolicyNV"/>
+  <int value="330" label="TPM_CC_CertifyCreation"/>
+  <int value="331" label="TPM_CC_Duplicate"/>
+  <int value="332" label="TPM_CC_GetTime"/>
+  <int value="333" label="TPM_CC_GetSessionAuditDigest"/>
+  <int value="334" label="TPM_CC_NV_Read"/>
+  <int value="335" label="TPM_CC_NV_ReadLock"/>
+  <int value="336" label="TPM_CC_ObjectChangeAuth"/>
+  <int value="337" label="TPM_CC_PolicySecret"/>
+  <int value="338" label="TPM_CC_Rewrap"/>
+  <int value="339" label="TPM_CC_Create"/>
+  <int value="340" label="TPM_CC_ECDH_ZGen"/>
+  <int value="341" label="TPM_CC_HMAC"/>
+  <int value="342" label="TPM_CC_Import"/>
+  <int value="343" label="TPM_CC_Load"/>
+  <int value="344" label="TPM_CC_Quote"/>
+  <int value="345" label="TPM_CC_RSA_Decrypt"/>
+  <int value="347" label="TPM_CC_HMAC_Start"/>
+  <int value="348" label="TPM_CC_SequenceUpdate"/>
+  <int value="349" label="TPM_CC_Sign"/>
+  <int value="350" label="TPM_CC_Unseal"/>
+  <int value="352" label="TPM_CC_PolicySigned"/>
+  <int value="353" label="TPM_CC_ContextLoad"/>
+  <int value="354" label="TPM_CC_ContextSave"/>
+  <int value="355" label="TPM_CC_ECDH_KeyGen"/>
+  <int value="356" label="TPM_CC_EncryptDecrypt"/>
+  <int value="357" label="TPM_CC_FlushContext"/>
+  <int value="359" label="TPM_CC_LoadExternal"/>
+  <int value="360" label="TPM_CC_MakeCredential"/>
+  <int value="361" label="TPM_CC_NV_ReadPublic"/>
+  <int value="362" label="TPM_CC_PolicyAuthorize"/>
+  <int value="363" label="TPM_CC_PolicyAuthValue"/>
+  <int value="364" label="TPM_CC_PolicyCommandCode"/>
+  <int value="365" label="TPM_CC_PolicyCounterTimer"/>
+  <int value="366" label="TPM_CC_PolicyCpHash"/>
+  <int value="367" label="TPM_CC_PolicyLocality"/>
+  <int value="368" label="TPM_CC_PolicyNameHash"/>
+  <int value="369" label="TPM_CC_PolicyOR"/>
+  <int value="370" label="TPM_CC_PolicyTicket"/>
+  <int value="371" label="TPM_CC_ReadPublic"/>
+  <int value="372" label="TPM_CC_RSA_Encrypt"/>
+  <int value="374" label="TPM_CC_StartAuthSession"/>
+  <int value="375" label="TPM_CC_VerifySignature"/>
+  <int value="376" label="TPM_CC_ECC_Parameters"/>
+  <int value="377" label="TPM_CC_FirmwareRead"/>
+  <int value="378" label="TPM_CC_GetCapability"/>
+  <int value="379" label="TPM_CC_GetRandom"/>
+  <int value="380" label="TPM_CC_GetTestResult"/>
+  <int value="381" label="TPM_CC_Hash"/>
+  <int value="382" label="TPM_CC_PCR_Read"/>
+  <int value="383" label="TPM_CC_PolicyPCR"/>
+  <int value="384" label="TPM_CC_PolicyRestart"/>
+  <int value="385" label="TPM_CC_ReadClock"/>
+  <int value="386" label="TPM_CC_PCR_Extend"/>
+  <int value="387" label="TPM_CC_PCR_SetAuthValue"/>
+  <int value="388" label="TPM_CC_NV_Certify"/>
+  <int value="389" label="TPM_CC_EventSequenceComplete"/>
+  <int value="390" label="TPM_CC_HashSequenceStart"/>
+  <int value="391" label="TPM_CC_PolicyPhysicalPresence"/>
+  <int value="392" label="TPM_CC_PolicyDuplicationSelect"/>
+  <int value="393" label="TPM_CC_PolicyGetDigest"/>
+  <int value="394" label="TPM_CC_TestParms"/>
+  <int value="395" label="TPM_CC_Commit"/>
+  <int value="396" label="TPM_CC_PolicyPassword"/>
+  <int value="397" label="TPM_CC_ZGen_2Phase"/>
+  <int value="398" label="TPM_CC_EC_Ephemeral"/>
+  <int value="399" label="TPM_CC_PolicyNvWritten"/>
+  <int value="536903681" label="TPM_CCE_PolicyFidoSigned"/>
+</enum>
+
 <enum name="TPMFirmwareUpdateResult">
   <int value="0" label="Success"/>
   <int value="1" label="Success after retry"/>
diff --git a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
index a9a1af3..41bbd9c8 100644
--- a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
@@ -67,7 +67,7 @@
 </histogram>
 
 <histogram name="Accessibility.Android.UserFontSizePref.Change" units="%"
-    expires_after="M90">
+    expires_after="2021-08-30">
   <owner>twellington@chromium.org</owner>
   <owner>skym@chromium.org</owner>
   <summary>
@@ -78,7 +78,7 @@
 </histogram>
 
 <histogram name="Accessibility.Android.UserFontSizePref.OnStartup" units="%"
-    expires_after="M90">
+    expires_after="2021-08-30">
   <owner>twellington@chromium.org</owner>
   <owner>skym@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml b/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
index d7ad3c5..9ccbb88b 100644
--- a/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
@@ -394,8 +394,8 @@
 </histogram>
 
 <histogram name="Cryptohome.TimeBetweenFreeDiskSpace" units="s"
-    expires_after="M90">
-  <owner>vsavu@chromium.org</owner>
+    expires_after="M93">
+  <owner>vsavu@google.com</owner>
   <owner>slangley@chromium.org</owner>
   <owner>weifangsun@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
index 3757232..6fd63ea 100644
--- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -15245,6 +15245,9 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="RecurrenceRankerModel" separator=".">
+  <obsolete>
+    Removed January 2021, all affected histograms have been deprecated.
+  </obsolete>
   <suffix name="QueryBasedMixedTypes" label=""/>
   <suffix name="QueryBasedMixedTypesGroup" label=""/>
   <suffix name="ZeroStateMixedTypes" label=""/>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index ceff4e75..e594eb4 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -2602,7 +2602,7 @@
 </histogram>
 
 <histogram name="Clipboard.X11StoreCopyPasteDuration" units="ms"
-    expires_after="M90">
+    expires_after="M95">
   <owner>dcheng@chromium.org</owner>
   <owner>pkotwicz@chromium.org</owner>
   <summary>
@@ -12587,6 +12587,9 @@
 
 <histogram base="true" name="RecurrenceRanker.InitializationStatus"
     enum="RecurrenceRankerInitializationStatus" expires_after="2021-02-01">
+  <obsolete>
+    Removed January 2021.
+  </obsolete>
 <!-- Name completed by histogram_suffixes
        name="RecurrenceRankerModel" -->
 
@@ -12600,6 +12603,9 @@
 
 <histogram base="true" name="RecurrenceRanker.JsonConfigConversionStatus"
     enum="BooleanSuccess" expires_after="2021-02-01">
+  <obsolete>
+    Removed January 2021.
+  </obsolete>
 <!-- Name completed by histogram_suffixes
        name="RecurrenceRankerModel" -->
 
@@ -12613,6 +12619,9 @@
 
 <histogram base="true" name="RecurrenceRanker.SerializationStatus"
     enum="RecurrenceRankerSerializationStatus" expires_after="2021-02-01">
+  <obsolete>
+    Removed January 2021.
+  </obsolete>
 <!-- Name completed by histogram_suffixes
        name="RecurrenceRankerModel" -->
 
@@ -12625,6 +12634,9 @@
 
 <histogram base="true" name="RecurrenceRanker.Usage"
     enum="RecurrenceRankerUsage" expires_after="2021-02-01">
+  <obsolete>
+    Removed January 2021.
+  </obsolete>
 <!-- Name completed by histogram_suffixes
        name="RecurrenceRankerModel" -->
 
diff --git a/tools/metrics/histograms/histograms_xml/platform/histograms.xml b/tools/metrics/histograms/histograms_xml/platform/histograms.xml
index ca6b831..9d023670 100644
--- a/tools/metrics/histograms/histograms_xml/platform/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/platform/histograms.xml
@@ -1233,6 +1233,34 @@
   </summary>
 </histogram>
 
+<histogram name="Platform.Trunks.FirstTimeoutReadingCommand"
+    enum="TPMCommandCode" expires_after="2022-01-14">
+  <owner>chingkang@chromium.org</owner>
+  <owner>cros-hwsec+uma@chromium.org</owner>
+  <summary>Command code of the first timeout reading TPM command</summary>
+</histogram>
+
+<histogram name="Platform.Trunks.FirstTimeoutReadingTime" units="seconds"
+    expires_after="2022-01-14">
+  <owner>chingkang@chromium.org</owner>
+  <owner>cros-hwsec+uma@chromium.org</owner>
+  <summary>System uptime when first timeout reading TPM command occurs</summary>
+</histogram>
+
+<histogram name="Platform.Trunks.FirstTimeoutWritingCommand"
+    enum="TPMCommandCode" expires_after="2022-01-14">
+  <owner>chingkang@chromium.org</owner>
+  <owner>cros-hwsec+uma@chromium.org</owner>
+  <summary>Command code of the first timeout writing TPM command</summary>
+</histogram>
+
+<histogram name="Platform.Trunks.FirstTimeoutWritingTime" units="seconds"
+    expires_after="2022-01-14">
+  <owner>chingkang@chromium.org</owner>
+  <owner>cros-hwsec+uma@chromium.org</owner>
+  <summary>System uptime when first timeout writing TPM command occurs</summary>
+</histogram>
+
 <histogram name="Platform.U2F.Command" enum="Cr50U2FCommands"
     expires_after="2021-12-21">
   <owner>cylai@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/uma/histograms.xml b/tools/metrics/histograms/histograms_xml/uma/histograms.xml
index 8c5ae658..b725b22 100644
--- a/tools/metrics/histograms/histograms_xml/uma/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/uma/histograms.xml
@@ -507,7 +507,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.EventRecordingState"
-    enum="StructuredMetricsEventRecordingState" expires_after="2021-06-06">
+    enum="StructuredMetricsEventRecordingState" expires_after="2021-12-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
@@ -519,7 +519,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.InternalError"
-    enum="StructuredMetricsInternalError" expires_after="2021-02-01">
+    enum="StructuredMetricsInternalError" expires_after="2021-12-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
@@ -530,7 +530,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.KeyValidationState"
-    enum="StructuredMetricsKeyValidationState" expires_after="2021-06-06">
+    enum="StructuredMetricsKeyValidationState" expires_after="2021-12-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
@@ -542,7 +542,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.NumEventsInUpload" units="count"
-    expires_after="2021-06-06">
+    expires_after="2021-12-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
@@ -553,7 +553,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.PrefReadError"
-    enum="PrefServiceReadError" expires_after="2021-06-06">
+    enum="PrefServiceReadError" expires_after="2021-12-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
diff --git a/ui/base/ime/chromeos/ime_input_context_handler_interface.h b/ui/base/ime/chromeos/ime_input_context_handler_interface.h
index ce021fe..1edfc63 100644
--- a/ui/base/ime/chromeos/ime_input_context_handler_interface.h
+++ b/ui/base/ime/chromeos/ime_input_context_handler_interface.h
@@ -30,6 +30,8 @@
 
   // Called when the engine changes the composition range.
   // Returns true if the operation was successful.
+  // If |text_spans| is empty, then this function uses a default span that
+  // spans across the new composition range.
   virtual bool SetCompositionRange(
       uint32_t before,
       uint32_t after,
diff --git a/ui/base/ime/chromeos/input_method_chromeos.cc b/ui/base/ime/chromeos/input_method_chromeos.cc
index 5ecc2bb..b84436c 100644
--- a/ui/base/ime/chromeos/input_method_chromeos.cc
+++ b/ui/base/ime/chromeos/input_method_chromeos.cc
@@ -380,16 +380,24 @@
   const auto ordered_range = std::minmax(start, end);
   const gfx::Range composition_range(ordered_range.first, ordered_range.second);
 
+  // Use a default text span that spans across the whole composition range.
+  auto non_empty_text_spans =
+      !text_spans.empty()
+          ? text_spans
+          : std::vector<ui::ImeTextSpan>{ui::ImeTextSpan(
+                ui::ImeTextSpan::Type::kComposition,
+                /*start_offset=*/0, /*end_offset=*/composition_range.length())};
+
   // If we have pending key events, then delay the operation until
   // |ProcessKeyEventPostIME|. Otherwise, process it immediately.
   if (handling_key_event_) {
     composition_changed_ = true;
     pending_composition_range_ =
-        PendingSetCompositionRange{composition_range, text_spans};
+        PendingSetCompositionRange{composition_range, non_empty_text_spans};
     return true;
   } else {
     return client->SetCompositionFromExistingText(composition_range,
-                                                  text_spans);
+                                                  non_empty_text_spans);
   }
 }
 
diff --git a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc
index 048d03a..a0a1ea5 100644
--- a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc
+++ b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc
@@ -951,6 +951,24 @@
   EXPECT_EQ(0U, composition_text_.text.length());
 }
 
+TEST_F(InputMethodChromeOSTest,
+       SetCompositionRangeWithSelectedTextAccountsForSelection) {
+  FakeTextInputClient fake_text_input_client(TEXT_INPUT_TYPE_TEXT);
+  fake_text_input_client.SetTextAndSelection(base::ASCIIToUTF16("01234"),
+                                             gfx::Range(1, 4));
+  InputMethodChromeOS ime(this);
+  ime.SetFocusedTextInputClient(&fake_text_input_client);
+
+  // before/after are relative to the selection start/end, respectively.
+  EXPECT_TRUE(ime.SetCompositionRange(/*before=*/1, /*after=*/1, {}));
+
+  EXPECT_EQ(fake_text_input_client.composition_range(), gfx::Range(0, 5));
+  EXPECT_THAT(fake_text_input_client.ime_text_spans(),
+              testing::ElementsAre(
+                  ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition,
+                                  /*start_offset=*/0, /*end_offset=*/5)));
+}
+
 TEST_F(InputMethodChromeOSTest, ConfirmCompositionText_NoComposition) {
   // Focus on a text field.
   input_type_ = TEXT_INPUT_TYPE_TEXT;
diff --git a/ui/base/ime/fake_text_input_client.cc b/ui/base/ime/fake_text_input_client.cc
index 262234b..647dbec 100644
--- a/ui/base/ime/fake_text_input_client.cc
+++ b/ui/base/ime/fake_text_input_client.cc
@@ -4,6 +4,7 @@
 
 #include "ui/base/ime/fake_text_input_client.h"
 
+#include "base/check_op.h"
 #include "build/chromeos_buildflags.h"
 #include "ui/events/event_constants.h"
 #include "ui/gfx/geometry/rect.h"
@@ -19,6 +20,13 @@
   text_input_type_ = text_input_type;
 }
 
+void FakeTextInputClient::SetTextAndSelection(const base::string16& text,
+                                              gfx::Range selection) {
+  DCHECK_LE(selection_.end(), text.length());
+  text_ = text;
+  selection_ = selection;
+}
+
 void FakeTextInputClient::SetCompositionText(
     const CompositionText& composition) {}
 
@@ -80,7 +88,8 @@
 }
 
 bool FakeTextInputClient::GetTextRange(gfx::Range* range) const {
-  return false;
+  *range = gfx::Range(0, text_.length());
+  return true;
 }
 
 bool FakeTextInputClient::GetCompositionTextRange(gfx::Range* range) const {
@@ -88,7 +97,8 @@
 }
 
 bool FakeTextInputClient::GetEditableSelectionRange(gfx::Range* range) const {
-  return false;
+  *range = selection_;
+  return true;
 }
 
 bool FakeTextInputClient::SetEditableSelectionRange(const gfx::Range& range) {
@@ -136,7 +146,12 @@
 bool FakeTextInputClient::SetCompositionFromExistingText(
     const gfx::Range& range,
     const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) {
-  return false;
+  if (range.start() < 0 || range.end() > text_.length())
+    return false;
+
+  composition_range_ = range;
+  ime_text_spans_ = ui_ime_text_spans;
+  return true;
 }
 #endif
 
diff --git a/ui/base/ime/fake_text_input_client.h b/ui/base/ime/fake_text_input_client.h
index e22d14fc..fbf2c6b 100644
--- a/ui/base/ime/fake_text_input_client.h
+++ b/ui/base/ime/fake_text_input_client.h
@@ -25,8 +25,14 @@
   ~FakeTextInputClient() override;
 
   void set_text_input_type(TextInputType text_input_type);
+  void SetTextAndSelection(const base::string16& text, gfx::Range selection);
+
   const base::string16& text() const { return text_; }
   const gfx::Range& selection() const { return selection_; }
+  const gfx::Range& composition_range() const { return composition_range_; }
+  const std::vector<ui::ImeTextSpan>& ime_text_spans() const {
+    return ime_text_spans_;
+  }
 
   // TextInputClient:
   void SetCompositionText(const CompositionText& composition) override;
@@ -86,6 +92,8 @@
   TextInputType text_input_type_;
   base::string16 text_;
   gfx::Range selection_;
+  gfx::Range composition_range_;
+  std::vector<ui::ImeTextSpan> ime_text_spans_;
 };
 
 }  // namespace ui
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn
index e8294a2..9a7a20e1 100644
--- a/ui/file_manager/BUILD.gn
+++ b/ui/file_manager/BUILD.gn
@@ -67,7 +67,6 @@
     "gallery/js:js_test_gen_html",
     "gallery/js/image_editor:js_test_gen_html",
     "gallery/js/image_editor:js_test_gen_html_modules",
-    "image_loader:js_test_gen_html",
     "image_loader:js_test_gen_html_modules",
     "video_player/js:js_test_gen_html_modules",
   ]
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index c945dc5..225e1ecb 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -48,6 +48,7 @@
     ":fake_android_app_list_model.m",
     ":fake_file_selection_handler.m",
     ":file_list_model.m",
+    ":file_manager.m",
     ":file_manager_commands.m",
     ":file_selection.m",
     ":file_tasks.m",
@@ -810,6 +811,90 @@
   ]
 }
 
+js_library("file_manager.m") {
+  sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/file_manager.m.js" ]
+  deps = [
+    ":actions_controller.m",
+    ":android_app_list_model.m",
+    ":app_state_controller.m",
+    ":column_visibility_controller.m",
+    ":crossover_search_utils.m",
+    ":crostini_controller.m",
+    ":dialog_action_controller.m",
+    ":dialog_type.m",
+    ":directory_contents.m",
+    ":directory_model.m",
+    ":directory_tree_naming_controller.m",
+    ":empty_folder_controller.m",
+    ":file_manager_commands.m",
+    ":file_selection.m",
+    ":file_tasks.m",
+    ":file_transfer_controller.m",
+    ":file_type_filters_controller.m",
+    ":folder_shortcuts_data_model.m",
+    ":gear_menu_controller.m",
+    ":import_controller.m",
+    ":last_modified_controller.m",
+    ":launch_param.m",
+    ":list_thumbnail_loader.m",
+    ":main_window_component.m",
+    ":metadata_box_controller.m",
+    ":metadata_update_controller.m",
+    ":naming_controller.m",
+    ":navigation_list_model.m",
+    ":navigation_uma.m",
+    ":providers_model.m",
+    ":quick_view_controller.m",
+    ":quick_view_model.m",
+    ":quick_view_uma.m",
+    ":scan_controller.m",
+    ":search_controller.m",
+    ":selection_menu_controller.m",
+    ":sort_menu_controller.m",
+    ":spinner_controller.m",
+    ":task_controller.m",
+    ":toolbar_controller.m",
+    "metadata:metadata_model.m",
+    "metadata:thumbnail_model.m",
+    "ui:a11y_announce.m",
+    "ui:banners.m",
+    "ui:commandbutton.m",
+    "ui:directory_tree.m",
+    "ui:file_grid.m",
+    "ui:file_list_selection_model.m",
+    "ui:file_manager_ui.m",
+    "ui:file_metadata_formatter.m",
+    "ui:file_table.m",
+    "//ui/file_manager/base/js:filtered_volume_manager.m",
+    "//ui/file_manager/base/js:volume_manager_types.m",
+    "//ui/file_manager/externs:background_window.m",
+    "//ui/file_manager/externs:command_handler_deps.m",
+    "//ui/file_manager/externs:files_app_entry_interfaces.m",
+    "//ui/file_manager/externs/background:crostini.m",
+    "//ui/file_manager/externs/background:file_browser_background_full.m",
+    "//ui/file_manager/externs/background:file_operation_manager.m",
+    "//ui/file_manager/externs/background:import_history.m",
+    "//ui/file_manager/externs/background:media_import_handler.m",
+    "//ui/file_manager/externs/background:media_scanner.m",
+    "//ui/file_manager/externs/background:progress_center.m",
+    "//ui/file_manager/file_manager/common/js:files_app_entry_types.m",
+    "//ui/file_manager/file_manager/common/js:metrics.m",
+    "//ui/file_manager/file_manager/common/js:progress_center_common.m",
+    "//ui/file_manager/file_manager/common/js:util.m",
+    "//ui/file_manager/file_manager/foreground/elements:files_message.m",
+    "//ui/webui/resources/js:assert.m",
+    "//ui/webui/resources/js:load_time_data.m",
+    "//ui/webui/resources/js:util.m",
+    "//ui/webui/resources/js/cr:event_target.m",
+    "//ui/webui/resources/js/cr/ui:array_data_model.m",
+    "//ui/webui/resources/js/cr/ui:context_menu_handler.m",
+    "//ui/webui/resources/js/cr/ui:list.m",
+    "//ui/webui/resources/js/cr/ui:menu.m",
+  ]
+
+  extra_deps = [ ":modulize" ]
+}
+
 js_library("file_manager_commands") {
   deps = [
     ":actions_controller",
@@ -1993,6 +2078,7 @@
     "fake_android_app_list_model.js",
     "fake_file_selection_handler.js",
     "file_list_model.js",
+    "file_manager.js",
     "file_manager_commands.js",
     "file_selection.js",
     "file_tasks.js",
@@ -2042,5 +2128,6 @@
                          "cr.ui.ComboButton|ComboButton",
                          "cr.filebrowser.DefaultTaskDialog|DefaultTaskDialog",
                          "cr.ui.Command|CrUiCommand",
+                         "window.importElementsPromise|importElements",
                        ]
 }
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 1cff976..71138537 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -2,6 +2,86 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// clang-format off
+// #import {List} from 'chrome://resources/js/cr/ui/list.m.js';
+// #import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
+// #import {FilesMessage} from '../elements/files_message.m.js';
+// #import {FileListSelectionModel} from './ui/file_list_selection_model.m.js';
+// #import {A11yAnnounce} from './ui/a11y_announce.m.js';
+// #import {ProgressCenter} from '../../../externs/background/progress_center.m.js';
+// #import {FakeEntry, FilesAppDirEntry} from '../../../externs/files_app_entry_interfaces.m.js';
+// #import {FileBrowserBackgroundFull} from '../../../externs/background/file_browser_background_full.m.js';
+// #import {BackgroundWindow} from '../../../externs/background_window.m.js';
+// #import {FileOperationManager} from '../../../externs/background/file_operation_manager.m.js';
+// #import {mediaImportInterfaces} from '../../../externs/background/media_import_handler.m.js';
+// #import {mediaScannerInterfaces} from '../../../externs/background/media_scanner.m.js';
+// #import {Crostini} from '../../../externs/background/crostini.m.js';
+// #import {importerHistoryInterfaces} from '../../../externs/background/import_history.m.js';
+// #import {CommandHandlerDeps} from '../../../externs/command_handler_deps.m.js';
+// #import {ProgressItemState} from '../../common/js/progress_center_common.m.js';
+// #import {crossoverSearchUtils} from './crossover_search_utils.m.js';
+// #import {FileTasks} from './file_tasks.m.js';
+// #import {CrostiniController} from './crostini_controller.m.js';
+// #import {NavigationListModel, NavigationModelFakeItem, NavigationModelItemType} from './navigation_list_model.m.js';
+// #import {DirectoryTree} from './ui/directory_tree.m.js';
+// #import {NavigationUma} from './navigation_uma.m.js';
+// #import {FileTypeFiltersController} from './file_type_filters_controller.m.js';
+// #import {DialogActionController} from './dialog_action_controller.m.js';
+// #import {SpinnerController} from './spinner_controller.m.js';
+// #import {DirectoryTreeNamingController} from './directory_tree_naming_controller.m.js';
+// #import {SearchController} from './search_controller.m.js';
+// #import {TaskController} from './task_controller.m.js';
+// #import {NamingController} from './naming_controller.m.js';
+// #import {MetadataUpdateController} from './metadata_update_controller.m.js';
+// #import {ColumnVisibilityController} from './column_visibility_controller.m.js';
+// #import {ListThumbnailLoader} from './list_thumbnail_loader.m.js';
+// #import {FileSelectionHandler, FileSelection} from './file_selection.m.js';
+// #import {FakeEntryImpl} from '../../common/js/files_app_entry_types.m.js';
+// #import {AndroidAppListModel} from './android_app_list_model.m.js';
+// #import {FolderShortcutsDataModel} from './folder_shortcuts_data_model.m.js';
+// #import {DirectoryModel} from './directory_model.m.js';
+// #import {assert, assertInstanceof} from 'chrome://resources/js/assert.m.js';
+// #import {FileGrid} from './ui/file_grid.m.js';
+// #import {FileTable} from './ui/file_table.m.js';
+// #import {FileManagerUI} from './ui/file_manager_ui.m.js';
+// #import {queryRequiredElement} from 'chrome://resources/js/util.m.js';
+// #import {FileFilter} from './directory_contents.m.js';
+// #import {ProvidersModel} from './providers_model.m.js';
+// #import {ThumbnailModel} from './metadata/thumbnail_model.m.js';
+// #import {MetadataModel} from './metadata/metadata_model.m.js';
+// #import {FilteredVolumeManager} from '../../../base/js/filtered_volume_manager.m.js';
+// #import {LaunchParam} from './launch_param.m.js';
+// #import {contextMenuHandler} from 'chrome://resources/js/cr/ui/context_menu_handler.m.js';
+// #import {CommandButton} from './ui/commandbutton.m.js';
+// #import {CommandHandler, CommandUtil} from './file_manager_commands.m.js';
+// #import {FileTransferController} from './file_transfer_controller.m.js';
+// #import {Banners} from './ui/banners.m.js';
+// #import {MainWindowComponent} from './main_window_component.m.js';
+// #import {QuickViewController} from './quick_view_controller.m.js';
+// #import {MetadataBoxController} from './metadata_box_controller.m.js';
+// #import {QuickViewUma} from './quick_view_uma.m.js';
+// #import {QuickViewModel} from './quick_view_model.m.js';
+// #import {LastModifiedController} from './last_modified_controller.m.js';
+// #import {ActionsController} from './actions_controller.m.js';
+// #import {EmptyFolderController} from './empty_folder_controller.m.js';
+// #import {ToolbarController} from './toolbar_controller.m.js';
+// #import {Menu} from 'chrome://resources/js/cr/ui/menu.m.js';
+// #import {util, str} from '../../common/js/util.m.js';
+// #import {SelectionMenuController} from './selection_menu_controller.m.js';
+// #import {GearMenuController} from './gear_menu_controller.m.js';
+// #import {SortMenuController} from './sort_menu_controller.m.js';
+// #import {ScanController} from './scan_controller.m.js';
+// #import {VolumeManagerCommon, AllowedPaths} from '../../../base/js/volume_manager_types.m.js';
+// #import {AppStateController} from './app_state_controller.m.js';
+// #import {DialogType} from './dialog_type.m.js';
+// #import {FileMetadataFormatter} from './ui/file_metadata_formatter.m.js';
+// #import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
+// #import {importer} from './import_controller.m.js';
+// #import {metrics} from '../../common/js/metrics.m.js';
+// #import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+// #import {importElements} from './elements_importer.m.js';
+// clang-format on
+
 /**
  * FileManager constructor.
  *
@@ -10,7 +90,7 @@
  *
  * @implements {CommandHandlerDeps}
  */
-class FileManager extends cr.EventTarget {
+/* #export */ class FileManager extends cr.EventTarget {
   constructor() {
     super();
 
diff --git a/ui/file_manager/image_loader/BUILD.gn b/ui/file_manager/image_loader/BUILD.gn
index 2ed6c6d..46176cc 100644
--- a/ui/file_manager/image_loader/BUILD.gn
+++ b/ui/file_manager/image_loader/BUILD.gn
@@ -10,8 +10,14 @@
 js_type_check("closure_compile_jsmodules") {
   uses_js_modules = true
   deps = [
+    ":cache.m",
+    ":image_loader.m",
     ":image_loader_client.m",
+    ":image_loader_util.m",
+    ":image_request_task.m",
     ":load_image_request.m",
+    ":piex_loader.m",
+    ":scheduler.m",
   ]
 }
 
@@ -37,11 +43,16 @@
 js_library("cache") {
 }
 
-js_unittest("cache_unittest") {
+js_library("cache.m") {
+  sources = [ "$root_gen_dir/ui/file_manager/image_loader/cache.m.js" ]
+
+  extra_deps = [ ":modulize" ]
+}
+
+js_unittest("cache_unittest.m") {
   deps = [
-    ":cache",
-    ":load_image_request",
-    "//ui/webui/resources/js:webui_resource_test",
+    ":load_image_request.m",
+    "//chrome/test/data/webui:chai_assert",
   ]
 }
 
@@ -55,10 +66,26 @@
   ]
 }
 
-js_unittest("image_loader_unittest") {
+js_library("image_loader.m") {
+  sources = [ "$root_gen_dir/ui/file_manager/image_loader/image_loader.m.js" ]
   deps = [
-    ":image_loader",
-    "//ui/webui/resources/js:webui_resource_test",
+    ":cache.m",
+    ":image_request_task.m",
+    ":load_image_request.m",
+    ":scheduler.m",
+    "//ui/file_manager/file_manager/foreground/js/metadata:image_orientation.m",
+    "//ui/webui/resources/js:assert.m",
+  ]
+
+  extra_deps = [ ":modulize" ]
+}
+
+js_unittest("image_loader_unittest.m") {
+  deps = [
+    ":image_loader_util.m",
+    ":load_image_request.m",
+    "//chrome/test/data/webui:chai_assert",
+    "//ui/file_manager/file_manager/foreground/js/metadata:image_orientation.m",
   ]
 }
 
@@ -69,6 +96,17 @@
   ]
 }
 
+js_library("image_loader_util.m") {
+  sources =
+      [ "$root_gen_dir/ui/file_manager/image_loader/image_loader_util.m.js" ]
+  deps = [
+    ":load_image_request.m",
+    "//ui/webui/resources/js:assert.m",
+  ]
+
+  extra_deps = [ ":modulize" ]
+}
+
 js_library("load_image_request") {
   deps = [
     "//ui/file_manager/file_manager/foreground/js/metadata:image_orientation",
@@ -131,6 +169,13 @@
   externs_list = [ "//ui/file_manager/externs/platform.js" ]
 }
 
+js_library("piex_loader.m") {
+  sources = [ "$root_gen_dir/ui/file_manager/image_loader/piex_loader.m.js" ]
+  externs_list = [ "//ui/file_manager/externs/platform.js" ]
+
+  extra_deps = [ ":modulize" ]
+}
+
 js_library("image_request_task") {
   deps = [
     ":cache",
@@ -142,19 +187,48 @@
   externs_list = [ "//ui/file_manager/externs/platform.js" ]
 }
 
+js_library("image_request_task.m") {
+  sources =
+      [ "$root_gen_dir/ui/file_manager/image_loader/image_request_task.m.js" ]
+  deps = [
+    ":cache.m",
+    ":image_loader_util.m",
+    ":load_image_request.m",
+    ":piex_loader.m",
+    "//ui/file_manager/file_manager/common/js:file_type.m",
+    "//ui/file_manager/file_manager/foreground/js/metadata:image_orientation.m",
+    "//ui/webui/resources/js:assert.m",
+  ]
+
+  extra_deps = [ ":modulize" ]
+}
+
 js_library("scheduler") {
   deps = [ ":image_request_task" ]
 }
 
-js_unittest("scheduler_unittest") {
+js_library("scheduler.m") {
+  sources = [ "$root_gen_dir/ui/file_manager/image_loader/scheduler.m.js" ]
+  deps = [ ":image_request_task.m" ]
+
+  extra_deps = [ ":modulize" ]
+}
+
+js_unittest("scheduler_unittest.m") {
   deps = [
-    ":scheduler",
-    "//ui/webui/resources/js:webui_resource_test",
+    ":image_request_task.m",
+    ":scheduler.m",
+    "//chrome/test/data/webui:chai_assert",
   ]
 }
 
 js_test_gen_html("js_test_gen_html_modules") {
-  deps = [ ":image_loader_client_unittest.m" ]
+  deps = [
+    ":cache_unittest.m",
+    ":image_loader_client_unittest.m",
+    ":image_loader_unittest.m",
+    ":scheduler_unittest.m",
+  ]
   js_module = true
 
   closure_flags =
@@ -165,22 +239,12 @@
       ]
 }
 
-js_test_gen_html("js_test_gen_html") {
-  closure_flags = default_closure_args + [ "jscomp_error=strictCheckTypes" ]
-  deps = [
-    ":cache_unittest",
-    ":image_loader_unittest",
-    ":scheduler_unittest",
-  ]
-}
-
 group("closure_compile") {
   testonly = true
   deps = [
     ":closure_compile_jsmodules",
     ":closure_compile_module",
     ":js_test_gen_html_modules_type_check_auto",
-    ":js_test_gen_html_type_check_auto",
   ]
 }
 
@@ -188,5 +252,11 @@
   input_files = [
     "image_loader_client.js",
     "load_image_request.js",
+    "cache.js",
+    "piex_loader.js",
+    "image_loader_util.js",
+    "scheduler.js",
+    "image_request_task.js",
+    "image_loader.js",
   ]
 }
diff --git a/ui/file_manager/image_loader/cache.js b/ui/file_manager/image_loader/cache.js
index 030d49e..32dfcbe 100644
--- a/ui/file_manager/image_loader/cache.js
+++ b/ui/file_manager/image_loader/cache.js
@@ -6,7 +6,7 @@
  * Persistent cache storing images in an indexed database on the hard disk.
  * @constructor
  */
-function ImageCache() {
+/* #export */ function ImageCache() {
   /**
    * IndexedDB database handle.
    * @type {IDBDatabase}
diff --git a/ui/file_manager/image_loader/cache_unittest.js b/ui/file_manager/image_loader/cache_unittest.m.js
similarity index 66%
rename from ui/file_manager/image_loader/cache_unittest.js
rename to ui/file_manager/image_loader/cache_unittest.m.js
index 4c4d1e8..01fdeee 100644
--- a/ui/file_manager/image_loader/cache_unittest.js
+++ b/ui/file_manager/image_loader/cache_unittest.m.js
@@ -2,14 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
+import {assertFalse, assertTrue} from 'chrome://test/chai_assert.js';
+import {LoadImageRequest} from './load_image_request.m.js';
 
-function testCreateCacheKey() {
+
+export function testCreateCacheKey() {
   const key = LoadImageRequest.cacheKey({url: 'http://example.com/image.jpg'});
   assertTrue(!!key);
 }
 
-function testNotCreateCacheKey() {
+export function testNotCreateCacheKey() {
   let key = LoadImageRequest.cacheKey({url: 'data:xxx'});
   assertFalse(!!key);
 
diff --git a/ui/file_manager/image_loader/image_loader.js b/ui/file_manager/image_loader/image_loader.js
index 368a7fd..6115c8f 100644
--- a/ui/file_manager/image_loader/image_loader.js
+++ b/ui/file_manager/image_loader/image_loader.js
@@ -2,11 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// clang-format off
+// #import {LoadImageRequest, LoadImageResponse} from './load_image_request.m.js';
+// #import {ImageRequestTask} from './image_request_task.m.js';
+// #import {ImageOrientation} from '../file_manager/foreground/js/metadata/image_orientation.m.js';
+// #import {assert} from 'chrome://resources/js/assert.m.js';
+// #import {Scheduler} from './scheduler.m.js';
+// #import {ImageCache} from './cache.m.js';
+// clang-format on
+
 /**
  * Loads and resizes an image.
  * @constructor
  */
-function ImageLoader() {
+/* #export */ function ImageLoader() {
   /**
    * Persistent cache object.
    * @type {ImageCache}
diff --git a/ui/file_manager/image_loader/image_loader_unittest.js b/ui/file_manager/image_loader/image_loader_unittest.m.js
similarity index 90%
rename from ui/file_manager/image_loader/image_loader_unittest.js
rename to ui/file_manager/image_loader/image_loader_unittest.m.js
index d004d09..b0e08852 100644
--- a/ui/file_manager/image_loader/image_loader_unittest.js
+++ b/ui/file_manager/image_loader/image_loader_unittest.m.js
@@ -2,6 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {assertEquals} from 'chrome://test/chai_assert.js';
+import {ImageOrientation} from '../file_manager/foreground/js/metadata/image_orientation.m.js';
+import {ImageLoaderUtil} from './image_loader_util.m.js';
+import {LoadImageRequest} from './load_image_request.m.js';
+
+
 /**
  * Casts a map of options as an incoming load request to test CopyParameters.
  *
@@ -19,7 +25,7 @@
  * - Source image: 200x50
  * - Target: max size is 100x100
  */
-function testNormalImage() {
+export function testNormalImage() {
   const source = new Image();
   source.width = 200;
   source.height = 50;
@@ -46,7 +52,7 @@
  * - Source image: 50x200 90 deg clock-wise rotated image.
  * - Target: max size is 100x100
  */
-function testRotatedImage() {
+export function testRotatedImage() {
   const source = new Image();
   source.width = 50;
   source.height = 200;
@@ -73,7 +79,7 @@
  * - Source image: 800x100
  * - Target: 50x50 cropped image.
  */
-function testCroppedImage() {
+export function testCroppedImage() {
   const source = new Image();
   source.width = 800;
   source.height = 100;
@@ -101,7 +107,7 @@
  * - Source image: 200x25
  * - Target: 50x50 cropped image.
  */
-function testCroppedImageWithResize() {
+export function testCroppedImageWithResize() {
   const source = new Image();
   source.width = 200;
   source.height = 25;
@@ -129,7 +135,7 @@
  * - Source image: 20x10
  * - Target: 50x50 cropped image.
  */
-function testCroppedTinyImage() {
+export function testCroppedTinyImage() {
   const source = new Image();
   source.width = 20;
   source.height = 10;
@@ -157,7 +163,7 @@
  * - Source image: 100x400 90 degree clock-wise rotated.
  * - Target: 50x50 cropped image
  */
-function testCroppedRotatedImage() {
+export function testCroppedRotatedImage() {
   const source = new Image();
   source.width = 100;
   source.height = 400;
diff --git a/ui/file_manager/image_loader/image_loader_util.js b/ui/file_manager/image_loader/image_loader_util.js
index ba111f2..9108faf8 100644
--- a/ui/file_manager/image_loader/image_loader_util.js
+++ b/ui/file_manager/image_loader/image_loader_util.js
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-function ImageLoaderUtil() {}
+// #import {LoadImageRequest} from './load_image_request.m.js';
+// #import {assert} from 'chrome://resources/js/assert.m.js';
+
+/* #export */ function ImageLoaderUtil() {}
 
 /**
  * Checks if the options on the request contain any image processing.
diff --git a/ui/file_manager/image_loader/image_request_task.js b/ui/file_manager/image_loader/image_request_task.js
index ea90e7b8..81381f9 100644
--- a/ui/file_manager/image_loader/image_request_task.js
+++ b/ui/file_manager/image_loader/image_request_task.js
@@ -2,6 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// clang-format off
+// #import {ImageCache} from './cache.m.js';
+// #import {ImageLoaderUtil} from './image_loader_util.m.js';
+// #import {ImageOrientation} from '../file_manager/foreground/js/metadata/image_orientation.m.js';
+// #import {PiexLoader} from './piex_loader.m.js';
+// #import {FileType} from '../file_manager/common/js/file_type.m.js';
+// #import {LoadImageRequest, LoadImageResponse, LoadImageResponseStatus} from './load_image_request.m.js';
+// #import {assert, assertInstanceof} from 'chrome://resources/js/assert.m.js';
+// clang-format on
+
 /**
  * Creates and starts downloading and then resizing of the image. Finally,
  * returns the image using the callback.
@@ -12,7 +22,7 @@
  * @param {function(!LoadImageResponse)} callback Response handler.
  * @constructor
  */
-function ImageRequestTask(id, cache, request, callback) {
+/* #export */ function ImageRequestTask(id, cache, request, callback) {
   /**
    * Global ID (concatenated client ID and client request ID).
    * @type {string}
diff --git a/ui/file_manager/image_loader/piex_loader.js b/ui/file_manager/image_loader/piex_loader.js
index a654aa6b..d298990 100644
--- a/ui/file_manager/image_loader/piex_loader.js
+++ b/ui/file_manager/image_loader/piex_loader.js
@@ -718,7 +718,7 @@
 /**
  * PiexLoader: is a namespace.
  */
-const PiexLoader = {};
+/* #export */ const PiexLoader = {};
 
 /**
  * Loads a RAW image. Returns the image metadata and the image thumbnail in a
diff --git a/ui/file_manager/image_loader/scheduler.js b/ui/file_manager/image_loader/scheduler.js
index e97ad830..78ccc81 100644
--- a/ui/file_manager/image_loader/scheduler.js
+++ b/ui/file_manager/image_loader/scheduler.js
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// #import {ImageRequestTask} from './image_request_task.m.js';
+
 /**
  * Scheduler for ImageRequestTask objects. Fetches tasks from a queue and
  * processes them synchronously, taking into account priorities. The highest
  * priority is 0.
  * @constructor
  */
-function Scheduler() {
+/* #export */ function Scheduler() {
   /**
    * List of tasks waiting to be checked. If these items are available in
    * cache, then they are processed immediately after starting the scheduler.
diff --git a/ui/file_manager/image_loader/scheduler_unittest.js b/ui/file_manager/image_loader/scheduler_unittest.m.js
similarity index 88%
rename from ui/file_manager/image_loader/scheduler_unittest.js
rename to ui/file_manager/image_loader/scheduler_unittest.m.js
index a8d9ac9d..a6dcffc 100644
--- a/ui/file_manager/image_loader/scheduler_unittest.js
+++ b/ui/file_manager/image_loader/scheduler_unittest.m.js
@@ -2,14 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
+import {assertEquals} from 'chrome://test/chai_assert.js';
+import {ImageRequestTask} from './image_request_task.m.js';
+import {Scheduler} from './scheduler.m.js';
+
 
 /**
  * Fake global clock used to record the "time" at which a task was run.
  */
 let globalTime = 0;
 
-function setUp() {
+export function setUp() {
   globalTime = 0;
 }
 
@@ -55,7 +58,7 @@
 /**
  * Checks that adding and removing tasks before the scheduler is started works.
  */
-function testIdleSchedulerAddRemove() {
+export function testIdleSchedulerAddRemove() {
   const scheduler = new Scheduler();
   const fakeTask = newTask('task-1', 0);
   scheduler.add(/** @type {!ImageRequestTask} */ (fakeTask));
@@ -71,7 +74,7 @@
  * tasks when scheduler is started. They also should be executed in the
  * order of their priorities.
  */
-function testNewTasksMovedAndRunInPriorityOrder() {
+export function testNewTasksMovedAndRunInPriorityOrder() {
   const fakeTask1 = newTask('task-1', 1);
   const fakeTask2 = newTask('task-2', 0);
 
@@ -87,7 +90,7 @@
 /**
  * Checks that the scheduler only launches MAXIMUM_IN_PARALLEL tasks.
  */
-function testParallelTasks() {
+export function testParallelTasks() {
   const scheduler = new Scheduler();
   const taskList = [];
   for (let i = 0; i <= Scheduler.MAXIMUM_IN_PARALLEL; ++i) {
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
index eb652349..144618f 100644
--- a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
+++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
@@ -74,9 +74,8 @@
   // world becomes new enough.
   const crosapi::mojom::LacrosInitParams* init_params =
       lacros_chrome_service->init_params();
-  if (init_params &&
-      init_params->exo_ime_support ==
-          crosapi::mojom::ExoImeSupport::kConsumedByImeWorkaround) {
+  if (init_params && init_params->exo_ime_support !=
+                         crosapi::mojom::ExoImeSupport::kUnsupported) {
     return true;
   }
 #endif