diff --git a/DEPS b/DEPS
index 6c2f029c..37fe6b9 100644
--- a/DEPS
+++ b/DEPS
@@ -121,11 +121,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'e9742a5a0db1e86f1b548d74c025404690eaed63',
+  'skia_revision': 'd20cf33472417ef8156553033f5faa2f2d8850bb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '7920be1f5a1fa8e0a6484e50a5e15bb4da2f29d9',
+  'v8_revision': 'd00f37dbe0937f28b8d74e49506789bbd16ff8b5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -141,7 +141,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '787f953343b0cd97e946682cc28be5d9900f2e49',
+  'swiftshader_revision': '5ebd2c0fafca2f0d570ca25605092b5c7aaadd42',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -233,7 +233,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': '7f1a020abc82e73576147d344607034825bea18a',
+  'spv_tools_revision': '464111eaef80c4951e63473bc1c9e072f8d33588',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -372,7 +372,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'eb06a3ba6561b910857100bdedd50eb6167d7eba',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'fa005e3a713d0a24c40b88916c53d36498c9256e',
       'condition': 'checkout_ios',
   },
 
@@ -1054,7 +1054,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'a3eb6034c5d2949481222e93246db1b4617cc33a',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'faa547c0731a568980a712c238b22692d29649f4',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1258,7 +1258,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@cad0b15c2af9195854eb6b0122d841c0deb66b5d',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0ec02f9abd06dcf9f97c6612927cd537d12baaad',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/public/interfaces/wallpaper.mojom b/ash/public/interfaces/wallpaper.mojom
index 5c524b4..6601ff3 100644
--- a/ash/public/interfaces/wallpaper.mojom
+++ b/ash/public/interfaces/wallpaper.mojom
@@ -53,14 +53,11 @@
   //                                    reside.
   // |device_policy_wallpaper_path|: The file path of the device policy
   //                                 wallpaper (if any).
-  // |is_device_wallpaper_policy_enforced|: Whether the device wallpaper policy
-  //                                        is enforced on the device.
   Init(WallpaperControllerClient client,
        mojo_base.mojom.FilePath user_data_path,
        mojo_base.mojom.FilePath chromeos_wallpapers_path,
        mojo_base.mojom.FilePath chromeos_custom_wallpapers_path,
-       mojo_base.mojom.FilePath device_policy_wallpaper_path,
-       bool is_device_wallpaper_policy_enforced);
+       mojo_base.mojom.FilePath device_policy_wallpaper_path);
 
   // Sets wallpaper from a local file and updates the saved wallpaper info for
   // the user.
@@ -145,9 +142,12 @@
                      string wallpaper_files_id,
                      string data);
 
-  // Sets whether device wallpaper policy is enforced on this device. Updates/
-  // clears the device policy controlled wallpaper if applicable.
-  SetDeviceWallpaperPolicyEnforced(bool enforced);
+  // Sets the path of device policy wallpaper.
+  // |device_policy_wallpaper_path|: The file path of the device policy
+  //                                 wallpaper if it was set or empty value if
+  //                                 it was cleared.
+  SetDevicePolicyWallpaperPath(
+      mojo_base.mojom.FilePath device_policy_wallpaper_path);
 
   // Sets wallpaper from a third-party app (as opposed to the Chrome OS
   // wallpaper picker).
diff --git a/ash/shelf/shelf_button.cc b/ash/shelf/shelf_button.cc
index 991c5d5..5427a844 100644
--- a/ash/shelf/shelf_button.cc
+++ b/ash/shelf/shelf_button.cc
@@ -52,11 +52,6 @@
   return true;
 }
 
-void ShelfButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
-  node_data->role = ax::mojom::Role::kButton;
-  node_data->SetName(GetAccessibleName());
-}
-
 bool ShelfButton::GetTooltipText(const gfx::Point& p,
                                  base::string16* tooltip) const {
   // Copy the proper tooltip text, but return false because we do not want to
diff --git a/ash/shelf/shelf_button.h b/ash/shelf/shelf_button.h
index fd1963b..e2d56d8 100644
--- a/ash/shelf/shelf_button.h
+++ b/ash/shelf/shelf_button.h
@@ -23,7 +23,6 @@
   void OnMouseReleased(const ui::MouseEvent& event) override;
   void OnMouseCaptureLost() override;
   bool OnMouseDragged(const ui::MouseEvent& event) override;
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
   bool GetTooltipText(const gfx::Point& p,
                       base::string16* tooltip) const override;
 
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc
index a4366cd..1e252f3 100644
--- a/ash/wallpaper/wallpaper_controller.cc
+++ b/ash/wallpaper/wallpaper_controller.cc
@@ -103,12 +103,6 @@
   return *dir_chrome_os_custom_wallpapers;
 }
 
-// The file path of the device policy wallpaper (if any).
-base::FilePath& GlobalDevicePolicyWallpaperFile() {
-  static base::NoDestructor<base::FilePath> device_policy_wallpaper_file;
-  return *device_policy_wallpaper_file;
-}
-
 void SetGlobalUserDataDir(const base::FilePath& path) {
   base::FilePath& global_path = GlobalUserDataDir();
   global_path = path;
@@ -124,11 +118,6 @@
   global_path = path;
 }
 
-void SetGlobalDevicePolicyWallpaperFile(const base::FilePath& path) {
-  base::FilePath& global_path = GlobalDevicePolicyWallpaperFile();
-  global_path = path;
-}
-
 // Returns the appropriate wallpaper resolution for all root windows.
 WallpaperController::WallpaperResolution GetAppropriateResolution() {
   gfx::Size size = WallpaperController::GetMaxDisplaySizeInNative();
@@ -875,15 +864,13 @@
     const base::FilePath& user_data_path,
     const base::FilePath& chromeos_wallpapers_path,
     const base::FilePath& chromeos_custom_wallpapers_path,
-    const base::FilePath& device_policy_wallpaper_path,
-    bool is_device_wallpaper_policy_enforced) {
+    const base::FilePath& device_policy_wallpaper_path) {
   DCHECK(!wallpaper_controller_client_.get());
   wallpaper_controller_client_ = std::move(client);
   SetGlobalUserDataDir(user_data_path);
   SetGlobalChromeOSWallpapersDir(chromeos_wallpapers_path);
   SetGlobalChromeOSCustomWallpapersDir(chromeos_custom_wallpapers_path);
-  SetGlobalDevicePolicyWallpaperFile(device_policy_wallpaper_path);
-  is_device_wallpaper_policy_enforced_ = is_device_wallpaper_policy_enforced;
+  SetDevicePolicyWallpaperPath(device_policy_wallpaper_path);
 }
 
 void WallpaperController::SetCustomWallpaper(
@@ -1034,13 +1021,15 @@
                   std::move(callback));
 }
 
-void WallpaperController::SetDeviceWallpaperPolicyEnforced(bool enforced) {
-  bool previous_enforced = is_device_wallpaper_policy_enforced_;
-  is_device_wallpaper_policy_enforced_ = enforced;
-
+void WallpaperController::SetDevicePolicyWallpaperPath(
+    const base::FilePath& device_policy_wallpaper_path) {
+  const bool was_device_policy_wallpaper_enforced =
+      !device_policy_wallpaper_path_.empty();
+  device_policy_wallpaper_path_ = device_policy_wallpaper_path;
   if (ShouldSetDevicePolicyWallpaper()) {
     SetDevicePolicyWallpaper();
-  } else if ((previous_enforced != enforced) && !enforced) {
+  } else if (was_device_policy_wallpaper_enforced &&
+             device_policy_wallpaper_path.empty()) {
     // If the device wallpaper policy is cleared, the wallpaper should revert to
     // the wallpaper of the current user with the large pod in the users list in
     // the login screen. If there is no such user, use the first user in the
@@ -1175,7 +1164,8 @@
 
   base::FilePath wallpaper_path;
   if (info.type == DEVICE) {
-    wallpaper_path = GlobalDevicePolicyWallpaperFile();
+    DCHECK(!device_policy_wallpaper_path_.empty());
+    wallpaper_path = device_policy_wallpaper_path_;
   } else {
     std::string sub_dir = GetCustomWallpaperSubdirForCurrentResolution();
     // Wallpaper is not resized when layout is
@@ -2027,16 +2017,12 @@
 bool WallpaperController::ShouldSetDevicePolicyWallpaper() const {
   // Only allow the device wallpaper if the policy is in effect for enterprise
   // managed devices.
-  if (!is_device_wallpaper_policy_enforced_)
+  if (device_policy_wallpaper_path_.empty())
     return false;
 
   // Only set the device wallpaper if we're at the login screen.
-  if (Shell::Get()->session_controller()->GetSessionState() !=
-      session_manager::SessionState::LOGIN_PRIMARY) {
-    return false;
-  }
-
-  return true;
+  return Shell::Get()->session_controller()->GetSessionState() ==
+         session_manager::SessionState::LOGIN_PRIMARY;
 }
 
 void WallpaperController::SetDevicePolicyWallpaper() {
@@ -2044,7 +2030,7 @@
   ReadAndDecodeWallpaper(
       base::BindRepeating(&WallpaperController::OnDevicePolicyWallpaperDecoded,
                           weak_factory_.GetWeakPtr()),
-      sequenced_task_runner_.get(), GlobalDevicePolicyWallpaperFile());
+      sequenced_task_runner_.get(), device_policy_wallpaper_path_);
 }
 
 void WallpaperController::OnDevicePolicyWallpaperDecoded(
@@ -2060,7 +2046,7 @@
     SetDefaultWallpaperImpl(EmptyAccountId(), user_manager::USER_TYPE_REGULAR,
                             /*show_wallpaper=*/true);
   } else {
-    WallpaperInfo info(GlobalDevicePolicyWallpaperFile().value(),
+    WallpaperInfo info(device_policy_wallpaper_path_.value(),
                        WALLPAPER_LAYOUT_CENTER_CROPPED, DEVICE,
                        base::Time::Now().LocalMidnight());
     ShowWallpaperImage(image, info, /*preview_mode=*/false);
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h
index ceb79e0..be67f35 100644
--- a/ash/wallpaper/wallpaper_controller.h
+++ b/ash/wallpaper/wallpaper_controller.h
@@ -218,8 +218,7 @@
             const base::FilePath& user_data_path,
             const base::FilePath& chromeos_wallpapers_path,
             const base::FilePath& chromeos_custom_wallpapers_path,
-            const base::FilePath& device_policy_wallpaper_path,
-            bool is_device_wallpaper_policy_enforced) override;
+            const base::FilePath& device_policy_wallpaper_path) override;
   void SetCustomWallpaper(mojom::WallpaperUserInfoPtr user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& file_name,
@@ -248,7 +247,8 @@
   void SetPolicyWallpaper(mojom::WallpaperUserInfoPtr user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& data) override;
-  void SetDeviceWallpaperPolicyEnforced(bool enforced) override;
+  void SetDevicePolicyWallpaperPath(
+      const base::FilePath& device_policy_wallpaper_path) override;
   void SetThirdPartyWallpaper(mojom::WallpaperUserInfoPtr user_info,
                               const std::string& wallpaper_files_id,
                               const std::string& file_name,
@@ -597,8 +597,7 @@
   // The wallpaper animation duration. An empty value disables the animation.
   base::TimeDelta animation_duration_;
 
-  // Whether the device wallpaper policy is enforced on this device.
-  bool is_device_wallpaper_policy_enforced_ = false;
+  base::FilePath device_policy_wallpaper_path_;
 
   // Whether the current wallpaper (if any) is the first wallpaper since the
   // controller initialization. Empty wallpapers for testing don't count.
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index 42225d1..3b7c95a 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -1916,7 +1916,8 @@
 
   // Verify the device policy wallpaper is shown on login screen.
   SetSessionState(SessionState::LOGIN_PRIMARY);
-  controller_->SetDeviceWallpaperPolicyEnforced(true);
+  controller_->SetDevicePolicyWallpaperPath(
+      base::FilePath(kDefaultSmallWallpaperName));
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_TRUE(IsDevicePolicyWallpaper());
diff --git a/base/allocator/partition_allocator/page_allocator_unittest.cc b/base/allocator/partition_allocator/page_allocator_unittest.cc
index fdc6a5e..3f162fd 100644
--- a/base/allocator/partition_allocator/page_allocator_unittest.cc
+++ b/base/allocator/partition_allocator/page_allocator_unittest.cc
@@ -182,7 +182,7 @@
                             PageTag::kChromium, true);
   EXPECT_TRUE(buffer);
 
-  FAULT_TEST_BEGIN();
+  FAULT_TEST_BEGIN()
 
   // Reading from buffer should fault.
   int* buffer0 = reinterpret_cast<int*>(buffer);
@@ -190,7 +190,7 @@
   EXPECT_EQ(buffer0_contents, *buffer0);
   EXPECT_TRUE(false);
 
-  FAULT_TEST_END();
+  FAULT_TEST_END()
 
   FreePages(buffer, kPageAllocationGranularity);
 }
@@ -204,13 +204,13 @@
   // Reading from buffer should succeed.
   int buffer0_contents = *buffer0;
 
-  FAULT_TEST_BEGIN();
+  FAULT_TEST_BEGIN()
 
   // Writing to buffer should fault.
   *buffer0 = ~buffer0_contents;
   EXPECT_TRUE(false);
 
-  FAULT_TEST_END();
+  FAULT_TEST_END()
 
   // Make sure no write occurred.
   EXPECT_EQ(buffer0_contents, *buffer0);
diff --git a/base/android/java/src/org/chromium/base/task/TaskTraits.java b/base/android/java/src/org/chromium/base/task/TaskTraits.java
index ae53b3d..6d79592 100644
--- a/base/android/java/src/org/chromium/base/task/TaskTraits.java
+++ b/base/android/java/src/org/chromium/base/task/TaskTraits.java
@@ -22,12 +22,30 @@
     // Keep in sync with base::TaskTraitsExtensionStorage::kStorageSize
     public static final int EXTENSION_STORAGE_SIZE = 8;
 
+    // A convenience variable explicitly specifying the default priority
+    public static final TaskTraits USER_VISIBLE =
+            new TaskTraits().taskPriority(TaskPriority.USER_VISIBLE);
+
     public TaskTraits() {}
 
-    public TaskTraits setTaskPriority(int taskPriority) {
-        mPrioritySetExplicitly = true;
-        mPriority = taskPriority;
-        return this;
+    private TaskTraits(TaskTraits other) {
+        mPrioritySetExplicitly = other.mPrioritySetExplicitly;
+        mPriority = other.mPriority;
+        mMayBlock = other.mMayBlock;
+        mExtensionId = other.mExtensionId;
+        mExtensionData = other.mExtensionData;
+    }
+
+    public TaskTraits(byte extensionId, byte[] extensionData) {
+        mExtensionId = extensionId;
+        mExtensionData = extensionData;
+    }
+
+    public TaskTraits taskPriority(int taskPriority) {
+        TaskTraits taskTraits = new TaskTraits(this);
+        taskTraits.mPrioritySetExplicitly = true;
+        taskTraits.mPriority = taskPriority;
+        return taskTraits;
     }
 
     /**
@@ -36,9 +54,10 @@
      * socket, rename or delete a file, enumerate files in a directory, etc. This trait isn't
      * required for the mere use of locks.
      */
-    public TaskTraits setMayBlock(boolean mayBlock) {
-        mMayBlock = mayBlock;
-        return this;
+    public TaskTraits mayBlock(boolean mayBlock) {
+        TaskTraits taskTraits = new TaskTraits(this);
+        taskTraits.mMayBlock = mayBlock;
+        return taskTraits;
     }
 
     // For convenience of the JNI code, we use primitive types only.
@@ -49,14 +68,6 @@
     byte mExtensionId = INVALID_EXTENSION_ID;
     byte mExtensionData[];
 
-    protected void setExtensionId(byte extensionId) {
-        mExtensionId = extensionId;
-    }
-
-    protected void setExtensionData(byte[] extensionData) {
-        mExtensionData = extensionData;
-    }
-
     /**
      * @return true if this task is using some TaskTraits extension.
      */
diff --git a/base/cancelable_callback_unittest.cc b/base/cancelable_callback_unittest.cc
index 0c254a8..da1a957c 100644
--- a/base/cancelable_callback_unittest.cc
+++ b/base/cancelable_callback_unittest.cc
@@ -23,7 +23,6 @@
  private:
   friend class RefCountedThreadSafe<TestRefCounted>;
   ~TestRefCounted() = default;
-  ;
 };
 
 void Increment(int* count) { (*count)++; }
diff --git a/base/debug/activity_tracker_unittest.cc b/base/debug/activity_tracker_unittest.cc
index e2b61a9..94bb7b6 100644
--- a/base/debug/activity_tracker_unittest.cc
+++ b/base/debug/activity_tracker_unittest.cc
@@ -275,7 +275,7 @@
 
   bool IsRunning() { return is_running_.load(std::memory_order_relaxed); }
 
-  bool WasDataChanged() { return data_changed_; };
+  bool WasDataChanged() { return data_changed_; }
 
  private:
   Lock* lock_;
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index b451d08..bd7211c0 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -465,7 +465,7 @@
   // Should never reach this point.
   const uintptr_t failed = 0;
   HANDLE_EINTR(write(g_child_crash_pipe, &failed, sizeof(uintptr_t)));
-};
+}
 
 void SpawnChildAndCrash(int death_location, uintptr_t* child_crash_addr) {
   int pipefd[2];
diff --git a/base/mac/bind_objc_block_unittest_arc.mm b/base/mac/bind_objc_block_unittest_arc.mm
index 1fd25d7c..10e4af7 100644
--- a/base/mac/bind_objc_block_unittest_arc.mm
+++ b/base/mac/bind_objc_block_unittest_arc.mm
@@ -111,7 +111,7 @@
           invoked_block = *v;
         },
         std::make_unique<BOOL>(YES));
-  };
+  }
   std::move(c).Run();
   EXPECT_TRUE(invoked_block);
 }
diff --git a/base/mac/foundation_util.h b/base/mac/foundation_util.h
index 2e417f0..8aae308 100644
--- a/base/mac/foundation_util.h
+++ b/base/mac/foundation_util.h
@@ -285,12 +285,12 @@
 template<typename T>
 T CFCastStrict(const CFTypeRef& cf_val);
 
-#define CF_CAST_DECL(TypeCF) \
-template<> BASE_EXPORT TypeCF##Ref \
-CFCast<TypeCF##Ref>(const CFTypeRef& cf_val);\
-\
-template<> BASE_EXPORT TypeCF##Ref \
-CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val);
+#define CF_CAST_DECL(TypeCF)                                            \
+  template <>                                                           \
+  BASE_EXPORT TypeCF##Ref CFCast<TypeCF##Ref>(const CFTypeRef& cf_val); \
+                                                                        \
+  template <>                                                           \
+  BASE_EXPORT TypeCF##Ref CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val)
 
 CF_CAST_DECL(CFArray);
 CF_CAST_DECL(CFBag);
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
index b14e40b..3de70a26 100644
--- a/base/mac/foundation_util.mm
+++ b/base/mac/foundation_util.mm
@@ -196,28 +196,28 @@
   return #TypeCF; \
 }
 
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFArray);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFBag);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFBoolean);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFData);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFDate);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFDictionary);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFNull);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFNumber);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFSet);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFString);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFURL);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CFUUID);
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFArray)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFBag)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFBoolean)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFData)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFDate)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFDictionary)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFNull)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFNumber)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFSet)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFString)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFURL)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CFUUID)
 
-TYPE_NAME_FOR_CF_TYPE_DEFN(CGColor);
+TYPE_NAME_FOR_CF_TYPE_DEFN(CGColor)
 
-TYPE_NAME_FOR_CF_TYPE_DEFN(CTFont);
-TYPE_NAME_FOR_CF_TYPE_DEFN(CTRun);
+TYPE_NAME_FOR_CF_TYPE_DEFN(CTFont)
+TYPE_NAME_FOR_CF_TYPE_DEFN(CTRun)
 
 #if !defined(OS_IOS)
-TYPE_NAME_FOR_CF_TYPE_DEFN(SecCertificate);
-TYPE_NAME_FOR_CF_TYPE_DEFN(SecKey);
-TYPE_NAME_FOR_CF_TYPE_DEFN(SecPolicy);
+TYPE_NAME_FOR_CF_TYPE_DEFN(SecCertificate)
+TYPE_NAME_FOR_CF_TYPE_DEFN(SecKey)
+TYPE_NAME_FOR_CF_TYPE_DEFN(SecPolicy)
 #endif
 
 #undef TYPE_NAME_FOR_CF_TYPE_DEFN
@@ -297,26 +297,26 @@
   return cf_val; \
 }
 
-CF_TO_NS_MUTABLE_CAST_DEFN(Array);
-CF_TO_NS_MUTABLE_CAST_DEFN(AttributedString);
-CF_TO_NS_CAST_DEFN(CFCalendar, NSCalendar);
-CF_TO_NS_MUTABLE_CAST_DEFN(CharacterSet);
-CF_TO_NS_MUTABLE_CAST_DEFN(Data);
-CF_TO_NS_CAST_DEFN(CFDate, NSDate);
-CF_TO_NS_MUTABLE_CAST_DEFN(Dictionary);
-CF_TO_NS_CAST_DEFN(CFError, NSError);
-CF_TO_NS_CAST_DEFN(CFLocale, NSLocale);
-CF_TO_NS_CAST_DEFN(CFNumber, NSNumber);
-CF_TO_NS_CAST_DEFN(CFRunLoopTimer, NSTimer);
-CF_TO_NS_CAST_DEFN(CFTimeZone, NSTimeZone);
-CF_TO_NS_MUTABLE_CAST_DEFN(Set);
-CF_TO_NS_CAST_DEFN(CFReadStream, NSInputStream);
-CF_TO_NS_CAST_DEFN(CFWriteStream, NSOutputStream);
-CF_TO_NS_MUTABLE_CAST_DEFN(String);
-CF_TO_NS_CAST_DEFN(CFURL, NSURL);
+CF_TO_NS_MUTABLE_CAST_DEFN(Array)
+CF_TO_NS_MUTABLE_CAST_DEFN(AttributedString)
+CF_TO_NS_CAST_DEFN(CFCalendar, NSCalendar)
+CF_TO_NS_MUTABLE_CAST_DEFN(CharacterSet)
+CF_TO_NS_MUTABLE_CAST_DEFN(Data)
+CF_TO_NS_CAST_DEFN(CFDate, NSDate)
+CF_TO_NS_MUTABLE_CAST_DEFN(Dictionary)
+CF_TO_NS_CAST_DEFN(CFError, NSError)
+CF_TO_NS_CAST_DEFN(CFLocale, NSLocale)
+CF_TO_NS_CAST_DEFN(CFNumber, NSNumber)
+CF_TO_NS_CAST_DEFN(CFRunLoopTimer, NSTimer)
+CF_TO_NS_CAST_DEFN(CFTimeZone, NSTimeZone)
+CF_TO_NS_MUTABLE_CAST_DEFN(Set)
+CF_TO_NS_CAST_DEFN(CFReadStream, NSInputStream)
+CF_TO_NS_CAST_DEFN(CFWriteStream, NSOutputStream)
+CF_TO_NS_MUTABLE_CAST_DEFN(String)
+CF_TO_NS_CAST_DEFN(CFURL, NSURL)
 
 #if defined(OS_IOS)
-CF_TO_NS_CAST_DEFN(CTFont, UIFont);
+CF_TO_NS_CAST_DEFN(CTFont, UIFont)
 #else
 // The NSFont/CTFont toll-free bridging is broken when it comes to type
 // checking, so do some special-casing.
@@ -362,26 +362,26 @@
   return rv; \
 }
 
-CF_CAST_DEFN(CFArray);
-CF_CAST_DEFN(CFBag);
-CF_CAST_DEFN(CFBoolean);
-CF_CAST_DEFN(CFData);
-CF_CAST_DEFN(CFDate);
-CF_CAST_DEFN(CFDictionary);
-CF_CAST_DEFN(CFNull);
-CF_CAST_DEFN(CFNumber);
-CF_CAST_DEFN(CFSet);
-CF_CAST_DEFN(CFString);
-CF_CAST_DEFN(CFURL);
-CF_CAST_DEFN(CFUUID);
+CF_CAST_DEFN(CFArray)
+CF_CAST_DEFN(CFBag)
+CF_CAST_DEFN(CFBoolean)
+CF_CAST_DEFN(CFData)
+CF_CAST_DEFN(CFDate)
+CF_CAST_DEFN(CFDictionary)
+CF_CAST_DEFN(CFNull)
+CF_CAST_DEFN(CFNumber)
+CF_CAST_DEFN(CFSet)
+CF_CAST_DEFN(CFString)
+CF_CAST_DEFN(CFURL)
+CF_CAST_DEFN(CFUUID)
 
-CF_CAST_DEFN(CGColor);
+CF_CAST_DEFN(CGColor)
 
-CF_CAST_DEFN(CTFontDescriptor);
-CF_CAST_DEFN(CTRun);
+CF_CAST_DEFN(CTFontDescriptor)
+CF_CAST_DEFN(CTRun)
 
 #if defined(OS_IOS)
-CF_CAST_DEFN(CTFont);
+CF_CAST_DEFN(CTFont)
 #else
 // The NSFont/CTFont toll-free bridging is broken when it comes to type
 // checking, so do some special-casing.
@@ -414,11 +414,11 @@
 #endif
 
 #if !defined(OS_IOS)
-CF_CAST_DEFN(SecACL);
-CF_CAST_DEFN(SecCertificate);
-CF_CAST_DEFN(SecKey);
-CF_CAST_DEFN(SecPolicy);
-CF_CAST_DEFN(SecTrustedApplication);
+CF_CAST_DEFN(SecACL)
+CF_CAST_DEFN(SecCertificate)
+CF_CAST_DEFN(SecKey)
+CF_CAST_DEFN(SecPolicy)
+CF_CAST_DEFN(SecTrustedApplication)
 #endif
 
 #undef CF_CAST_DEFN
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
index 2f96a6b..9616911 100644
--- a/base/metrics/persistent_histogram_allocator.cc
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -925,7 +925,7 @@
 
   subtle::Release_Store(&g_histogram_allocator, 0);
   return WrapUnique(histogram_allocator);
-};
+}
 
 void GlobalHistogramAllocator::SetPersistentLocation(const FilePath& location) {
   persistent_location_ = location;
diff --git a/base/metrics/persistent_histogram_allocator_unittest.cc b/base/metrics/persistent_histogram_allocator_unittest.cc
index 7e07386d..aee6ceb7 100644
--- a/base/metrics/persistent_histogram_allocator_unittest.cc
+++ b/base/metrics/persistent_histogram_allocator_unittest.cc
@@ -274,7 +274,7 @@
     HistogramBase* found =
         StatisticsRecorder::FindHistogram(recovered->histogram_name());
     EXPECT_NE(recovered.get(), found);
-  };
+  }
   EXPECT_EQ(starting_sr_count + 2, StatisticsRecorder::GetHistogramCount());
 
   // Check the merged histograms for accuracy.
@@ -313,7 +313,7 @@
     if (!recovered)
       break;
     recovery2.MergeHistogramDeltaToStatisticsRecorder(recovered.get());
-  };
+  }
   EXPECT_EQ(starting_sr_count + 2, StatisticsRecorder::GetHistogramCount());
 
   // And verify.
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index cab401a..865675c1 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -528,28 +528,20 @@
 // This hash function is copied from base/strings/string16.h. We don't use the
 // ones already defined for string and string16 directly because it would
 // require the string constructors to be called, which we don't want.
-#define HASH_STRING_PIECE(StringPieceType, string_piece)         \
-  std::size_t result = 0;                                        \
-  for (StringPieceType::const_iterator i = string_piece.begin(); \
-       i != string_piece.end(); ++i)                             \
-    result = (result * 131) + *i;                                \
-  return result
 
-struct StringPieceHash {
-  std::size_t operator()(const StringPiece& sp) const {
-    HASH_STRING_PIECE(StringPiece, sp);
+template <typename StringPieceType>
+struct StringPieceHashImpl {
+  std::size_t operator()(StringPieceType sp) const {
+    std::size_t result = 0;
+    for (auto c : sp)
+      result = (result * 131) + c;
+    return result;
   }
 };
-struct StringPiece16Hash {
-  std::size_t operator()(const StringPiece16& sp16) const {
-    HASH_STRING_PIECE(StringPiece16, sp16);
-  }
-};
-struct WStringPieceHash {
-  std::size_t operator()(const WStringPiece& wsp) const {
-    HASH_STRING_PIECE(WStringPiece, wsp);
-  }
-};
+
+using StringPieceHash = StringPieceHashImpl<StringPiece>;
+using StringPiece16Hash = StringPieceHashImpl<StringPiece16>;
+using WStringPieceHash = StringPieceHashImpl<WStringPiece>;
 
 }  // namespace base
 
diff --git a/base/strings/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc
index ab3b8cd..a952a31 100644
--- a/base/strings/string_piece_unittest.cc
+++ b/base/strings/string_piece_unittest.cc
@@ -66,63 +66,63 @@
                           op 0));                                          \
   }
 
-  CMP_Y(==, "",   "");
-  CMP_Y(==, "a",  "a");
-  CMP_Y(==, "aa", "aa");
-  CMP_N(==, "a",  "");
-  CMP_N(==, "",   "a");
-  CMP_N(==, "a",  "b");
-  CMP_N(==, "a",  "aa");
-  CMP_N(==, "aa", "a");
+  CMP_Y(==, "", "")
+  CMP_Y(==, "a", "a")
+  CMP_Y(==, "aa", "aa")
+  CMP_N(==, "a", "")
+  CMP_N(==, "", "a")
+  CMP_N(==, "a", "b")
+  CMP_N(==, "a", "aa")
+  CMP_N(==, "aa", "a")
 
-  CMP_N(!=, "",   "");
-  CMP_N(!=, "a",  "a");
-  CMP_N(!=, "aa", "aa");
-  CMP_Y(!=, "a",  "");
-  CMP_Y(!=, "",   "a");
-  CMP_Y(!=, "a",  "b");
-  CMP_Y(!=, "a",  "aa");
-  CMP_Y(!=, "aa", "a");
+  CMP_N(!=, "", "")
+  CMP_N(!=, "a", "a")
+  CMP_N(!=, "aa", "aa")
+  CMP_Y(!=, "a", "")
+  CMP_Y(!=, "", "a")
+  CMP_Y(!=, "a", "b")
+  CMP_Y(!=, "a", "aa")
+  CMP_Y(!=, "aa", "a")
 
-  CMP_Y(<, "a",  "b");
-  CMP_Y(<, "a",  "aa");
-  CMP_Y(<, "aa", "b");
-  CMP_Y(<, "aa", "bb");
-  CMP_N(<, "a",  "a");
-  CMP_N(<, "b",  "a");
-  CMP_N(<, "aa", "a");
-  CMP_N(<, "b",  "aa");
-  CMP_N(<, "bb", "aa");
+  CMP_Y(<, "a", "b")
+  CMP_Y(<, "a", "aa")
+  CMP_Y(<, "aa", "b")
+  CMP_Y(<, "aa", "bb")
+  CMP_N(<, "a", "a")
+  CMP_N(<, "b", "a")
+  CMP_N(<, "aa", "a")
+  CMP_N(<, "b", "aa")
+  CMP_N(<, "bb", "aa")
 
-  CMP_Y(<=, "a",  "a");
-  CMP_Y(<=, "a",  "b");
-  CMP_Y(<=, "a",  "aa");
-  CMP_Y(<=, "aa", "b");
-  CMP_Y(<=, "aa", "bb");
-  CMP_N(<=, "b",  "a");
-  CMP_N(<=, "aa", "a");
-  CMP_N(<=, "b",  "aa");
-  CMP_N(<=, "bb", "aa");
+  CMP_Y(<=, "a", "a")
+  CMP_Y(<=, "a", "b")
+  CMP_Y(<=, "a", "aa")
+  CMP_Y(<=, "aa", "b")
+  CMP_Y(<=, "aa", "bb")
+  CMP_N(<=, "b", "a")
+  CMP_N(<=, "aa", "a")
+  CMP_N(<=, "b", "aa")
+  CMP_N(<=, "bb", "aa")
 
-  CMP_N(>=, "a",  "b");
-  CMP_N(>=, "a",  "aa");
-  CMP_N(>=, "aa", "b");
-  CMP_N(>=, "aa", "bb");
-  CMP_Y(>=, "a",  "a");
-  CMP_Y(>=, "b",  "a");
-  CMP_Y(>=, "aa", "a");
-  CMP_Y(>=, "b",  "aa");
-  CMP_Y(>=, "bb", "aa");
+  CMP_N(>=, "a", "b")
+  CMP_N(>=, "a", "aa")
+  CMP_N(>=, "aa", "b")
+  CMP_N(>=, "aa", "bb")
+  CMP_Y(>=, "a", "a")
+  CMP_Y(>=, "b", "a")
+  CMP_Y(>=, "aa", "a")
+  CMP_Y(>=, "b", "aa")
+  CMP_Y(>=, "bb", "aa")
 
-  CMP_N(>, "a",  "a");
-  CMP_N(>, "a",  "b");
-  CMP_N(>, "a",  "aa");
-  CMP_N(>, "aa", "b");
-  CMP_N(>, "aa", "bb");
-  CMP_Y(>, "b",  "a");
-  CMP_Y(>, "aa", "a");
-  CMP_Y(>, "b",  "aa");
-  CMP_Y(>, "bb", "aa");
+  CMP_N(>, "a", "a")
+  CMP_N(>, "a", "b")
+  CMP_N(>, "a", "aa")
+  CMP_N(>, "aa", "b")
+  CMP_N(>, "aa", "bb")
+  CMP_Y(>, "b", "a")
+  CMP_Y(>, "aa", "a")
+  CMP_Y(>, "b", "aa")
+  CMP_Y(>, "bb", "aa")
 
   std::string x;
   for (int i = 0; i < 256; i++) {
diff --git a/base/sync_socket_unittest.cc b/base/sync_socket_unittest.cc
index fdcd9a1..0f80a1c 100644
--- a/base/sync_socket_unittest.cc
+++ b/base/sync_socket_unittest.cc
@@ -121,7 +121,7 @@
   SyncSocket socket_c(socket_a_.Release());
   SyncSocket socket_d(socket_b_.Release());
   SendReceivePeek(&socket_c, &socket_d);
-};
+}
 
 class CancelableSyncSocketTest : public testing::Test {
  public:
diff --git a/base/task/task_scheduler/scheduler_worker_unittest.cc b/base/task/task_scheduler/scheduler_worker_unittest.cc
index f6305dc..d4f30dc3 100644
--- a/base/task/task_scheduler/scheduler_worker_unittest.cc
+++ b/base/task/task_scheduler/scheduler_worker_unittest.cc
@@ -498,7 +498,7 @@
 class MockedControllableCleanupDelegate : public ControllableCleanupDelegate {
  public:
   MockedControllableCleanupDelegate(TaskTracker* task_tracker)
-      : ControllableCleanupDelegate(task_tracker){};
+      : ControllableCleanupDelegate(task_tracker) {}
   ~MockedControllableCleanupDelegate() override = default;
 
   // SchedulerWorker::Delegate:
diff --git a/base/task_runner_util_unittest.cc b/base/task_runner_util_unittest.cc
index 9c1ed1f..3ffc479e 100644
--- a/base/task_runner_util_unittest.cc
+++ b/base/task_runner_util_unittest.cc
@@ -53,7 +53,7 @@
   void operator()(Foo* foo) const {
     ++g_foo_free_count;
     delete foo;
-  };
+  }
 };
 
 std::unique_ptr<Foo, FooDeleter> CreateScopedFoo() {
diff --git a/base/threading/sequence_bound.h b/base/threading/sequence_bound.h
index a4ba4123b..c5fb9d0 100644
--- a/base/threading/sequence_bound.h
+++ b/base/threading/sequence_bound.h
@@ -93,7 +93,7 @@
                               static_cast<Base*>(nullptr)))> : std::false_type {
 };
 
-};  // namespace internal
+}  // namespace internal
 
 template <typename T>
 class SequenceBound {
diff --git a/base/trace_event/memory_dump_manager_test_utils.h b/base/trace_event/memory_dump_manager_test_utils.h
index 413017f..c0062d8a 100644
--- a/base/trace_event/memory_dump_manager_test_utils.h
+++ b/base/trace_event/memory_dump_manager_test_utils.h
@@ -19,7 +19,7 @@
                                       level_of_detail};
   MemoryDumpManager::GetInstance()->CreateProcessDump(
       local_args, ProcessMemoryDumpCallback());
-};
+}
 
 // Short circuits the RequestGlobalDumpFunction() to CreateProcessDump(),
 // effectively allowing to use both in unittests with the same behavior.
diff --git a/base/trace_event/trace_arguments_unittest.cc b/base/trace_event/trace_arguments_unittest.cc
index a550cd6..787ff55 100644
--- a/base/trace_event/trace_arguments_unittest.cc
+++ b/base/trace_event/trace_arguments_unittest.cc
@@ -249,7 +249,7 @@
   EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args.types()[1]);
   EXPECT_EQ(kValues[0], args.values()[0].as_uint);
   EXPECT_EQ(kText, args.values()[1].as_string);
-};
+}
 
 TEST(TraceArguments, ConstructorLegacyWithConvertables) {
   const char* const kNames[3] = {"legacy_arg1", "legacy_arg2", "legacy_arg3"};
diff --git a/base/trace_event/trace_config_memory_test_util.h b/base/trace_event/trace_config_memory_test_util.h
index cc49a65c..107c5f4 100644
--- a/base/trace_event/trace_config_memory_test_util.h
+++ b/base/trace_event/trace_config_memory_test_util.h
@@ -44,7 +44,6 @@
         "\"record_mode\":\"record-until-full\""
         "}",
         MemoryDumpManager::kTraceCategory, light_period, heavy_period);
-    ;
   }
 
   static std::string GetTraceConfig_PeriodicTriggers(int light_period,
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py
index a42dadee..18e3faa 100755
--- a/build/android/gyp/proguard.py
+++ b/build/android/gyp/proguard.py
@@ -4,6 +4,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import cStringIO
 import optparse
 import os
 import shutil
@@ -189,16 +190,23 @@
       # from failing.
       build_utils.Touch(tmp_mapping_path)
 
+      f = cStringIO.StringIO()
+      proguard_util.WriteFlagsFile(
+          options.proguard_configs, f, exclude_generated=True)
+      merged_configs = f.getvalue()
+      f.close()
+      print_stdout = '-whyareyoukeeping' in merged_configs
+
       if options.output_path.endswith('.dex'):
         with build_utils.TempDir() as tmp_dex_dir:
           cmd = _CreateR8Command(options, tmp_mapping_path, tmp_dex_dir,
                                  tmp_proguard_config_path, libraries)
-          build_utils.CheckOutput(cmd)
+          build_utils.CheckOutput(cmd, print_stdout=print_stdout)
           _MoveTempDexFile(tmp_dex_dir, options.output_path)
       else:
         cmd = _CreateR8Command(options, tmp_mapping_path, options.output_path,
                                tmp_proguard_config_path, libraries)
-        build_utils.CheckOutput(cmd)
+        build_utils.CheckOutput(cmd, print_stdout=print_stdout)
 
       # Copy output files to correct locations.
       with build_utils.AtomicOutput(options.mapping_output) as mapping:
@@ -207,9 +215,8 @@
         with open(tmp_mapping_path) as tmp:
           mapping.writelines(l for l in tmp if not l.startswith("#"))
 
-    with build_utils.AtomicOutput(options.output_config) as merged_config:
-      proguard_util.WriteFlagsFile(
-          options.proguard_configs, merged_config, exclude_generated=True)
+    with build_utils.AtomicOutput(options.output_config) as f:
+      f.write(merged_configs)
 
     if options.expected_configs_file:
       _VerifyExpectedConfigs(options.expected_configs_file,
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
index 9e49542..6b92f3e 100644
--- a/build/config/sanitizers/BUILD.gn
+++ b/build/config/sanitizers/BUILD.gn
@@ -2,12 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build_overrides/build.gni")
 import("//build/config/chrome_build.gni")
 import("//build/config/chromecast_build.gni")
 import("//build/config/clang/clang.gni")
 import("//build/config/sanitizers/sanitizers.gni")
 import("//build/toolchain/toolchain.gni")
+import("//build_overrides/build.gni")
 
 if (is_ios) {
   import("//build/config/ios/ios_sdk.gni")
@@ -201,6 +201,11 @@
     if (use_sanitizer_coverage) {
       if (use_libfuzzer) {
         ldflags += [ "-fsanitize=fuzzer-no-link" ]
+        if (is_mac) {
+          # TODO(crbug.com/926588): on macOS, dead code stripping does not work
+          # well with `pc-table` instrumentation enabled by `fuzzer-no-link`.
+          ldflags += [ "-fno-sanitize-coverage=pc-table" ]
+        }
       } else {
         ldflags += [ "-fsanitize-coverage=$sanitizer_coverage_flags" ]
       }
@@ -399,6 +404,11 @@
 
     if (use_libfuzzer) {
       cflags += [ "-fsanitize=fuzzer-no-link" ]
+      if (is_mac) {
+        # TODO(crbug.com/926588): on macOS, dead code stripping does not work
+        # well with `pc-table` instrumentation enabled by `fuzzer-no-link`.
+        cflags += [ "-fno-sanitize-coverage=pc-table" ]
+      }
     } else {
       cflags += [
         "-fsanitize-coverage=$sanitizer_coverage_flags",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 998fb9d..2c96613 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-bd18abd7baddaa69cdf9a888581fcd3fa815e38c
\ No newline at end of file
+f8f8ce7b42e9377b18a457804a6928665004e5b5
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 8cc3500..be4b1c9 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-a6442bbdbb932d9df04001e77c8e4ddea51bd0af
\ No newline at end of file
+66374af5ae391a2a5152a90e097e991acf9c8d68
\ No newline at end of file
diff --git a/build/toolchain/fuchsia/BUILD.gn b/build/toolchain/fuchsia/BUILD.gn
index d160a83..06ac5e5 100644
--- a/build/toolchain/fuchsia/BUILD.gn
+++ b/build/toolchain/fuchsia/BUILD.gn
@@ -15,7 +15,6 @@
 
     # We want to build and strip binaries, but retain the unstripped binaries
     # in runtime_deps to make them available for isolates.
-    # TODO(https://crbug.com/877080): Switch to llvm-strip.
     if (host_os == "linux") {
       strip = rebase_path("//buildtools/third_party/eu-strip/bin/eu-strip",
                           root_build_dir)
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_onboarding.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_onboarding.xml
index 9c3c6688..955fc64 100644
--- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_onboarding.xml
+++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_onboarding.xml
@@ -2,116 +2,132 @@
 <!-- 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. -->
+
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/assistant_onboarding"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:gravity="center_horizontal"
-    android:orientation="vertical"
-    android:paddingTop="20dp"
-    android:paddingBottom="20dp"
+    android:orientation="vertical">
+
+    <org.chromium.chrome.browser.widget.FadingEdgeScrollView
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:layout_width="match_parent">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:orientation="vertical"
+            android:paddingTop="20dp"
+            android:paddingBottom="20dp"
+            android:paddingStart="24dp"
+            android:paddingEnd="24dp">
+
+            <!-- Image background -->
+            <ImageView
+                tools:ignore="contentDescription"
+                android:layout_width="250dp"
+                android:layout_height="141dp"
+                android:scaleType="centerCrop"
+                android:src="@drawable/onboarding_background"
+                android:paddingTop="10dp"
+                android:paddingBottom="15dp"/>
+
+            <!-- Title (e.g., 'Fast Checkout')-->
+            <TextView
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:textAppearance="@style/TextAppearance.AssistantBlackTitle"
+                android:gravity="center_horizontal"
+                android:text="@string/autofill_assistant_onboarding_title" />
+
+            <!-- Subtitle (e.g., 'Google Assistant saves you time...')-->
+            <Space android:layout_width="0dp" android:layout_height="16dp"/>
+            <TextView
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:textAppearance="@style/TextAppearance.AssistantBlackBody"
+                android:paddingStart="12dp"
+                android:paddingEnd="12dp"
+                android:gravity="center_horizontal"
+                android:text="@string/autofill_assistant_init_message" />
+
+            <!-- Separator -->
+            <Space android:layout_width="0dp" android:layout_height="24dp"/>
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center_horizontal"
+                android:orientation="horizontal"
+                android:weightSum="1.0">
+                <View style="@style/HorizontalDivider"
+                    android:layout_width="0dp"
+                    android:layout_height="2dp"
+                    android:layout_weight="0.33"/>
+            </LinearLayout>
+            <Space android:layout_width="0dp" android:layout_height="24dp"/>
+
+            <!-- Terms and Conditions message and link -->
+            <LinearLayout
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:paddingStart="12dp"
+                android:paddingEnd="12dp"
+                android:paddingBottom="9dp">
+
+                <TextView
+                    android:id="@+id/google_terms_message"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_margin="0dp"
+                    android:layout_gravity="center"
+                    android:textAppearance="@style/TextAppearance.AssistantBlackCaption"
+                    android:text="@string/autofill_assistant_google_terms_description" />
+            </LinearLayout>
+        </LinearLayout>
+    </org.chromium.chrome.browser.widget.FadingEdgeScrollView>
+
+    <!-- Layout for the buttons -->
+    <Space android:layout_width="0dp" android:layout_height="24dp"/>
+    <LinearLayout
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="bottom|center"
+    android:orientation="horizontal"
     android:paddingStart="24dp"
     android:paddingEnd="24dp">
 
-    <!-- Image background -->
-    <ImageView
-        tools:ignore="contentDescription"
-        android:layout_width="250dp"
-        android:layout_height="141dp"
-        android:scaleType="centerCrop"
-        android:src="@drawable/onboarding_background"
-        android:paddingTop="10dp"
-        android:paddingBottom="15dp"/>
-
-    <!-- Title (e.g., 'Fast Checkout')-->
-    <TextView
-        android:layout_height="wrap_content"
+    <!-- 'No' button -->
+    <org.chromium.ui.widget.ButtonCompat
+        android:id="@+id/button_init_not_ok"
         android:layout_width="wrap_content"
-        android:textAppearance="@style/TextAppearance.AssistantBlackTitle"
-        android:gravity="center_horizontal"
-        android:text="@string/autofill_assistant_onboarding_title" />
-
-    <!-- Subtitle (e.g., 'Google Assistant saves you time...')-->
-    <Space android:layout_width="0dp" android:layout_height="16dp"/>
-    <TextView
         android:layout_height="wrap_content"
+        android:minHeight="36dp"
+        android:minWidth="120dp"
+        android:singleLine="true"
+        android:gravity="center"
+        android:text="@string/cancel"
+        style="@style/TextButton" />
+
+    <Space
+        android:layout_weight="1"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"/>
+
+    <!-- 'Yes' button -->
+    <org.chromium.ui.widget.ButtonCompat
+        android:id="@+id/button_init_ok"
         android:layout_width="wrap_content"
-        android:textAppearance="@style/TextAppearance.AssistantBlackBody"
-        android:paddingStart="12dp"
-        android:paddingEnd="12dp"
-        android:gravity="center_horizontal"
-        android:text="@string/autofill_assistant_init_message" />
-
-    <!-- Separator -->
-    <Space android:layout_width="0dp" android:layout_height="24dp"/>
-    <LinearLayout
-        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:gravity="center_horizontal"
-        android:orientation="horizontal"
-        android:weightSum="1.0">
-        <View style="@style/HorizontalDivider"
-            android:layout_width="0dp"
-            android:layout_height="2dp"
-            android:layout_weight="0.33"/>
+        android:minHeight="36dp"
+        android:minWidth="120dp"
+        android:singleLine="true"
+        android:gravity="center"
+        android:text="@string/init_ok"
+        style="FilledButton" />
     </LinearLayout>
     <Space android:layout_width="0dp" android:layout_height="24dp"/>
-
-    <!-- Terms and Conditions message and link -->
-    <LinearLayout
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:paddingStart="12dp"
-        android:paddingEnd="12dp"
-        android:paddingBottom="9dp">
-
-        <TextView
-            android:id="@+id/google_terms_message"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_margin="0dp"
-            android:layout_gravity="center"
-            android:textAppearance="@style/TextAppearance.AssistantBlackCaption"
-            android:text="@string/autofill_assistant_google_terms_description" />
-    </LinearLayout>
-
-    <!-- Layout for the buttons -->
-    <Space android:layout_width="0dp" android:layout_height="32dp"/>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="bottom|center"
-        android:orientation="horizontal">
-
-        <!-- 'No' button -->
-        <org.chromium.ui.widget.ButtonCompat
-            android:id="@+id/button_init_not_ok"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:minHeight="36dp"
-            android:minWidth="120dp"
-            android:singleLine="true"
-            android:gravity="center"
-            android:text="@string/cancel"
-            style="@style/TextButton" />
-
-        <Space
-            android:layout_weight="1"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"/>
-
-        <!-- 'Yes' button -->
-        <org.chromium.ui.widget.ButtonCompat
-            android:id="@+id/button_init_ok"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:minHeight="36dp"
-            android:minWidth="120dp"
-            android:singleLine="true"
-            android:gravity="center"
-            android:text="@string/init_ok"
-            style="FilledButton" />
-    </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
index f403f23..bda68e3b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
@@ -15,17 +15,12 @@
 import org.chromium.chrome.browser.ResourceId;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.AccessoryAction;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData;
-import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryMetricsRecorder;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.ManualFillingCoordinator;
 import org.chromium.components.autofill.AutofillDelegate;
 import org.chromium.components.autofill.AutofillSuggestion;
-import org.chromium.components.autofill.PopupItemId;
 import org.chromium.ui.DropdownItem;
 import org.chromium.ui.base.WindowAndroid;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
 * JNI call glue for AutofillExternalDelagate C++ and Java objects.
 * This provides an alternative UI for Autofill suggestions, and replaces AutofillPopupBridge when
@@ -37,7 +32,7 @@
     private long mNativeAutofillKeyboardAccessory;
     private ManualFillingCoordinator mManualFillingCoordinator;
     private Context mContext;
-    private KeyboardAccessoryData.Provider<KeyboardAccessoryData.Action[]> mChipProvider =
+    private KeyboardAccessoryData.Provider<AutofillSuggestion[]> mChipProvider =
             new KeyboardAccessoryData.PropertyProvider<>(AccessoryAction.AUTOFILL_SUGGESTION);
 
     private AutofillKeyboardAccessoryBridge() {
@@ -56,7 +51,6 @@
 
     @Override
     public void suggestionSelected(int listIndex) {
-        KeyboardAccessoryMetricsRecorder.recordActionSelected(AccessoryAction.AUTOFILL_SUGGESTION);
         mManualFillingCoordinator.dismiss();
         if (mNativeAutofillKeyboardAccessory == 0) return;
         nativeSuggestionSelected(mNativeAutofillKeyboardAccessory, listIndex);
@@ -97,8 +91,8 @@
         if (mContext instanceof ChromeActivity) {
             mManualFillingCoordinator = ((ChromeActivity) mContext).getManualFillingController();
             if (mManualFillingCoordinator.getKeyboardAccessory() != null) {
-                mManualFillingCoordinator.getKeyboardAccessory().registerActionProvider(
-                        mChipProvider);
+                mManualFillingCoordinator.getKeyboardAccessory().registerAutofillProvider(
+                        mChipProvider, this);
             }
         }
 
@@ -118,7 +112,7 @@
      */
     @CalledByNative
     private void dismiss() {
-        mChipProvider.notifyObservers(new KeyboardAccessoryData.Action[0]);
+        mChipProvider.notifyObservers(new AutofillSuggestion[0]);
         mContext = null;
     }
 
@@ -128,27 +122,7 @@
      */
     @CalledByNative
     private void show(AutofillSuggestion[] suggestions, boolean isRtl) {
-        mChipProvider.notifyObservers(convertSuggestionsToChips(suggestions));
-    }
-
-    private KeyboardAccessoryData.Action[] convertSuggestionsToChips(
-            AutofillSuggestion[] suggestions) {
-        List<KeyboardAccessoryData.Action> suggestionChips = new ArrayList<>();
-        for (int i = 0; i < suggestions.length; ++i) {
-            AutofillSuggestion suggestion = suggestions[i];
-            // The accessory doesn't need any special options like clearing or managing for now.
-            if (suggestion.getSuggestionId() == PopupItemId.ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY
-                    || suggestion.getSuggestionId() == PopupItemId.ITEM_ID_CLEAR_FORM
-                    || suggestion.getSuggestionId() == PopupItemId.ITEM_ID_SEPARATOR
-                    || suggestion.getSuggestionId() == PopupItemId.ITEM_ID_AUTOFILL_OPTIONS) {
-                continue;
-            }
-            final int triggerPosition = i;
-            suggestionChips.add(new KeyboardAccessoryData.Action(suggestion.getLabel(),
-                    AccessoryAction.AUTOFILL_SUGGESTION,
-                    result -> suggestionSelected(triggerPosition)));
-        }
-        return suggestionChips.toArray(new KeyboardAccessoryData.Action[suggestionChips.size()]);
+        mChipProvider.notifyObservers(suggestions);
     }
 
     // Helper methods for AutofillSuggestion. These are copied from AutofillPopupBridge (which
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java
index d22478b..b2d3019 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java
@@ -18,6 +18,8 @@
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BarItem;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryViewBinder.BarItemViewHolder;
+import org.chromium.components.autofill.AutofillDelegate;
+import org.chromium.components.autofill.AutofillSuggestion;
 import org.chromium.ui.ViewProvider;
 import org.chromium.ui.modelutil.LazyConstructionPropertyMcp;
 import org.chromium.ui.modelutil.ListModel;
@@ -198,6 +200,19 @@
     }
 
     /**
+     * Registers a KeyboardAccessoryData.Observer to the given KeyboardAccessoryData.Provider. The
+     * new observer will render chips into the accessory bar for every new suggestion and call the
+     * given {@link AutofillDelegate} when the user interacts with a chip.
+     * @param provider A {@link KeyboardAccessoryData.Provider<AutofillSuggestion[]>}.
+     * @param delegate A {@link AutofillDelegate}.
+     */
+    public void registerAutofillProvider(
+            KeyboardAccessoryData.Provider<AutofillSuggestion[]> provider,
+            AutofillDelegate delegate) {
+        provider.addObserver(mMediator.createAutofillSuggestionsObserver(delegate));
+    }
+
+    /**
      * Dismisses the accessory by hiding it's view, clearing potentially left over suggestions and
      * hiding the keyboard.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java
index 2bed6ff..35fa048 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java
@@ -18,7 +18,11 @@
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryCoordinator.TabSwitchingDelegate;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryCoordinator.VisibilityDelegate;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action;
+import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.AutofillBarItem;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BarItem;
+import org.chromium.components.autofill.AutofillDelegate;
+import org.chromium.components.autofill.AutofillSuggestion;
+import org.chromium.components.autofill.PopupItemId;
 import org.chromium.ui.modelutil.ListObservable;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -58,21 +62,59 @@
         mModel.addObserver(this);
     }
 
+    /**
+     * Creates an observer object that refreshes the accessory bar items when a connected provider
+     * notifies it about new {@link AutofillSuggestion}s. It ensures the delegate receives
+     * interactions with the view representing a suggestion.
+     * @param delegate A {@link AutofillDelegate}.
+     * @return A {@link KeyboardAccessoryData.Observer} accepting only {@link AutofillSuggestion}s.
+     */
+    public KeyboardAccessoryData.Observer<AutofillSuggestion[]> createAutofillSuggestionsObserver(
+            AutofillDelegate delegate) {
+        return (@AccessoryAction int typeId, AutofillSuggestion[] suggestions) -> {
+            assert typeId
+                    == AccessoryAction.AUTOFILL_SUGGESTION
+                : "Autofill suggestions observer received wrong data: "
+                            + typeId;
+            List<BarItem> retainedItems = collectItemsToRetain(AccessoryAction.AUTOFILL_SUGGESTION);
+            retainedItems.addAll(toBarItems(suggestions, delegate));
+            mModel.get(BAR_ITEMS).set(retainedItems);
+        };
+    }
+
     @Override
-    public void onItemAvailable(@BarItem.Type int typeId, KeyboardAccessoryData.Action[] actions) {
+    public void onItemAvailable(
+            @AccessoryAction int typeId, KeyboardAccessoryData.Action[] actions) {
         assert typeId != DEFAULT_TYPE : "Did not specify which Action type has been updated.";
-        // If there is a new list, retain all actions that are of a different type than the provided
-        // actions.
+        List<BarItem> retainedItems = collectItemsToRetain(typeId);
+        retainedItems.addAll(0, toBarItems(actions));
+        mModel.get(BAR_ITEMS).set(retainedItems);
+    }
+
+    private List<BarItem> collectItemsToRetain(@AccessoryAction int actionType) {
         List<BarItem> retainedItems = new ArrayList<>();
         for (BarItem item : mModel.get(BAR_ITEMS)) {
             if (item.getAction() == null) continue;
-            if (item.getAction().getActionType() == typeId) continue;
+            if (item.getAction().getActionType() == actionType) continue;
             retainedItems.add(item);
         }
-        // Append autofill suggestions to the end, right before the tab switcher.
-        int insertPos = typeId == AccessoryAction.AUTOFILL_SUGGESTION ? retainedItems.size() : 0;
-        retainedItems.addAll(insertPos, toBarItems(actions));
-        mModel.get(BAR_ITEMS).set(retainedItems);
+        return retainedItems;
+    }
+
+    private List<BarItem> toBarItems(AutofillSuggestion[] suggestions, AutofillDelegate delegate) {
+        List<BarItem> barItems = new ArrayList<>(suggestions.length);
+        for (int position = 0; position < suggestions.length; ++position) {
+            AutofillSuggestion suggestion = suggestions[position];
+            // The accessory doesn't need any special options like clearing or managing for now.
+            if (suggestion.getSuggestionId() == PopupItemId.ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY
+                    || suggestion.getSuggestionId() == PopupItemId.ITEM_ID_CLEAR_FORM
+                    || suggestion.getSuggestionId() == PopupItemId.ITEM_ID_SEPARATOR
+                    || suggestion.getSuggestionId() == PopupItemId.ITEM_ID_AUTOFILL_OPTIONS) {
+                continue;
+            }
+            barItems.add(new AutofillBarItem(suggestion, createAutofillAction(delegate, position)));
+        }
+        return barItems;
     }
 
     private Collection<BarItem> toBarItems(Action[] actions) {
@@ -83,6 +125,16 @@
         return barItems;
     }
 
+    private KeyboardAccessoryData.Action createAutofillAction(AutofillDelegate delegate, int pos) {
+        return new KeyboardAccessoryData.Action(
+                null, // Unused. The AutofillSuggestion has more meaningful labels.
+                AccessoryAction.AUTOFILL_SUGGESTION, result -> {
+                    KeyboardAccessoryMetricsRecorder.recordActionSelected(
+                            AccessoryAction.AUTOFILL_SUGGESTION);
+                    delegate.suggestionSelected(pos);
+                });
+    }
+
     private @BarItem.Type int toBarItemType(@AccessoryAction int accessoryAction) {
         switch (accessoryAction) {
             case AccessoryAction.AUTOFILL_SUGGESTION:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java
index 0cc3449..5a8384ab 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java
@@ -7,9 +7,11 @@
 import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.KEYBOARD_TOGGLE_VISIBLE;
 import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.SHOW_KEYBOARD_CALLBACK;
 
+import android.view.View;
 import android.view.ViewGroup;
 
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.AutofillBarItem;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BarItem;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryViewBinder.BarItemViewHolder;
 import org.chromium.ui.modelutil.PropertyKey;
@@ -34,16 +36,21 @@
         return KeyboardAccessoryViewBinder.create(parent, viewType);
     }
 
-    static class BarItemChipViewHolder extends BarItemViewHolder<BarItem, ChipView> {
+    static class BarItemChipViewHolder extends BarItemViewHolder<AutofillBarItem, ChipView> {
         BarItemChipViewHolder(ViewGroup parent) {
             super(parent, R.layout.keyboard_accessory_suggestion_modern);
         }
 
         @Override
-        protected void bind(BarItem item, ChipView chipView) {
+        protected void bind(AutofillBarItem item, ChipView chipView) {
+            chipView.getPrimaryTextView().setText(item.getSuggestion().getLabel());
+            chipView.getSecondaryTextView().setText(item.getSuggestion().getSublabel());
+            chipView.getSecondaryTextView().setVisibility(
+                    item.getSuggestion().getSublabel().isEmpty() ? View.GONE : View.VISIBLE);
+            int iconId = item.getSuggestion().getIconId();
+            chipView.setIcon(iconId != 0 ? iconId : ChipView.INVALID_ICON_ID, false);
             KeyboardAccessoryData.Action action = item.getAction();
             assert action != null : "Tried to bind item without action. Chose a wrong ViewHolder?";
-            chipView.getPrimaryTextView().setText(action.getCaption());
             chipView.setOnClickListener(view -> action.getCallback().onResult(action));
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java
index 8a2eab5..cfdb3fb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java
@@ -9,6 +9,7 @@
 import android.support.v7.widget.RecyclerView;
 
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action;
+import org.chromium.components.autofill.AutofillSuggestion;
 import org.chromium.ui.modelutil.ListModel;
 import org.chromium.ui.modelutil.PropertyModel.ReadableObjectPropertyKey;
 import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
@@ -97,6 +98,33 @@
             return typeName + ": " + mAction;
         }
     }
+    /**
+     * This {@link BarItem} is used to render Autofill suggestions into the accessory bar.
+     * For that, it needs (in addition to an {@link Action}) the held {@link AutofillSuggestion}.
+     */
+    public static class AutofillBarItem extends BarItem {
+        private final AutofillSuggestion mSuggestion;
+
+        /**
+         * Creates a new autofill item with a suggestion for the view's representation and an action
+         * to handle the interaction with the rendered View.
+         * @param suggestion An {@link AutofillSuggestion}.
+         * @param action An {@link Action}.
+         */
+        public AutofillBarItem(AutofillSuggestion suggestion, Action action) {
+            super(Type.SUGGESTION, action);
+            mSuggestion = suggestion;
+        }
+
+        public AutofillSuggestion getSuggestion() {
+            return mSuggestion;
+        }
+
+        @Override
+        public String toString() {
+            return "Autofill" + super.toString();
+        }
+    }
 
     private KeyboardAccessoryProperties() {}
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java
index 58c2715..6919170 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java
@@ -143,8 +143,12 @@
         // Show overlay to prevent user from interacting with the page during onboarding.
         mModel.getOverlayModel().set(AssistantOverlayModel.STATE, AssistantOverlayState.full());
 
+        // Disable swiping for the onboarding because it interferes with letting the user scroll
+        // the onboarding contents.
+        mBottomBarCoordinator.allowSwipingBottomSheet(false);
         AssistantOnboardingCoordinator.show(mActivity, mBottomBarCoordinator.getView())
                 .then(accepted -> {
+                    mBottomBarCoordinator.allowSwipingBottomSheet(true);
                     if (!accepted) {
                         shutdownImmediately(DropOutReason.DECLINED);
                         return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
index e0a647e..755a801 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.util.IntentUtils;
 
+import java.net.URLDecoder;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -116,9 +117,14 @@
         Map<String, String> result = new HashMap<>();
         if (extras != null) {
             for (String key : extras.keySet()) {
-                if (key.startsWith(INTENT_EXTRA_PREFIX) && !key.startsWith(INTENT_SPECIAL_PREFIX)) {
-                    result.put(key.substring(INTENT_EXTRA_PREFIX.length()),
-                            extras.get(key).toString());
+                try {
+                    if (key.startsWith(INTENT_EXTRA_PREFIX)
+                            && !key.startsWith(INTENT_SPECIAL_PREFIX)) {
+                        result.put(key.substring(INTENT_EXTRA_PREFIX.length()),
+                                URLDecoder.decode(extras.get(key).toString(), "UTF-8"));
+                    }
+                } catch (java.io.UnsupportedEncodingException e) {
+                    throw new IllegalStateException("UTF-8 encoding not available.", e);
                 }
             }
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
index b015b7a..d6f5d99 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
@@ -35,6 +35,8 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeStringConstants;
+import org.chromium.chrome.browser.help.HelpAndFeedback;
+import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.components.sync.PassphraseType;
@@ -98,6 +100,7 @@
 
         TextView promptText = (TextView) v.findViewById(R.id.prompt_text);
         promptText.setText(getPromptText());
+        promptText.setMovementMethod(LinkMovementMethod.getInstance());
 
         TextView resetText = (TextView) v.findViewById(R.id.reset_text);
         resetText.setText(getResetText());
@@ -170,25 +173,42 @@
         super.onResume();
     }
 
-    private String getPromptText() {
+    private SpannableString applyInProductHelpSpan(
+            String stringWithLearnMoreTag, String helpContext) {
+        return SpanApplier.applySpans(stringWithLearnMoreTag,
+                new SpanInfo("<learnmore>", "</learnmore>", new ClickableSpan() {
+                    @Override
+                    public void onClick(View view) {
+                        HelpAndFeedback help = HelpAndFeedback.getInstance(getActivity());
+                        help.show(getActivity(), helpContext, Profile.getLastUsedProfile(), null);
+                    }
+                }));
+    }
+
+    private SpannableString getPromptText() {
         ProfileSyncService pss = ProfileSyncService.get();
         String accountName = pss.getCurrentSignedInAccountText() + "\n\n";
         PassphraseType passphraseType = pss.getPassphraseType();
         if (pss.hasExplicitPassphraseTime()) {
+            String syncPassphraseHelpContext =
+                    getString(R.string.help_context_change_sync_passphrase);
             switch (passphraseType) {
                 case FROZEN_IMPLICIT_PASSPHRASE:
-                    return accountName + pss.getSyncEnterGooglePassphraseBodyWithDateText();
+                    return applyInProductHelpSpan(
+                            accountName + pss.getSyncEnterGooglePassphraseBodyWithDateText(),
+                            syncPassphraseHelpContext);
                 case CUSTOM_PASSPHRASE:
-                    return accountName + pss.getSyncEnterCustomPassphraseBodyWithDateText();
+                    return applyInProductHelpSpan(
+                            accountName + pss.getSyncEnterCustomPassphraseBodyWithDateText(),
+                            syncPassphraseHelpContext);
                 case IMPLICIT_PASSPHRASE: // Falling through intentionally.
                 case KEYSTORE_PASSPHRASE: // Falling through intentionally.
                 default:
                     Log.w(TAG, "Found incorrect passphrase type " + passphraseType
                                     + ". Falling back to default string.");
-                    return accountName + pss.getSyncEnterCustomPassphraseBodyText();
             }
         }
-        return accountName + pss.getSyncEnterCustomPassphraseBodyText();
+        return new SpannableString(accountName + pss.getSyncEnterCustomPassphraseBodyText());
     }
 
     private SpannableString getResetText() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java
index 47b67fc..f2b10c40 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java
@@ -41,12 +41,17 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
+import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.AutofillBarItem;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BarItem;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.components.autofill.AutofillSuggestion;
 import org.chromium.ui.DeferredViewStubInflationProvider;
+import org.chromium.ui.DropdownItem;
 import org.chromium.ui.ViewProvider;
 import org.chromium.ui.modelutil.LazyConstructionPropertyMcp;
 import org.chromium.ui.modelutil.ListModel;
@@ -189,4 +194,27 @@
         onView(withText("Second")).check(doesNotExist());
         onView(withText("Third")).check(matches(isDisplayed()));
     }
+
+    @Test
+    @MediumTest
+    @Features.EnableFeatures(ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY)
+    public void testAddsClickableAutofillSuggestions() {
+        AtomicReference<Boolean> clickRecorded = new AtomicReference<>();
+        KeyboardAccessoryData.Action action = new KeyboardAccessoryData.Action(
+                "Unused", AUTOFILL_SUGGESTION, result -> clickRecorded.set(true));
+        ThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.set(VISIBLE, true);
+            mModel.get(BAR_ITEMS).set(new BarItem[] {
+                    new AutofillBarItem(
+                            new AutofillSuggestion("Johnathan", "Smithonian-Jackson",
+                                    DropdownItem.NO_ICON, false, 0, false, false, false),
+                            action),
+            });
+        });
+
+        onView(isRoot()).check((root, e) -> waitForView((ViewGroup) root, withText("Johnathan")));
+        onView(withText("Johnathan")).perform(click());
+
+        assertTrue(clickRecorded.get());
+    }
 }
\ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingTestHelper.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingTestHelper.java
index 0b90b3f..e2ea569 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingTestHelper.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingTestHelper.java
@@ -42,12 +42,15 @@
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Provider;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.UserInfo;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.components.autofill.AutofillDelegate;
+import org.chromium.components.autofill.AutofillSuggestion;
 import org.chromium.content_public.browser.ImeAdapter;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.test.util.DOMUtils;
 import org.chromium.content_public.browser.test.util.TestInputMethodManagerWrapper;
+import org.chromium.ui.DropdownItem;
 import org.chromium.ui.DropdownPopupWindowInterface;
 
 import java.util.concurrent.TimeoutException;
@@ -306,18 +309,29 @@
     }
 
     public void addAutofillChips() {
-        KeyboardAccessoryData.PropertyProvider<KeyboardAccessoryData.Action[]> suggestionProvider =
+        KeyboardAccessoryData.PropertyProvider<AutofillSuggestion[]> suggestionProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(AccessoryAction.AUTOFILL_SUGGESTION);
-        mActivityTestRule.getActivity().getManualFillingController().registerActionProvider(
-                suggestionProvider);
+        mActivityTestRule.getActivity()
+                .getManualFillingController()
+                .getKeyboardAccessory()
+                .registerAutofillProvider(suggestionProvider, new AutofillDelegate() {
+                    @Override
+                    public void dismissed() {}
+                    @Override
+                    public void suggestionSelected(int listIndex) {}
+                    @Override
+                    public void deleteSuggestion(int listIndex) {}
+                    @Override
+                    public void accessibilityFocusCleared() {}
+                });
         ThreadUtils.runOnUiThreadBlocking(() -> {
-            suggestionProvider.notifyObservers(new KeyboardAccessoryData.Action[] {
-                    new KeyboardAccessoryData.Action(
-                            "Jonathan", AccessoryAction.AUTOFILL_SUGGESTION, result -> {}),
-                    new KeyboardAccessoryData.Action(
-                            "Jane", AccessoryAction.AUTOFILL_SUGGESTION, result -> {}),
-                    new KeyboardAccessoryData.Action(
-                            "Marcus", AccessoryAction.AUTOFILL_SUGGESTION, result -> {})});
+            suggestionProvider.notifyObservers(new AutofillSuggestion[] {
+                    new AutofillSuggestion("Johnathan", "Smithonian-Jackson", DropdownItem.NO_ICON,
+                            false, 0, false, false, false),
+                    new AutofillSuggestion("Jane Erika", "Donovanova", DropdownItem.NO_ICON, false,
+                            1, false, false, false),
+                    new AutofillSuggestion("Marcus", "McSpartangregor", DropdownItem.NO_ICON, false,
+                            2, false, false, false)});
         });
     }
 
diff --git a/chrome/android/junit/DEPS b/chrome/android/junit/DEPS
index 47b7597..f0a295f 100644
--- a/chrome/android/junit/DEPS
+++ b/chrome/android/junit/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "!clank/java/src/org/chromium/chrome/browser/AppHooksImpl.java",
+  "+components/autofill/android/java/src/org/chromium/components/autofill",
   "+components/background_task_scheduler/android",
   "+components/bookmarks/common/android",
   "+components/offline_items_collection/core/android/java/src",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java
index f6c3165..ff40fc67 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java
@@ -7,6 +7,7 @@
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -32,7 +33,10 @@
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.PropertyProvider;
+import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.AutofillBarItem;
 import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BarItem;
+import org.chromium.components.autofill.AutofillDelegate;
+import org.chromium.components.autofill.AutofillSuggestion;
 import org.chromium.ui.modelutil.ListObservable;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -58,6 +62,8 @@
     private KeyboardAccessoryModernView mMockView;
     @Mock
     private KeyboardAccessoryTabLayoutView mMockTabSwitcherView;
+    @Mock
+    private AutofillDelegate mMockAutofillDelegate;
 
     private final KeyboardAccessoryData.Tab mTestTab =
             new KeyboardAccessoryData.Tab(null, null, 0, 0, null);
@@ -155,10 +161,11 @@
 
     @Test
     public void testIsVisibleWithSuggestionsBeforeKeyboardComesUp() {
-        KeyboardAccessoryData.PropertyProvider<Action[]> autofillSuggestionProvider =
+        KeyboardAccessoryData.PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(AUTOFILL_SUGGESTION);
-        Action suggestion = new Action("Suggestion", AUTOFILL_SUGGESTION, (a) -> {});
-        mCoordinator.registerActionProvider(autofillSuggestionProvider);
+        AutofillSuggestion suggestion =
+                new AutofillSuggestion("Label", "sublabel", 0, false, 0, false, false, false);
+        mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
 
         // Without suggestions, the accessory should remain invisible - even if the keyboard shows.
         assertThat(mModel.get(BAR_ITEMS).size(), is(0));
@@ -168,7 +175,8 @@
         mCoordinator.close();
 
         // Adding suggestions doesn't change the visibility by itself.
-        autofillSuggestionProvider.notifyObservers(new Action[] {suggestion, suggestion});
+        autofillSuggestionProvider.notifyObservers(
+                new AutofillSuggestion[] {suggestion, suggestion});
         assertThat(mModel.get(BAR_ITEMS).size(), is(2));
         assertThat(mModel.get(VISIBLE), is(false));
 
@@ -179,10 +187,11 @@
 
     @Test
     public void testIsVisibleWithSuggestionsAfterKeyboardComesUp() {
-        KeyboardAccessoryData.PropertyProvider<Action[]> autofillSuggestionProvider =
+        KeyboardAccessoryData.PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(AUTOFILL_SUGGESTION);
-        Action suggestion = new Action("Suggestion", AUTOFILL_SUGGESTION, (a) -> {});
-        mCoordinator.registerActionProvider(autofillSuggestionProvider);
+        AutofillSuggestion suggestion =
+                new AutofillSuggestion("Label", "sublabel", 0, false, 0, false, false, false);
+        mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
 
         // Without any suggestions, the accessory should remain invisible.
         assertThat(mModel.get(VISIBLE), is(false));
@@ -193,7 +202,8 @@
         assertThat(mModel.get(VISIBLE), is(false));
 
         // Adding suggestions while the keyboard is visible triggers the accessory.
-        autofillSuggestionProvider.notifyObservers(new Action[] {suggestion, suggestion});
+        autofillSuggestionProvider.notifyObservers(
+                new AutofillSuggestion[] {suggestion, suggestion});
         assertThat(mModel.get(BAR_ITEMS).size(), is(2));
         assertThat(mModel.get(VISIBLE), is(true));
     }
@@ -215,51 +225,62 @@
     public void testSortsActionsBasedOnType() {
         KeyboardAccessoryData.PropertyProvider<Action[]> generationProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(GENERATE_PASSWORD_AUTOMATIC);
-        KeyboardAccessoryData.PropertyProvider<Action[]> autofillSuggestionProvider =
+        KeyboardAccessoryData.PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(AUTOFILL_SUGGESTION);
 
         mCoordinator.registerActionProvider(generationProvider);
-        mCoordinator.registerActionProvider(autofillSuggestionProvider);
+        mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
 
-        Action suggestion1 = new Action("FirstSuggestion", AUTOFILL_SUGGESTION, (a) -> {});
-        Action suggestion2 = new Action("SecondSuggestion", AUTOFILL_SUGGESTION, (a) -> {});
+        AutofillSuggestion suggestion1 =
+                new AutofillSuggestion("FirstSuggestion", "", 0, false, 0, false, false, false);
+        AutofillSuggestion suggestion2 =
+                new AutofillSuggestion("SecondSuggestion", "", 0, false, 0, false, false, false);
         Action generationAction = new Action("Generate", GENERATE_PASSWORD_AUTOMATIC, (a) -> {});
-        autofillSuggestionProvider.notifyObservers(new Action[] {suggestion1, suggestion2});
+        autofillSuggestionProvider.notifyObservers(
+                new AutofillSuggestion[] {suggestion1, suggestion2});
         generationProvider.notifyObservers(new Action[] {generationAction});
 
         // Autofill suggestions should always come last, independent of when they were added.
         assertThat(mModel.get(BAR_ITEMS).size(), is(3));
         assertThat(mModel.get(BAR_ITEMS).get(0).getAction(), is(generationAction));
-        assertThat(mModel.get(BAR_ITEMS).get(1).getAction(), is(suggestion1));
-        assertThat(mModel.get(BAR_ITEMS).get(2).getAction(), is(suggestion2));
+        assertThat(mModel.get(BAR_ITEMS).get(1), instanceOf(AutofillBarItem.class));
+        AutofillBarItem autofillBarItem1 = (AutofillBarItem) mModel.get(BAR_ITEMS).get(1);
+        assertThat(autofillBarItem1.getSuggestion(), is(suggestion1));
+        assertThat(mModel.get(BAR_ITEMS).get(2), instanceOf(AutofillBarItem.class));
+        AutofillBarItem autofillBarItem2 = (AutofillBarItem) mModel.get(BAR_ITEMS).get(2);
+        assertThat(autofillBarItem2.getSuggestion(), is(suggestion2));
     }
 
     @Test
     public void testDeletingActionsAffectsOnlyOneType() {
         KeyboardAccessoryData.PropertyProvider<Action[]> generationProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(GENERATE_PASSWORD_AUTOMATIC);
-        KeyboardAccessoryData.PropertyProvider<Action[]> autofillSuggestionProvider =
+        KeyboardAccessoryData.PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(AUTOFILL_SUGGESTION);
 
         mCoordinator.registerActionProvider(generationProvider);
-        mCoordinator.registerActionProvider(autofillSuggestionProvider);
+        mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
 
-        Action suggestion = new Action("NewSuggestion", AUTOFILL_SUGGESTION, (a) -> {});
+        AutofillSuggestion suggestion =
+                new AutofillSuggestion("Suggestion", "", 0, false, 0, false, false, false);
         Action generationAction = new Action("Generate", GENERATE_PASSWORD_AUTOMATIC, (a) -> {});
-        autofillSuggestionProvider.notifyObservers(new Action[] {suggestion, suggestion});
+        autofillSuggestionProvider.notifyObservers(
+                new AutofillSuggestion[] {suggestion, suggestion});
         generationProvider.notifyObservers(new Action[] {generationAction});
         assertThat(mModel.get(BAR_ITEMS).size(), is(3));
 
         // Drop all Autofill suggestions. Only the generation action should remain.
-        autofillSuggestionProvider.notifyObservers(new Action[0]);
+        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[0]);
         assertThat(mModel.get(BAR_ITEMS).size(), is(1));
         assertThat(mModel.get(BAR_ITEMS).get(0).getAction(), is(generationAction));
 
         // Readd an Autofill suggestion and drop the generation. Only the suggestion should remain.
-        autofillSuggestionProvider.notifyObservers(new Action[] {suggestion});
+        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[] {suggestion});
         generationProvider.notifyObservers(new Action[0]);
         assertThat(mModel.get(BAR_ITEMS).size(), is(1));
-        assertThat(mModel.get(BAR_ITEMS).get(0).getAction(), is(suggestion));
+        assertThat(mModel.get(BAR_ITEMS).get(0), instanceOf(AutofillBarItem.class));
+        AutofillBarItem autofillBarItem = (AutofillBarItem) mModel.get(BAR_ITEMS).get(0);
+        assertThat(autofillBarItem.getSuggestion(), is(suggestion));
     }
 
     @Test
@@ -311,11 +332,12 @@
 
         // Adding suggestions adds to the suggestions bucket - and again to tabs and total.
         mCoordinator.close(); // Hide, so it's brought up again.
-        KeyboardAccessoryData.PropertyProvider<Action[]> autofillSuggestionProvider =
+        KeyboardAccessoryData.PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(AUTOFILL_SUGGESTION);
-        Action suggestion = new Action("Suggestion", AUTOFILL_SUGGESTION, (a) -> {});
-        mCoordinator.registerActionProvider(autofillSuggestionProvider);
-        autofillSuggestionProvider.notifyObservers(new Action[] {suggestion});
+        AutofillSuggestion suggestion =
+                new AutofillSuggestion("Label", "sublabel", 0, false, 0, false, false, false);
+        mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
+        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[] {suggestion});
         mCoordinator.requestShowing();
 
         // Hiding the keyboard clears actions, so don't log more actions from here on out.
@@ -326,7 +348,7 @@
 
         // Removing suggestions adds to everything but the suggestions bucket. The value remains.
         mCoordinator.close(); // Hide, so it's brought up again.
-        autofillSuggestionProvider.notifyObservers(new Action[0]);
+        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[0]);
         mCoordinator.requestShowing();
 
         assertThat(getShownMetricsCount(AccessoryBarContents.WITH_AUTOFILL_SUGGESTIONS), is(1));
@@ -354,11 +376,12 @@
         assertThat(getShownMetricsCount(AccessoryBarContents.WITH_ACTIONS), is(1));
         assertThat(getShownMetricsCount(AccessoryBarContents.ANY_CONTENTS), is(1));
 
-        KeyboardAccessoryData.PropertyProvider<Action[]> autofillSuggestionProvider =
+        KeyboardAccessoryData.PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
                 new KeyboardAccessoryData.PropertyProvider<>(AUTOFILL_SUGGESTION);
-        Action suggestion = new Action("Suggestion", AUTOFILL_SUGGESTION, (a) -> {});
-        mCoordinator.registerActionProvider(autofillSuggestionProvider);
-        autofillSuggestionProvider.notifyObservers(new Action[] {suggestion});
+        AutofillSuggestion suggestion =
+                new AutofillSuggestion("Label", "sublabel", 0, false, 0, false, false, false);
+        mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
+        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[] {suggestion});
         assertThat(getShownMetricsCount(AccessoryBarContents.WITH_AUTOFILL_SUGGESTIONS), is(1));
 
         // The other changes were not recorded again - just the changes.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index acb93ecb..142d8f73 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6998,9 +6998,6 @@
       <!-- Sync strings -->
 
       <!-- Shared between all the plaforms -->
-      <message name="IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE" desc="Instructions for the dialog where the user needs to enter their previous google passphrase.">
-        Your data was encrypted with your Google password as of <ph name="TIME">$1<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
-      </message>
       <message name="IDS_SYNC_ACCOUNT_INFO" desc="The message that appears in the options dialog indicating that the user is signed in with the given email address.">
         Signed in as <ph name="USER_EMAIL_ADDRESS">$1<ex>foo@gmail.com</ex></ph>.
       </message>
diff --git a/chrome/browser/android/signin/signin_investigator_android.cc b/chrome/browser/android/signin/signin_investigator_android.cc
index 01ea9fa..6618fc9 100644
--- a/chrome/browser/android/signin/signin_investigator_android.cc
+++ b/chrome/browser/android/signin/signin_investigator_android.cc
@@ -5,12 +5,14 @@
 #include "chrome/browser/android/signin/signin_investigator_android.h"
 
 #include "base/android/jni_string.h"
+#include "base/optional.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/signin/account_tracker_service_factory.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/investigator_dependency_provider.h"
-#include "components/signin/core/browser/account_tracker_service.h"
+#include "components/signin/core/browser/account_info.h"
 #include "jni/SigninInvestigator_jni.h"
+#include "services/identity/public/cpp/identity_manager.h"
 
 using base::android::ConvertJavaStringToUTF8;
 using base::android::JavaParamRef;
@@ -24,13 +26,15 @@
   InvestigatorDependencyProvider provider(profile);
   const std::string email = ConvertJavaStringToUTF8(env, current_email);
 
-  // It may be possible that the account tracker is not aware of this account
-  // yet. If this happens we'll get an empty account_id back, and the
-  // investigator should fallback to an email comparison.
-  const std::string account_id =
-      AccountTrackerServiceFactory::GetForProfile(profile)
-          ->FindAccountInfoByEmail(email)
-          .account_id;
+  // It is possible that the Identity Service is not aware of that account
+  // yet. In that case, pass an empty account_id to the investigator, so
+  // that it falls back to email comparison.
+  base::Optional<AccountInfo> maybe_account_info =
+      IdentityManagerFactory::GetForProfile(profile)
+          ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(email);
+  std::string account_id;
+  if (maybe_account_info.has_value())
+    account_id = maybe_account_info.value().account_id;
 
   return static_cast<int>(
       SigninInvestigator(email, account_id, &provider).Investigate());
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
index ace57e9..fd8ae34c 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -1351,8 +1351,10 @@
 
 // TODO(crbug.com/840080, crbug.com/824533): Filesystem and
 // CacheStorage can't be deleted on exit correctly at the moment.
+// TODO(crbug.com/927312): LocalStorage deletion is flaky.
 const std::vector<std::string> kSessionOnlyStorageTestTypes{
-    "Cookie", "LocalStorage",
+    "Cookie",
+    // "LocalStorage",
     // "FileSystem",
     "SessionStorage", "IndexedDb", "WebSql", "ServiceWorker",
     // "CacheStorage",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 5ef0e74..9f87ae1a 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -121,7 +121,6 @@
 #include "chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h"
 #include "chrome/browser/signin/chrome_signin_url_loader_throttle.h"
 #include "chrome/browser/signin/header_modification_delegate_impl.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
 #include "chrome/browser/speech/tts_controller_delegate_impl.h"
 #include "chrome/browser/speech/tts_message_filter.h"
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 32c174c..3beeed6 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1469,6 +1469,10 @@
     "platform_keys/platform_keys_service_factory.h",
     "plugin_vm/plugin_vm_image_download_client.cc",
     "plugin_vm/plugin_vm_image_download_client.h",
+    "plugin_vm/plugin_vm_image_manager.cc",
+    "plugin_vm/plugin_vm_image_manager.h",
+    "plugin_vm/plugin_vm_image_manager_factory.cc",
+    "plugin_vm/plugin_vm_image_manager_factory.h",
     "plugin_vm/plugin_vm_pref_names.cc",
     "plugin_vm/plugin_vm_pref_names.h",
     "plugin_vm/plugin_vm_util.cc",
@@ -1558,6 +1562,8 @@
     "policy/device_policy_remover.h",
     "policy/device_status_collector.cc",
     "policy/device_status_collector.h",
+    "policy/device_wallpaper_image_handler.cc",
+    "policy/device_wallpaper_image_handler.h",
     "policy/display_resolution_handler.cc",
     "policy/display_resolution_handler.h",
     "policy/display_rotation_default_handler.cc",
@@ -2356,6 +2362,7 @@
     "note_taking_helper_unittest.cc",
     "oauth2_token_service_delegate_unittest.cc",
     "ownership/owner_settings_service_chromeos_unittest.cc",
+    "plugin_vm/plugin_vm_image_manager_unittest.cc",
     "policy/active_directory_policy_manager_unittest.cc",
     "policy/affiliated_cloud_policy_invalidator_unittest.cc",
     "policy/affiliated_invalidation_service_provider_impl_unittest.cc",
@@ -2565,6 +2572,7 @@
     "//chromeos/services/multidevice_setup/public/cpp:prefs",
     "//chromeos/services/multidevice_setup/public/cpp:test_support",
     "//chromeos/services/secure_channel/public/cpp/client:test_support",
+    "//components/download/public/background_service/test:test_support",
     "//components/drive",
     "//components/drive:drive_chromeos",
     "//components/drive:test_support",
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
index 45a4bc4..b893167 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/image_decoder.h"
 #include "chrome/browser/ui/ash/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
@@ -71,6 +72,8 @@
         ash::prefs::kUserWallpaperInfo);
     pref_service_.registry()->RegisterDictionaryPref(
         ash::prefs::kWallpaperColors);
+    pref_service_.registry()->RegisterStringPref(
+        prefs::kDeviceWallpaperImageFilePath, std::string());
 
     // User
     user_manager_->AddUser(user_manager::StubAccountId());
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
index 19d176e..5c051c99 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
@@ -12,6 +12,8 @@
 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/ui/ash/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
 #include "components/account_id/account_id.h"
 #include "components/user_manager/scoped_user_manager.h"
@@ -66,6 +68,7 @@
   chromeos::SystemSaltGetter::Get()->SetRawSaltForTesting(
       chromeos::SystemSaltGetter::RawSalt({1, 2, 3, 4, 5, 6, 7, 8}));
 
+  ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal());
   WallpaperControllerClient client;
   TestWallpaperController test_controller;
   client.InitForTesting(test_controller.CreateInterfacePtr());
diff --git a/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc
index 15591a6e..7667eff 100644
--- a/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc
@@ -185,6 +185,11 @@
 
     LoginManagerTest::SetUpInProcessBrowserTestFixture();
     ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
+
+    // Set some fake state keys to make sure they are not empty.
+    std::vector<std::string> state_keys;
+    state_keys.push_back("1");
+    fake_session_manager_client_->set_server_backed_state_keys(state_keys);
   }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.cc
index 7e3f0776..59f77151 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.cc
@@ -5,21 +5,38 @@
 #include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h"
 
 #include "base/bind.h"
+#include "base/optional.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h"
+#include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
 #include "components/download/public/background_service/download_metadata.h"
+#include "components/download/public/background_service/download_service.h"
 #include "services/network/public/cpp/resource_request_body.h"
 
 namespace plugin_vm {
 
-PluginVmImageDownloadClient::PluginVmImageDownloadClient() = default;
+PluginVmImageDownloadClient::PluginVmImageDownloadClient(Profile* profile)
+    : profile_(profile) {}
 PluginVmImageDownloadClient::~PluginVmImageDownloadClient() = default;
 
+PluginVmImageManager* PluginVmImageDownloadClient::GetManager() {
+  return PluginVmImageManagerFactory::GetForProfile(profile_);
+}
+
 // TODO(okalitova): Remove logs.
 
 void PluginVmImageDownloadClient::OnServiceInitialized(
     bool state_lost,
     const std::vector<download::DownloadMetaData>& downloads) {
   VLOG(1) << __func__ << " called";
+  // TODO(okalitova): Manage downloads after sleep and log out.
+  for (const auto& download : downloads) {
+    VLOG(1) << "Download tracked by DownloadService: " << download.guid;
+    DownloadServiceFactory::GetForBrowserContext(profile_)->CancelDownload(
+        download.guid);
+  }
 }
 
 void PluginVmImageDownloadClient::OnServiceUnavailable() {
@@ -31,6 +48,8 @@
     const std::vector<GURL>& url_chain,
     const scoped_refptr<const net::HttpResponseHeaders>& headers) {
   VLOG(1) << __func__ << " called";
+  content_length_ = headers->GetContentLength();
+  GetManager()->OnDownloadStarted();
   return download::Client::ShouldDownload::CONTINUE;
 }
 
@@ -39,6 +58,7 @@
                                                     uint64_t bytes_downloaded) {
   VLOG(1) << __func__ << " called";
   VLOG(1) << bytes_downloaded << " bytes downloaded";
+  GetManager()->OnProgressUpdated(GetFractionComplete(bytes_downloaded));
 }
 
 void PluginVmImageDownloadClient::OnDownloadFailed(
@@ -66,6 +86,11 @@
       VLOG(1) << "Failure reason: CANCELLED";
       break;
   }
+
+  if (reason == download::Client::FailureReason::CANCELLED)
+    GetManager()->OnDownloadCancelled();
+  else
+    GetManager()->OnDownloadFailed();
 }
 
 void PluginVmImageDownloadClient::OnDownloadSucceeded(
@@ -75,14 +100,13 @@
   VLOG(1) << "Downloaded file is in " << completion_info.path.value();
   // TODO(https://crbug.com/904851): Verify download using hash specified by
   // PluginVmImage user policy. If hashes don't match remove downloaded file.
+  GetManager()->OnDownloadCompleted(completion_info.path);
 }
 
 bool PluginVmImageDownloadClient::CanServiceRemoveDownloadedFile(
     const std::string& guid,
     bool force_delete) {
   VLOG(1) << __func__ << " called";
-  // TODO(https://crbug.com/904851): Allow file removal only after it is
-  // unzipped to a specific directory.
   return true;
 }
 
@@ -94,4 +118,14 @@
       FROM_HERE, base::BindOnce(std::move(callback), nullptr));
 }
 
+base::Optional<double> PluginVmImageDownloadClient::GetFractionComplete(
+    int64_t bytes_downloaded) {
+  if (content_length_ == -1 || content_length_ == 0)
+    return base::nullopt;
+  if (bytes_downloaded > content_length_)
+    return base::nullopt;
+  return base::make_optional(static_cast<double>(bytes_downloaded) /
+                             content_length_);
+}
+
 }  // namespace plugin_vm
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h
index 4a8cd13..f699de8 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h
@@ -13,14 +13,23 @@
 struct DownloadMetaData;
 }  // namespace download
 
+class Profile;
+
 namespace plugin_vm {
 
+class PluginVmImageManager;
+
 class PluginVmImageDownloadClient : public download::Client {
  public:
-  PluginVmImageDownloadClient();
+  explicit PluginVmImageDownloadClient(Profile* profile);
   ~PluginVmImageDownloadClient() override;
 
  private:
+  Profile* profile_ = nullptr;
+  int64_t content_length_ = -1;
+
+  PluginVmImageManager* GetManager();
+
   // download::Client implementation.
   void OnServiceInitialized(
       bool state_lost,
@@ -44,6 +53,8 @@
   void GetUploadData(const std::string& guid,
                      download::GetUploadDataCallback callback) override;
 
+  base::Optional<double> GetFractionComplete(int64_t bytes_downloaded);
+
   DISALLOW_COPY_AND_ASSIGN(PluginVmImageDownloadClient);
 };
 
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc
new file mode 100644
index 0000000..4df7888
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc
@@ -0,0 +1,129 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/guid.h"
+#include "base/optional.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h"
+#include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/download/public/background_service/download_service.h"
+#include "components/prefs/pref_service.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+
+namespace plugin_vm {
+
+bool PluginVmImageManager::IsDownloading() {
+  return processing_download_;
+}
+
+void PluginVmImageManager::StartDownload() {
+  if (IsDownloading())
+    return OnDownloadFailed();
+  processing_download_ = true;
+  download_service_->StartDownload(GetDownloadParams());
+}
+
+void PluginVmImageManager::CancelDownload() {
+  DCHECK(!current_download_guid_.empty());
+  download_service_->CancelDownload(current_download_guid_);
+}
+
+void PluginVmImageManager::SetObserver(Observer* observer) {
+  observer_ = observer;
+}
+
+void PluginVmImageManager::OnDownloadStarted() {
+  if (observer_)
+    observer_->OnDownloadStarted();
+}
+
+void PluginVmImageManager::OnProgressUpdated(
+    base::Optional<double> fraction_complete) {
+  if (observer_)
+    observer_->OnProgressUpdated(fraction_complete);
+}
+
+void PluginVmImageManager::OnDownloadCompleted(base::FilePath file_path) {
+  if (observer_)
+    observer_->OnDownloadCompleted(file_path);
+  current_download_guid_.clear();
+  processing_download_ = false;
+}
+
+void PluginVmImageManager::OnDownloadCancelled() {
+  if (observer_)
+    observer_->OnDownloadCancelled();
+  current_download_guid_.clear();
+  processing_download_ = false;
+}
+
+void PluginVmImageManager::OnDownloadFailed() {
+  if (observer_)
+    observer_->OnDownloadFailed();
+  current_download_guid_.clear();
+  processing_download_ = false;
+}
+
+void PluginVmImageManager::SetDownloadServiceForTesting(
+    download::DownloadService* download_service) {
+  download_service_ = download_service;
+}
+
+std::string PluginVmImageManager::GetCurrentDownloadGuidForTesting() {
+  return current_download_guid_;
+}
+
+PluginVmImageManager::PluginVmImageManager(Profile* profile)
+    : profile_(profile),
+      download_service_(DownloadServiceFactory::GetForBrowserContext(profile)) {
+}
+PluginVmImageManager::~PluginVmImageManager() = default;
+
+download::DownloadParams PluginVmImageManager::GetDownloadParams() {
+  download::DownloadParams params;
+
+  // DownloadParams
+  params.client = download::DownloadClient::PLUGIN_VM_IMAGE;
+  params.guid = base::GenerateGUID();
+  params.callback = base::BindRepeating(&PluginVmImageManager::OnStarted,
+                                        base::Unretained(this));
+  // TODO(okalitova): Create annotation.
+  params.traffic_annotation =
+      net::MutableNetworkTrafficAnnotationTag(NO_TRAFFIC_ANNOTATION_YET);
+
+  // RequestParams
+  std::string url;
+  profile_->GetPrefs()
+      ->GetDictionary(plugin_vm::prefs::kPluginVmImage)
+      ->GetString("url", &url);
+  params.request_params.url = GURL(url);
+  params.request_params.method = "GET";
+
+  // SchedulingParams
+  // User initiates download by clicking on PluginVm icon so priorities should
+  // be the highest.
+  params.scheduling_params.priority = download::SchedulingParams::Priority::UI;
+  params.scheduling_params.battery_requirements =
+      download::SchedulingParams::BatteryRequirements::BATTERY_INSENSITIVE;
+  params.scheduling_params.network_requirements =
+      download::SchedulingParams::NetworkRequirements::NONE;
+
+  return params;
+}
+
+void PluginVmImageManager::OnStarted(
+    const std::string& download_guid,
+    download::DownloadParams::StartResult start_result) {
+  if (start_result == download::DownloadParams::ACCEPTED)
+    current_download_guid_ = download_guid;
+  else
+    OnDownloadFailed();
+}
+
+}  // namespace plugin_vm
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h
new file mode 100644
index 0000000..67ce02a
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h
@@ -0,0 +1,91 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_H_
+#define CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "components/download/public/background_service/download_params.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace base {
+template <typename T>
+class Optional;
+}  // namespace base
+
+namespace download {
+class DownloadService;
+}  // namespace download
+
+class Profile;
+
+namespace plugin_vm {
+
+// PluginVmImageManager is responsible for management of PluginVm image
+// including downloading this image from url specified by user policy and
+// unzipping downloaded image to the specified location.
+//
+// Only one download of PluginVm image at a time is allowed.
+// IsDownloading() should be called to check whether the manager is downloading
+// PluginVm image at the moment.
+class PluginVmImageManager : public KeyedService {
+ public:
+  // Observer class for the PluginVm image related events.
+  class Observer {
+   public:
+    virtual ~Observer() = default;
+    virtual void OnDownloadStarted() = 0;
+    virtual void OnProgressUpdated(
+        base::Optional<double> fraction_complete) = 0;
+    virtual void OnDownloadCompleted(base::FilePath file_path) = 0;
+    virtual void OnDownloadCancelled() = 0;
+    // TODO(https://crbug.com/904851): Add failure reasons.
+    virtual void OnDownloadFailed() = 0;
+  };
+
+  explicit PluginVmImageManager(Profile* profile);
+
+  // Returns true if manager is downloading PluginVm image at the moment.
+  bool IsDownloading();
+  // Fails download in case IsDownloading() returns true otherwise starts a new
+  // download of PluginVm image.
+  void StartDownload();
+  // Cancels the download of PluginVm image.
+  void CancelDownload();
+
+  void SetObserver(Observer* observer);
+
+  // Called by PluginVmImageDownloadClient.
+  void OnDownloadStarted();
+  void OnProgressUpdated(base::Optional<double> fraction_complete);
+  void OnDownloadCompleted(base::FilePath file_path);
+  void OnDownloadCancelled();
+  void OnDownloadFailed();
+
+  void SetDownloadServiceForTesting(
+      download::DownloadService* download_service);
+  std::string GetCurrentDownloadGuidForTesting();
+
+ private:
+  Profile* profile_ = nullptr;
+  download::DownloadService* download_service_ = nullptr;
+  Observer* observer_ = nullptr;
+  bool processing_download_ = false;
+  std::string current_download_guid_;
+
+  ~PluginVmImageManager() override;
+
+  download::DownloadParams GetDownloadParams();
+
+  void OnStarted(const std::string& download_guid,
+                 download::DownloadParams::StartResult start_result);
+
+  DISALLOW_COPY_AND_ASSIGN(PluginVmImageManager);
+};
+
+}  // namespace plugin_vm
+
+#endif  // CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_H_
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.cc
new file mode 100644
index 0000000..cb42325
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.cc
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h"
+
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h"
+#include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace plugin_vm {
+
+// static
+PluginVmImageManager* PluginVmImageManagerFactory::GetForProfile(
+    Profile* profile) {
+  return static_cast<PluginVmImageManager*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+PluginVmImageManagerFactory* PluginVmImageManagerFactory::GetInstance() {
+  return base::Singleton<PluginVmImageManagerFactory>::get();
+}
+
+PluginVmImageManagerFactory::PluginVmImageManagerFactory()
+    : BrowserContextKeyedServiceFactory(
+          "PluginVmImageManager",
+          BrowserContextDependencyManager::GetInstance()) {
+  DependsOn(DownloadServiceFactory::GetInstance());
+}
+
+PluginVmImageManagerFactory::~PluginVmImageManagerFactory() = default;
+
+KeyedService* PluginVmImageManagerFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new PluginVmImageManager(Profile::FromBrowserContext(context));
+}
+
+content::BrowserContext* PluginVmImageManagerFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  return chrome::GetBrowserContextRedirectedInIncognito(context);
+}
+
+}  // namespace plugin_vm
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h
new file mode 100644
index 0000000..ad4879f
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_FACTORY_H_
+#define CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+class Profile;
+
+namespace plugin_vm {
+
+class PluginVmImageManager;
+
+class PluginVmImageManagerFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static PluginVmImageManager* GetForProfile(Profile* profile);
+  static PluginVmImageManagerFactory* GetInstance();
+
+ private:
+  friend struct base::DefaultSingletonTraits<PluginVmImageManagerFactory>;
+
+  PluginVmImageManagerFactory();
+  ~PluginVmImageManagerFactory() override;
+
+  // BrowserContextKeyedServiceFactory implementation.
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(PluginVmImageManagerFactory);
+};
+
+}  // namespace plugin_vm
+
+#endif  // CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_FACTORY_H_
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc
new file mode 100644
index 0000000..430c030
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc
@@ -0,0 +1,165 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/optional.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h"
+#include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/download/public/background_service/test/test_download_service.h"
+#include "components/prefs/scoped_user_pref_update.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace plugin_vm {
+
+namespace {
+
+const char kProfileName[] = "p1";
+const char kUrl[] = "http://example.com";
+const char kHash[] =
+    "842841a4c75a55ad050d686f4ea5f77e83ae059877fe9b6946aa63d3d057ed32";
+
+}  // namespace
+
+class MockObserver : public PluginVmImageManager::Observer {
+ public:
+  MOCK_METHOD0(OnDownloadStarted, void());
+  MOCK_METHOD1(OnProgressUpdated,
+               void(base::Optional<double> fraction_complete));
+  MOCK_METHOD1(OnDownloadCompleted, void(base::FilePath file_path));
+  MOCK_METHOD0(OnDownloadCancelled, void());
+  MOCK_METHOD0(OnDownloadFailed, void());
+};
+
+class PluginVmImageManagerTest : public testing::Test {
+ public:
+  PluginVmImageManagerTest()
+      : download_service_(new download::test::TestDownloadService()) {}
+
+ protected:
+  content::TestBrowserThreadBundle test_browser_thread_bundle_;
+  std::unique_ptr<TestingProfile> profile_;
+  PluginVmImageManager* manager_;
+  download::test::TestDownloadService* download_service_;
+  std::unique_ptr<MockObserver> download_observer_;
+
+  void SetUp() override {
+    ASSERT_TRUE(profiles_dir_.CreateUniqueTempDir());
+    CreateProfile();
+    SetPluginVmImagePref(kUrl, kHash);
+
+    manager_ = PluginVmImageManagerFactory::GetForProfile(profile_.get());
+    download_service_->SetIsReady(true);
+    download_service_->set_client(
+        new PluginVmImageDownloadClient(profile_.get()));
+    manager_->SetDownloadServiceForTesting(download_service_);
+    download_observer_ = std::make_unique<MockObserver>();
+    manager_->SetObserver(download_observer_.get());
+  }
+
+  void TearDown() override {
+    profile_.reset();
+    download_observer_.reset();
+  }
+
+  void SetPluginVmImagePref(std::string url, std::string hash) {
+    DictionaryPrefUpdate update(profile_->GetPrefs(),
+                                plugin_vm::prefs::kPluginVmImage);
+    base::DictionaryValue* plugin_vm_image = update.Get();
+    plugin_vm_image->SetKey("url", base::Value(url));
+    plugin_vm_image->SetKey("hash", base::Value(hash));
+  }
+
+ private:
+  base::ScopedTempDir profiles_dir_;
+
+  void CreateProfile() {
+    TestingProfile::Builder profile_builder;
+    profile_builder.SetProfileName(kProfileName);
+    profile_builder.SetPath(profiles_dir_.GetPath().AppendASCII(kProfileName));
+    std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service =
+        std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
+    RegisterUserProfilePrefs(pref_service->registry());
+    profile_builder.SetPrefService(std::move(pref_service));
+    profile_ = profile_builder.Build();
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(PluginVmImageManagerTest);
+};
+
+TEST_F(PluginVmImageManagerTest, DownloadPluginVmImageParamsTest) {
+  EXPECT_CALL(*download_observer_, OnDownloadCompleted(testing::_));
+
+  manager_->StartDownload();
+
+  std::string guid = manager_->GetCurrentDownloadGuidForTesting();
+  base::Optional<download::DownloadParams> params =
+      download_service_->GetDownload(guid);
+  ASSERT_TRUE(params.has_value());
+  EXPECT_EQ(guid, params->guid);
+  EXPECT_EQ(download::DownloadClient::PLUGIN_VM_IMAGE, params->client);
+  EXPECT_EQ(GURL(kUrl), params->request_params.url);
+
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(PluginVmImageManagerTest, OnlyOneDownloadAtATimeIsAllowedTest) {
+  EXPECT_CALL(*download_observer_, OnDownloadCompleted(testing::_)).Times(1);
+  EXPECT_CALL(*download_observer_, OnDownloadFailed()).Times(1);
+
+  manager_->StartDownload();
+
+  EXPECT_TRUE(manager_->IsDownloading());
+
+  manager_->StartDownload();
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(PluginVmImageManagerTest, CanStartSecondDownloadWhenSucceededTest) {
+  EXPECT_CALL(*download_observer_, OnDownloadCompleted(testing::_)).Times(2);
+
+  manager_->StartDownload();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(manager_->IsDownloading());
+
+  manager_->StartDownload();
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(PluginVmImageManagerTest, CanStartSecondDownloadWhenFailedTest) {
+  EXPECT_CALL(*download_observer_, OnDownloadFailed()).Times(1);
+  EXPECT_CALL(*download_observer_, OnDownloadCompleted(testing::_)).Times(1);
+
+  manager_->StartDownload();
+  std::string guid = manager_->GetCurrentDownloadGuidForTesting();
+  download_service_->SetFailedDownload(guid, false);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(manager_->IsDownloading());
+
+  manager_->StartDownload();
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(PluginVmImageManagerTest, CancelledDownloadTest) {
+  EXPECT_CALL(*download_observer_, OnDownloadCompleted(testing::_)).Times(0);
+
+  manager_->StartDownload();
+  manager_->CancelDownload();
+  base::RunLoop().RunUntilIdle();
+}
+
+}  // namespace plugin_vm
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
index 8a74c70..6348208 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -32,6 +32,7 @@
 #include "chrome/browser/chromeos/policy/device_native_printers_handler.h"
 #include "chrome/browser/chromeos/policy/device_network_configuration_updater.h"
 #include "chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.h"
+#include "chrome/browser/chromeos/policy/device_wallpaper_image_handler.h"
 #include "chrome/browser/chromeos/policy/enrollment_config.h"
 #include "chrome/browser/chromeos/policy/hostname_handler.h"
 #include "chrome/browser/chromeos/policy/minimum_version_policy_handler.h"
@@ -228,6 +229,10 @@
 
   device_native_printers_handler_ =
       std::make_unique<DeviceNativePrintersHandler>(GetPolicyService());
+
+  device_wallpaper_image_handler_ =
+      std::make_unique<DeviceWallpaperImageHandler>(local_state,
+                                                    GetPolicyService());
 }
 
 void BrowserPolicyConnectorChromeOS::PreShutdown() {
@@ -262,6 +267,9 @@
   if (device_native_printers_handler_)
     device_native_printers_handler_->Shutdown();
 
+  if (device_wallpaper_image_handler_)
+    device_wallpaper_image_handler_->Shutdown();
+
   ChromeBrowserPolicyConnector::Shutdown();
 }
 
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
index a03f9f9..0a12d909 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -48,6 +48,7 @@
 class HostnameHandler;
 class MinimumVersionPolicyHandler;
 class DeviceNativePrintersHandler;
+class DeviceWallpaperImageHandler;
 class ProxyPolicyProvider;
 class ServerBackedStateKeysBroker;
 
@@ -226,6 +227,7 @@
   std::unique_ptr<HostnameHandler> hostname_handler_;
   std::unique_ptr<MinimumVersionPolicyHandler> minimum_version_policy_handler_;
   std::unique_ptr<DeviceNativePrintersHandler> device_native_printers_handler_;
+  std::unique_ptr<DeviceWallpaperImageHandler> device_wallpaper_image_handler_;
 
   // This policy provider is used on Chrome OS to feed user policy into the
   // global PolicyService instance. This works by installing the cloud policy
diff --git a/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.cc b/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.cc
index 1e56ede..c992719 100644
--- a/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.cc
+++ b/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.cc
@@ -19,8 +19,11 @@
 
 const char kCacheKey[] = "device_policy_external_data";
 
-// Maximum size of the device policy external data cache directory set to 10MB.
-const int64_t kCacheMaxSize = 10 * 1024 * 1024;
+// The maximum size of the device policy external data cache directory is set to
+// 21 MiB. It's calculated as the sum of the maximum allowed sizes for each of
+// the external data type device policies. At the moment, we have two of them:
+// DeviceWallpaperImage (16 MiB) and DeviceNativePrinters (5 MiB).
+const int64_t kCacheMaxSize = 21 * 1024 * 1024;
 // Only used for tests.
 int64_t g_cache_max_size_override = 0;
 
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
index 3c93246b..5641820 100644
--- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -768,7 +768,16 @@
     const em::ChromeDeviceSettingsProto& policy,
     base::WeakPtr<ExternalDataManager> external_data_manager,
     PolicyMap* policies) {
-  // TODO(https://crbug.com/814364): Migrate device wallpaper here.
+  if (policy.has_device_wallpaper_image()) {
+    const em::DeviceWallpaperImageProto& container(
+        policy.device_wallpaper_image());
+    if (container.has_device_wallpaper_image()) {
+      SetExternalDataDevicePolicy(key::kDeviceWallpaperImage,
+                                  container.device_wallpaper_image(),
+                                  external_data_manager, policies);
+    }
+  }
+
   if (policy.has_native_device_printers()) {
     const em::DeviceNativePrintersProto& container(
         policy.native_device_printers());
@@ -954,15 +963,6 @@
     }
   }
 
-  if (policy.has_device_wallpaper_image()) {
-    const em::DeviceWallpaperImageProto& container(
-        policy.device_wallpaper_image());
-    if (container.has_device_wallpaper_image()) {
-      SetJsonDevicePolicy(key::kDeviceWallpaperImage,
-                          container.device_wallpaper_image(), policies);
-    }
-  }
-
   if (policy.has_device_second_factor_authentication()) {
     const em::DeviceSecondFactorAuthenticationProto& container(
         policy.device_second_factor_authentication());
diff --git a/chrome/browser/chromeos/policy/device_wallpaper_image_handler.cc b/chrome/browser/chromeos/policy/device_wallpaper_image_handler.cc
new file mode 100644
index 0000000..647b3be
--- /dev/null
+++ b/chrome/browser/chromeos/policy/device_wallpaper_image_handler.cc
@@ -0,0 +1,51 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/policy/device_wallpaper_image_handler.h"
+
+#include <utility>
+
+#include "chrome/common/pref_names.h"
+#include "components/policy/policy_constants.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+
+namespace policy {
+
+DeviceWallpaperImageHandler::DeviceWallpaperImageHandler(
+    PrefService* local_state,
+    PolicyService* policy_service)
+    : local_state_(local_state),
+      device_wallpaper_image_observer_(
+          std::make_unique<DeviceCloudExternalDataPolicyObserver>(
+              policy_service,
+              key::kDeviceWallpaperImage,
+              this)) {}
+
+DeviceWallpaperImageHandler::~DeviceWallpaperImageHandler() = default;
+
+// static
+void DeviceWallpaperImageHandler::RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterStringPref(prefs::kDeviceWallpaperImageFilePath,
+                               std::string());
+}
+
+void DeviceWallpaperImageHandler::OnDeviceExternalDataCleared(
+    const std::string& policy) {
+  local_state_->SetString(prefs::kDeviceWallpaperImageFilePath, std::string());
+}
+
+void DeviceWallpaperImageHandler::OnDeviceExternalDataFetched(
+    const std::string& policy,
+    std::unique_ptr<std::string> data,
+    const base::FilePath& file_path) {
+  local_state_->SetString(prefs::kDeviceWallpaperImageFilePath,
+                          file_path.value());
+}
+
+void DeviceWallpaperImageHandler::Shutdown() {
+  device_wallpaper_image_observer_.reset();
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_wallpaper_image_handler.h b/chrome/browser/chromeos/policy/device_wallpaper_image_handler.h
new file mode 100644
index 0000000..84ed4a7
--- /dev/null
+++ b/chrome/browser/chromeos/policy/device_wallpaper_image_handler.h
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_WALLPAPER_IMAGE_HANDLER_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_WALLPAPER_IMAGE_HANDLER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/policy/device_cloud_external_data_policy_observer.h"
+
+class PrefRegistrySimple;
+class PrefService;
+
+namespace policy {
+
+class PolicyService;
+
+// This class observes the device setting "DeviceWallpaperImage", and sets
+// "policy.device_wallpaper_image_file_path" pref appropriately based on the
+// file path with fetched wallpaper image.
+class DeviceWallpaperImageHandler final
+    : public DeviceCloudExternalDataPolicyObserver::Delegate {
+ public:
+  DeviceWallpaperImageHandler(PrefService* local_state,
+                              PolicyService* policy_service);
+  ~DeviceWallpaperImageHandler() override;
+
+  static void RegisterPrefs(PrefRegistrySimple* registry);
+
+  // DeviceCloudExternalDataPolicyObserver::Delegate:
+  void OnDeviceExternalDataCleared(const std::string& policy) override;
+  void OnDeviceExternalDataFetched(const std::string& policy,
+                                   std::unique_ptr<std::string> data,
+                                   const base::FilePath& file_path) override;
+
+  void Shutdown();
+
+ private:
+  PrefService* const local_state_;
+
+  std::unique_ptr<DeviceCloudExternalDataPolicyObserver>
+      device_wallpaper_image_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceWallpaperImageHandler);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_WALLPAPER_IMAGE_HANDLER_H_
diff --git a/chrome/browser/download/download_service_factory.cc b/chrome/browser/download/download_service_factory.cc
index ffd4d188..00dd862 100644
--- a/chrome/browser/download/download_service_factory.cc
+++ b/chrome/browser/download/download_service_factory.cc
@@ -80,9 +80,10 @@
 
 #if defined(CHROMEOS)
   if (!context->IsOffTheRecord()) {
-    clients->insert(std::make_pair(
-        download::DownloadClient::PLUGIN_VM_IMAGE,
-        std::make_unique<plugin_vm::PluginVmImageDownloadClient>()));
+    clients->insert(
+        std::make_pair(download::DownloadClient::PLUGIN_VM_IMAGE,
+                       std::make_unique<plugin_vm::PluginVmImageDownloadClient>(
+                           Profile::FromBrowserContext(context))));
   }
 #endif
 
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index e48abac..5ab9d96 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -19,12 +19,10 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/chrome_device_id_helper.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "chrome/common/extensions/api/identity.h"
 #include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_pref_names.h"
 #include "content/public/common/service_manager_connection.h"
 #include "extensions/common/extension_l10n_util.h"
@@ -364,8 +362,8 @@
 #if !defined(OS_CHROMEOS)
   // ChromeOS in kiosk mode may start the mint token flow without account.
   DCHECK(!token_key_.account_id.empty());
-  DCHECK(ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile())
-             ->RefreshTokenIsAvailable(token_key_.account_id));
+  DCHECK(IdentityManagerFactory::GetForProfile(GetProfile())
+             ->HasAccountWithRefreshToken(token_key_.account_id));
 #endif
 
   mint_token_flow_type_ = type;
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc b/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc
index 0225bbfe..3dddc11 100644
--- a/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc
+++ b/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc
@@ -13,6 +13,7 @@
 #include "base/run_loop.h"
 #include "base/sequenced_task_runner.h"
 #include "base/task/post_task.h"
+#include "build/build_config.h"
 #include "chrome/browser/extensions/api/image_writer_private/operation.h"
 #include "chrome/services/removable_storage_writer/public/mojom/removable_storage_writer.mojom.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -277,7 +278,13 @@
   EXPECT_FALSE(error().empty());
 }
 
-IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, Write) {
+// Flaky on Win. http://crbug.com/927218
+#if defined(OS_WIN)
+#define MAYBE_Write DISABLED_Write
+#else
+#define MAYBE_Write Write
+#endif
+IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, MAYBE_Write) {
   FillImageFileWithPattern('i');
   FillDeviceFileWithPattern(0);
 
@@ -287,7 +294,13 @@
   EXPECT_TRUE(error().empty());
 }
 
-IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, WriteVerify) {
+// Flaky on Win. http://crbug.com/927218
+#if defined(OS_WIN)
+#define MAYBE_WriteVerify DISABLED_WriteVerify
+#else
+#define MAYBE_WriteVerify WriteVerify
+#endif
+IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, MAYBE_WriteVerify) {
   FillImageFileWithPattern('m');
   FillDeviceFileWithPattern(0);
 
@@ -297,7 +310,13 @@
   EXPECT_TRUE(error().empty());
 }
 
-IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, WriteCancel) {
+// Flaky on Win. http://crbug.com/927218
+#if defined(OS_WIN)
+#define MAYBE_WriteCancel DISABLED_WriteCancel
+#else
+#define MAYBE_WriteCancel WriteCancel
+#endif
+IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, MAYBE_WriteCancel) {
   FillImageFileWithPattern('a');
   FillDeviceFileWithPattern(0);
 
@@ -333,7 +352,13 @@
   EXPECT_FALSE(error().empty());
 }
 
-IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, Verify) {
+// Flaky on Win. http://crbug.com/927218
+#if defined(OS_WIN)
+#define MAYBE_Verify DISABLED_Verify
+#else
+#define MAYBE_Verify Verify
+#endif
+IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, MAYBE_Verify) {
   FillImageFileWithPattern('e');
   FillDeviceFileWithPattern('e');
 
@@ -343,7 +368,13 @@
   EXPECT_TRUE(error().empty());
 }
 
-IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, VerifyCancel) {
+// Flaky on Win. http://crbug.com/927218
+#if defined(OS_WIN)
+#define MAYBE_VerifyCancel DISABLED_VerifyCancel
+#else
+#define MAYBE_VerifyCancel VerifyCancel
+#endif
+IN_PROC_BROWSER_TEST_F(ImageWriterUtilityClientTest, MAYBE_VerifyCancel) {
   FillImageFileWithPattern('s');
   FillDeviceFileWithPattern('s');
 
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc
index d6dfa33..c2167513 100644
--- a/chrome/browser/metrics/ukm_browsertest.cc
+++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -341,8 +341,8 @@
     // This is required to support (fake) secondary-account-signin (based on
     // cookies) in tests. Without this, the real GaiaCookieManagerService would
     // try talking to Google servers which of course wouldn't work in tests.
-    fake_gaia_cookie_manager_factory_ =
-        secondary_account_helper::SetUpFakeGaiaCookieManagerService(
+    test_gaia_cookie_manager_factory_ =
+        secondary_account_helper::SetUpGaiaCookieManagerService(
             &test_url_loader_factory_);
     UkmBrowserTest::SetUpInProcessBrowserTestFixture();
   }
@@ -357,8 +357,8 @@
  private:
   base::test::ScopedFeatureList features_;
 
-  secondary_account_helper::ScopedFakeGaiaCookieManagerServiceFactory
-      fake_gaia_cookie_manager_factory_;
+  secondary_account_helper::ScopedGaiaCookieManagerServiceFactory
+      test_gaia_cookie_manager_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(UkmBrowserTestWithSyncTransport);
 };
@@ -1174,8 +1174,8 @@
   browser_sync::ProfileSyncService* sync_service =
       ProfileSyncServiceFactory::GetForProfile(profile);
 
-  secondary_account_helper::SignInSecondaryAccount(profile,
-                                                   "secondary_user@email.com");
+  secondary_account_helper::SignInSecondaryAccount(
+      profile, &test_url_loader_factory_, "secondary_user@email.com");
   ASSERT_NE(syncer::SyncService::TransportState::DISABLED,
             sync_service->GetTransportState());
   ASSERT_TRUE(harness->AwaitSyncTransportActive());
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc
index 6bc5cb5..da84369f 100644
--- a/chrome/browser/net/network_context_configuration_browsertest.cc
+++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -1574,8 +1574,14 @@
 
 // Test that when there's a proxy configuration at startup, the initial requests
 // use that configuration.
+// Flaky on CrOS only. http://crbug.com/922876
+#if defined(OS_CHROMEOS)
+#define MAYBE_TestInitialProxyConfig DISABLED_TestInitialProxyConfig
+#else
+#define MAYBE_TestInitialProxyConfig TestInitialProxyConfig
+#endif
 IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationProxyOnStartBrowserTest,
-                       TestInitialProxyConfig) {
+                       MAYBE_TestInitialProxyConfig) {
   if (IsRestartStateWithInProcessNetworkService())
     return;
   TestProxyConfigured(/*expect_success=*/true);
diff --git a/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc b/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc
index cb8b027..7c24f2a 100644
--- a/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc
+++ b/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc
@@ -5,12 +5,16 @@
 #include "chrome/browser/password_manager/password_store_signin_notifier_impl.h"
 
 #include "base/bind.h"
-#include "chrome/browser/signin/account_tracker_service_factory.h"
+#include "chrome/browser/signin/account_fetcher_service_factory.h"
 #include "chrome/browser/signin/fake_signin_manager_builder.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/password_manager/core/browser/mock_password_store.h"
+#include "components/signin/core/browser/account_fetcher_service.h"
 #include "content/public/test/test_browser_thread_bundle.h"
+#include "services/identity/public/cpp/accounts_mutator.h"
+#include "services/identity/public/cpp/primary_account_mutator.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using testing::_;
@@ -28,8 +32,6 @@
     testing_profile_.reset(builder.Build().release());
     fake_signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
         SigninManagerFactory::GetForProfile(testing_profile_.get()));
-    account_tracker_service_ =
-        AccountTrackerServiceFactory::GetForProfile(testing_profile_.get());
     store_ = new MockPasswordStore();
   }
 
@@ -41,7 +43,6 @@
   content::TestBrowserThreadBundle thread_bundle;
   std::unique_ptr<TestingProfile> testing_profile_;
   FakeSigninManagerForTesting* fake_signin_manager_;  // Weak
-  AccountTrackerService* account_tracker_service_;    // Weak
   scoped_refptr<MockPasswordStore> store_;
 };
 
@@ -50,7 +51,7 @@
 TEST_F(PasswordStoreSigninNotifierImplTest, Subscribed) {
   PasswordStoreSigninNotifierImpl notifier(testing_profile_.get());
   notifier.SubscribeToSigninEvents(store_.get());
-  fake_signin_manager_->SignIn("accountid", "username", "password");
+  fake_signin_manager_->SignIn("accountid", "username");
   testing::Mock::VerifyAndClearExpectations(store_.get());
   EXPECT_CALL(*store_, ClearAllGaiaPasswordHash());
   fake_signin_manager_->ForceSignOut();
@@ -64,7 +65,7 @@
   notifier.SubscribeToSigninEvents(store_.get());
   notifier.UnsubscribeFromSigninEvents();
   EXPECT_CALL(*store_, ClearAllGaiaPasswordHash()).Times(0);
-  fake_signin_manager_->SignIn("accountid", "username", "secret");
+  fake_signin_manager_->SignIn("accountid", "username");
   fake_signin_manager_->ForceSignOut();
 }
 
@@ -73,17 +74,43 @@
 TEST_F(PasswordStoreSigninNotifierImplTest, SignOutContentArea) {
   PasswordStoreSigninNotifierImpl notifier(testing_profile_.get());
   notifier.SubscribeToSigninEvents(store_.get());
-  fake_signin_manager_->SignIn("primary_accountid", "username", "password");
+
+  identity::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfileIfExists(testing_profile_.get());
+  identity::PrimaryAccountMutator* primary_account_mutator =
+      identity_manager->GetPrimaryAccountMutator();
+  DCHECK(primary_account_mutator);
+  primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
+      /*refresh_token=*/"refresh_token",
+      /*gaia_id=*/"primary_account_id",
+      /*username=*/"username", base::OnceCallback<void(const std::string&)>());
+  primary_account_mutator->LegacyCompletePendingPrimaryAccountSignin();
+
   testing::Mock::VerifyAndClearExpectations(store_.get());
 
   EXPECT_CALL(*store_, ClearGaiaPasswordHash("username2"));
-  account_tracker_service_->SeedAccountInfo("secondary_account_id",
-                                            "username2");
-  account_tracker_service_->RemoveAccount("secondary_account_id");
+
+  AccountFetcherService* account_fetcher_service =
+      AccountFetcherServiceFactory::GetForProfile(testing_profile_.get());
+  // This call is necessary to ensure that the account removal is fully
+  // processed in this testing context.
+  account_fetcher_service->EnableNetworkFetchesForTest();
+  identity_manager->GetAccountsMutator()->AddOrUpdateAccount(
+      /*gaia_id=*/"secondary_account_id",
+      /*email=*/"username2",
+      /*refresh_token=*/"refresh_token",
+      /*is_under_advanced_protection=*/false,
+      signin_metrics::SourceForRefreshTokenOperation::kUnknown);
+  identity_manager->GetAccountsMutator()->RemoveAccount(
+      "secondary_account_id",
+      signin_metrics::SourceForRefreshTokenOperation::kUserMenu_RemoveAccount);
   testing::Mock::VerifyAndClearExpectations(store_.get());
 
   EXPECT_CALL(*store_, ClearAllGaiaPasswordHash());
-  fake_signin_manager_->ForceSignOut();
+  primary_account_mutator->ClearPrimaryAccount(
+      identity::PrimaryAccountMutator::ClearAccountsAction::kRemoveAll,
+      signin_metrics::FORCE_SIGNOUT_ALWAYS_ALLOWED_FOR_TEST,
+      signin_metrics::SignoutDelete::IGNORE_METRIC);
   notifier.UnsubscribeFromSigninEvents();
 }
 
diff --git a/chrome/browser/policy/browser_signin_policy_handler.cc b/chrome/browser/policy/browser_signin_policy_handler.cc
index 5fe2c83..35b47eb 100644
--- a/chrome/browser/policy/browser_signin_policy_handler.cc
+++ b/chrome/browser/policy/browser_signin_policy_handler.cc
@@ -38,8 +38,7 @@
     }
     switch (static_cast<BrowserSigninMode>(int_value)) {
       case BrowserSigninMode::kForced:
-        prefs->SetValue(prefs::kForceBrowserSignin,
-                        std::make_unique<base::Value>(true));
+        prefs->SetValue(prefs::kForceBrowserSignin, base::Value(true));
         FALLTHROUGH;
       case BrowserSigninMode::kEnabled:
         prefs->SetValue(
@@ -51,7 +50,7 @@
 #else
             prefs::kSigninAllowedOnNextStartup,
 #endif
-            std::make_unique<base::Value>(true));
+            base::Value(true));
         break;
       case BrowserSigninMode::kDisabled:
         prefs->SetValue(
@@ -63,7 +62,7 @@
 #else
             prefs::kSigninAllowedOnNextStartup,
 #endif
-            std::make_unique<base::Value>(false));
+            base::Value(false));
         break;
     }
   }
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
index d27d4cae..7e7cd95 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -186,7 +186,7 @@
         IdentityManagerFactory::GetForProfile(browser()->profile())
             ->GetPrimaryAccountMutator();
     primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-        "", "account_id", "12345", PolicyBuilder::kFakeUsername,
+        "", "account_id", PolicyBuilder::kFakeUsername,
         base::OnceCallback<void(const std::string&)>());
 
     UserCloudPolicyManager* policy_manager =
diff --git a/chrome/browser/policy/developer_tools_policy_handler.cc b/chrome/browser/policy/developer_tools_policy_handler.cc
index 1c33dfb..d32c6f90 100644
--- a/chrome/browser/policy/developer_tools_policy_handler.cc
+++ b/chrome/browser/policy/developer_tools_policy_handler.cc
@@ -180,8 +180,7 @@
     if (value.value() == Availability::kDisallowed) {
       // Piggy-back disallowed developer tools to also force-disable
       // kExtensionsUIDeveloperMode.
-      prefs->SetValue(prefs::kExtensionsUIDeveloperMode,
-                      std::make_unique<base::Value>(false));
+      prefs->SetValue(prefs::kExtensionsUIDeveloperMode, base::Value(false));
     }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
   }
diff --git a/chrome/browser/policy/local_sync_policy_handler.cc b/chrome/browser/policy/local_sync_policy_handler.cc
index e40a648..e962be6 100644
--- a/chrome/browser/policy/local_sync_policy_handler.cc
+++ b/chrome/browser/policy/local_sync_policy_handler.cc
@@ -30,7 +30,7 @@
     base::FilePath::StringType expanded_value =
         policy::path_parser::ExpandPathVariables(string_value);
     prefs->SetValue(syncer::prefs::kLocalSyncBackendDir,
-                    std::make_unique<base::Value>(expanded_value));
+                    base::Value(expanded_value));
   }
 }
 
diff --git a/chrome/browser/policy/managed_bookmarks_policy_handler.cc b/chrome/browser/policy/managed_bookmarks_policy_handler.cc
index fe77569..5b5d701 100644
--- a/chrome/browser/policy/managed_bookmarks_policy_handler.cc
+++ b/chrome/browser/policy/managed_bookmarks_policy_handler.cc
@@ -43,7 +43,8 @@
   prefs->SetString(bookmarks::prefs::kManagedBookmarksFolderName,
                    GetFolderName(*list));
   FilterBookmarks(list);
-  prefs->SetValue(bookmarks::prefs::kManagedBookmarks, std::move(value));
+  prefs->SetValue(bookmarks::prefs::kManagedBookmarks,
+                  base::Value::FromUniquePtrValue(std::move(value)));
 }
 
 std::string
diff --git a/chrome/browser/policy/printing_restrictions_policy_handler.cc b/chrome/browser/policy/printing_restrictions_policy_handler.cc
index d4051408..c6c32ec 100644
--- a/chrome/browser/policy/printing_restrictions_policy_handler.cc
+++ b/chrome/browser/policy/printing_restrictions_policy_handler.cc
@@ -114,7 +114,9 @@
 void PrintingAllowedPageSizesPolicyHandler::ApplyList(
     std::unique_ptr<base::ListValue> filtered_list,
     PrefValueMap* prefs) {
-  prefs->SetValue(prefs::kPrintingAllowedPageSizes, std::move(filtered_list));
+  DCHECK(filtered_list);
+  prefs->SetValue(prefs::kPrintingAllowedPageSizes,
+                  base::Value::FromUniquePtrValue(std::move(filtered_list)));
 }
 
 PrintingColorDefaultPolicyHandler::PrintingColorDefaultPolicyHandler()
@@ -245,8 +247,7 @@
     PrefValueMap* prefs) {
   const base::Value* value;
   if (GetValue(policies, nullptr, &value)) {
-    prefs->SetValue(prefs::kPrintingSizeDefault,
-                    std::make_unique<base::Value>(value->Clone()));
+    prefs->SetValue(prefs::kPrintingSizeDefault, value->Clone());
   }
 }
 
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
index 9b7c986..f8517650 100644
--- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
+++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler.cc
@@ -181,7 +181,8 @@
   if (!value || !value->is_list())
     return;
 
-  prefs->SetValue(prefs::kManagedWebUsbAllowDevicesForUrls, std::move(value));
+  prefs->SetValue(prefs::kManagedWebUsbAllowDevicesForUrls,
+                  base::Value::FromUniquePtrValue(std::move(value)));
 }
 
 }  // namespace policy
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 0c5bca7..30731dc 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -261,6 +261,7 @@
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_status_collector.h"
+#include "chrome/browser/chromeos/policy/device_wallpaper_image_handler.h"
 #include "chrome/browser/chromeos/policy/dm_token_storage.h"
 #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
 #include "chrome/browser/chromeos/power/auto_screen_brightness/metrics_reporter.h"
@@ -533,6 +534,7 @@
   policy::BrowserPolicyConnectorChromeOS::RegisterPrefs(registry);
   policy::DeviceCloudPolicyManagerChromeOS::RegisterPrefs(registry);
   policy::DeviceStatusCollector::RegisterPrefs(registry);
+  policy::DeviceWallpaperImageHandler::RegisterPrefs(registry);
   policy::DMTokenStorage::RegisterPrefs(registry);
   policy::PolicyCertServiceFactory::RegisterPrefs(registry);
   quirks::QuirksManager::RegisterPrefs(registry);
diff --git a/chrome/browser/profiles/force_safe_search_policy_handler.cc b/chrome/browser/profiles/force_safe_search_policy_handler.cc
index db2ef1a..237d9bb 100644
--- a/chrome/browser/profiles/force_safe_search_policy_handler.cc
+++ b/chrome/browser/profiles/force_safe_search_policy_handler.cc
@@ -34,16 +34,16 @@
   }
   const base::Value* value = policies.GetValue(policy_name());
   if (value) {
-    prefs->SetValue(prefs::kForceGoogleSafeSearch, value->CreateDeepCopy());
+    prefs->SetValue(prefs::kForceGoogleSafeSearch, value->Clone());
 
     // Note that ForceYouTubeRestrict is an int policy, we cannot simply deep
     // copy value, which is a boolean.
     bool enabled = false;
     if (value->GetAsBoolean(&enabled)) {
-      prefs->SetValue(prefs::kForceYouTubeRestrict,
-                      std::make_unique<base::Value>(
-                          enabled ? safe_search_util::YOUTUBE_RESTRICT_MODERATE
-                                  : safe_search_util::YOUTUBE_RESTRICT_OFF));
+      prefs->SetValue(
+          prefs::kForceYouTubeRestrict,
+          base::Value(enabled ? safe_search_util::YOUTUBE_RESTRICT_MODERATE
+                              : safe_search_util::YOUTUBE_RESTRICT_OFF));
     }
   }
 }
diff --git a/chrome/browser/profiles/force_youtube_safety_mode_policy_handler.cc b/chrome/browser/profiles/force_youtube_safety_mode_policy_handler.cc
index 6537823..ba5176f9 100644
--- a/chrome/browser/profiles/force_youtube_safety_mode_policy_handler.cc
+++ b/chrome/browser/profiles/force_youtube_safety_mode_policy_handler.cc
@@ -33,10 +33,10 @@
   const base::Value* value = policies.GetValue(policy_name());
   bool enabled;
   if (value && value->GetAsBoolean(&enabled)) {
-    prefs->SetValue(prefs::kForceYouTubeRestrict,
-                    std::make_unique<base::Value>(
-                        enabled ? safe_search_util::YOUTUBE_RESTRICT_MODERATE
-                                : safe_search_util::YOUTUBE_RESTRICT_OFF));
+    prefs->SetValue(
+        prefs::kForceYouTubeRestrict,
+        base::Value(enabled ? safe_search_util::YOUTUBE_RESTRICT_MODERATE
+                            : safe_search_util::YOUTUBE_RESTRICT_OFF));
   }
 }
 
diff --git a/chrome/browser/profiles/renderer_updater_factory.cc b/chrome/browser/profiles/renderer_updater_factory.cc
index 3de9b05..d3b9ab5 100644
--- a/chrome/browser/profiles/renderer_updater_factory.cc
+++ b/chrome/browser/profiles/renderer_updater_factory.cc
@@ -6,14 +6,14 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/renderer_updater.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 RendererUpdaterFactory::RendererUpdaterFactory()
     : BrowserContextKeyedServiceFactory(
           "RendererUpdater",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(SigninManagerFactory::GetInstance());
+  DependsOn(IdentityManagerFactory::GetInstance());
 }
 
 RendererUpdaterFactory::~RendererUpdaterFactory() {}
diff --git a/chrome/browser/resources/chromeos/camera/Makefile b/chrome/browser/resources/chromeos/camera/Makefile
index f7322be..4cd0bfe 100644
--- a/chrome/browser/resources/chromeos/camera/Makefile
+++ b/chrome/browser/resources/chromeos/camera/Makefile
@@ -110,6 +110,7 @@
 	src/images/settings_timer_duration.svg \
 	src/images/spinner.svg \
 	src/js/background.js \
+	src/js/gallerybutton.js \
 	src/js/main.js \
 	src/js/models/gallery.js \
 	src/js/models/file_system.js \
@@ -120,7 +121,6 @@
 	src/js/util.js \
 	src/js/views/browser.js \
 	src/js/views/camera.js \
-	src/js/views/camera/gallerybutton.js \
 	src/js/views/camera/layout.js \
 	src/js/views/camera/options.js \
 	src/js/views/camera/preview.js \
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/gallerybutton.js b/chrome/browser/resources/chromeos/camera/src/js/gallerybutton.js
similarity index 80%
rename from chrome/browser/resources/chromeos/camera/src/js/views/camera/gallerybutton.js
rename to chrome/browser/resources/chromeos/camera/src/js/gallerybutton.js
index 9ddc0f0d..9d362b66 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/gallerybutton.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/gallerybutton.js
@@ -10,22 +10,12 @@
 var cca = cca || {};
 
 /**
- * Namespace for views.
- */
-cca.views = cca.views || {};
-
-/**
- * Namespace for Camera view.
- */
-cca.views.camera = cca.views.camera || {};
-
-/**
- * Creates a controller for the gallery-button of Camera view.
+ * Creates a controller for the gallery-button.
  * @param {cca.models.Gallery} model Model object.
  * @implements {cca.models.Gallery.Observer}
  * @constructor
  */
-cca.views.camera.GalleryButton = function(model) {
+cca.GalleryButton = function(model) {
   /**
    * @type {cca.models.Gallery}
    * @private
@@ -62,7 +52,7 @@
  * Updates the button for the model changes.
  * @private
  */
-cca.views.camera.GalleryButton.prototype.updateButton_ = function() {
+cca.GalleryButton.prototype.updateButton_ = function() {
   this.model_.lastPicture().then((picture) => {
     if (picture != this.lastPicture_) {
       this.lastPicture_ = picture;
@@ -84,7 +74,7 @@
  * @param {cca.models.Gallery.Picture} picture Picture to be browsed.
  * @private
  */
-cca.views.camera.GalleryButton.prototype.openGallery_ = function(picture) {
+cca.GalleryButton.prototype.openGallery_ = function(picture) {
   if (cca.App.useGalleryApp()) {
     const id = 'nlkncpkkdoccmpiclbokaimcnedabhhm|app|open';
     const entry = picture.pictureEntry;
@@ -101,7 +91,7 @@
 /**
  * @override
  */
-cca.views.camera.GalleryButton.prototype.onPictureDeleted = function(picture) {
+cca.GalleryButton.prototype.onPictureDeleted = function(picture) {
   if (this.lastPicture_ == picture) {
     this.updateButton_();
   }
@@ -110,7 +100,7 @@
 /**
  * @override
  */
-cca.views.camera.GalleryButton.prototype.onPictureAdded = function(picture) {
+cca.GalleryButton.prototype.onPictureAdded = function(picture) {
   if (!this.lastPicture_ || this.lastPicture_.timestamp <= picture.timestamp) {
     this.updateButton_();
   }
diff --git a/chrome/browser/resources/chromeos/camera/src/js/main.js b/chrome/browser/resources/chromeos/camera/src/js/main.js
index d1de32b..7a728fc 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/main.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/main.js
@@ -21,28 +21,10 @@
   this.model_ = new cca.models.Gallery();
 
   /**
-   * @type {cca.views.Camera}
+   * @type {cca.GalleryButton}
    * @private
    */
-  this.cameraView_ = new cca.views.Camera(this.model_);
-
-  /**
-   * @type {cca.views.MasterSettings}
-   * @private
-   */
-  this.settingsView_ = new cca.views.MasterSettings();
-
-  /**
-   * @type {cca.views.GridSettings}
-   * @private
-   */
-  this.gridsettingsView_ = new cca.views.GridSettings();
-
-  /**
-   * @type {cca.views.TimerSettings}
-   * @private
-   */
-  this.timersettingsView_ = new cca.views.TimerSettings();
+  this.galleryButton_ = new cca.GalleryButton(this.model_);
 
   /**
    * @type {cca.views.Browser}
@@ -50,18 +32,6 @@
    */
   this.browserView_ = new cca.views.Browser(this.model_);
 
-  /**
-   * @type {cca.views.Warning}
-   * @private
-   */
-  this.warningView_ = new cca.views.Warning();
-
-  /**
-   * @type {cca.views.Dialog}
-   * @private
-   */
-  this.dialogView_ = new cca.views.Dialog();
-
   // End of properties. Seal the object.
   Object.seal(this);
 
@@ -70,6 +40,17 @@
   document.title = chrome.i18n.getMessage('name');
   this.setupI18nElements_();
   this.setupToggles_();
+
+  // Set up views navigation by their DOM z-order.
+  cca.nav.setup([
+    new cca.views.Camera(this.model_),
+    new cca.views.MasterSettings(),
+    new cca.views.GridSettings(),
+    new cca.views.TimerSettings(),
+    this.browserView_,
+    new cca.views.Warning(),
+    new cca.views.Dialog(),
+  ]);
 };
 
 /*
@@ -146,18 +127,9 @@
 };
 
 /**
- * Starts the app by preparing views/model and opening the camera-view.
+ * Starts the app by loading the model and opening the camera-view.
  */
 cca.App.prototype.start = function() {
-  cca.nav.setup([
-    this.cameraView_,
-    this.settingsView_,
-    this.gridsettingsView_,
-    this.timersettingsView_,
-    this.browserView_,
-    this.warningView_,
-    this.dialogView_,
-  ]);
   cca.models.FileSystem.initialize(() => {
     // Prompt to migrate pictures if needed.
     var message = chrome.i18n.getMessage('migratePicturesMsg');
@@ -168,9 +140,7 @@
     });
   }).then((external) => {
     document.body.classList.toggle('ext-fs', external);
-    // Prepare the views/model and open camera-view.
-    this.cameraView_.prepare();
-    this.model_.addObserver(this.cameraView_.galleryButton);
+    this.model_.addObserver(this.galleryButton_);
     if (!cca.App.useGalleryApp()) {
       this.model_.addObserver(this.browserView_);
     }
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
index 99a7b734..dd4804c 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
@@ -79,13 +79,6 @@
   this.recordTime_ = new cca.views.camera.RecordTime();
 
   /**
-   * Button for going to the gallery.
-   * @type {cca.views.camera.GalleryButton}
-   * @private
-   */
-  this.galleryButton_ = new cca.views.camera.GalleryButton(model);
-
-  /**
    * Button for taking photos and recording videos.
    * @type {HTMLButtonElement}
    * @private
@@ -136,7 +129,18 @@
   Object.seal(this);
 
   this.shutterButton_.addEventListener('click',
-      this.onShutterButtonClicked_.bind(this));
+      () => this.onShutterButtonClicked_());
+
+  // Monitor the states to stop camera when locked/minimized.
+  chrome.idle.onStateChanged.addListener((newState) => {
+    this.locked_ = (newState == 'locked');
+    if (this.locked_) {
+      this.stop_();
+    }
+  });
+  chrome.app.window.current().onMinimized.addListener(() => this.stop_());
+
+  this.start_();
 };
 
 /**
@@ -157,27 +161,6 @@
   get recordMode() {
     return document.body.classList.contains('record-mode');
   },
-  get galleryButton() {
-    return this.galleryButton_;
-  },
-};
-
-/**
- * Prepares the view.
- */
-cca.views.Camera.prototype.prepare = function() {
-  // Monitor the states to stop camera when locked/minimized.
-  chrome.idle.onStateChanged.addListener((newState) => {
-    this.locked_ = (newState == 'locked');
-    if (this.locked_) {
-      this.stop_();
-    }
-  });
-  chrome.app.window.current().onMinimized.addListener(() => this.stop_());
-
-  // Start the camera after preparing the options (device ids).
-  this.options_.prepare();
-  this.start_();
 };
 
 /**
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
index d21de311..3ccb1e5 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
@@ -122,6 +122,16 @@
   this.tickSound_.src = '../sounds/tick.ogg';
   this.recordStartSound_.src = '../sounds/record_start.ogg';
   this.recordEndSound_.src = '../sounds/record_end.ogg';
+
+  // Restore saved mirroring states per video device.
+  chrome.storage.local.get({mirroringToggles: {}},
+      (values) => this.mirroringToggles_ = values.mirroringToggles);
+  // Remove the deprecated values.
+  chrome.storage.local.remove(['effectIndex', 'toggleMulti', 'toggleMirror']);
+
+  // TODO(yuli): Replace with devicechanged event.
+  this.maybeRefreshVideoDeviceIds_();
+  setInterval(() => this.maybeRefreshVideoDeviceIds_(), 1000);
 };
 
 /**
@@ -143,21 +153,6 @@
 };
 
 /**
- * Prepares the options.
- */
-cca.views.camera.Options.prototype.prepare = function() {
-  // Restore saved mirroring states per video device.
-  chrome.storage.local.get({mirroringToggles: {}},
-      (values) => this.mirroringToggles_ = values.mirroringToggles);
-  // Remove the deprecated values.
-  chrome.storage.local.remove(['effectIndex', 'toggleMulti', 'toggleMirror']);
-
-  // TODO(yuli): Replace with devicechanged event.
-  this.maybeRefreshVideoDeviceIds_();
-  setInterval(this.maybeRefreshVideoDeviceIds_.bind(this), 1000);
-};
-
-/**
  * Switches mode to either video-recording or photo-taking.
  * @param {boolean} record True for record-mode, false otherwise.
  * @private
diff --git a/chrome/browser/resources/chromeos/camera/src/views/main.html b/chrome/browser/resources/chromeos/camera/src/views/main.html
index 934b7af7..5faef4f6 100644
--- a/chrome/browser/resources/chromeos/camera/src/views/main.html
+++ b/chrome/browser/resources/chromeos/camera/src/views/main.html
@@ -13,12 +13,12 @@
     <script src="../js/toast.js"></script>
     <script src="../js/tooltip.js"></script>
     <script src="../js/scrollbar.js"></script>
+    <script src="../js/gallerybutton.js"></script>
     <script src="../js/models/gallery.js"></script>
     <script src="../js/models/file_system.js"></script>
     <script src="../js/views/view.js"></script>
     <script src="../js/views/gallery_base.js"></script>
     <script src="../js/views/camera.js"></script>
-    <script src="../js/views/camera/gallerybutton.js"></script>
     <script src="../js/views/camera/layout.js"></script>
     <script src="../js/views/camera/options.js"></script>
     <script src="../js/views/camera/preview.js"></script>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html
index a6f9b405..61815c4 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.html
+++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -125,11 +125,8 @@
         <div id="existingPassphraseTitle" class="list-item">
             <div class="start settings-box-text">
               <div>$i18n{existingPassphraseTitle}</div>
-              <div class="secondary">
-                [[enterPassphrasePrompt_(syncPrefs.passphraseTypeIsCustom)]]
-                <a href="$i18nRaw{syncErrorHelpUrl}" target="_blank">
-                  $i18n{learnMore}
-                </a>
+              <div class="secondary" inner-h-t-m-l="[[enterPassphrasePrompt_(
+                  syncPrefs.passphraseTypeIsCustom)]]">
               </div>
             </div>
         </div>
@@ -175,11 +172,9 @@
             unifiedConsentEnabled, syncPrefs.passphraseRequired)]]">
           <div id="existingPassphrase" class="list-frame">
             <div class="list-item">
-              <div class="settings-box-text">
-                [[enterPassphrasePrompt_(syncPrefs.passphraseTypeIsCustom)]]
-                <a href="$i18nRaw{syncErrorHelpUrl}" target="_blank">
-                  $i18n{learnMore}
-                </a>
+              <div class="settings-box-text"
+                  inner-h-t-m-l="[[enterPassphrasePrompt_(
+                      syncPrefs.passphraseTypeIsCustom)]]">
               </div>
             </div>
             <div id="existingPassphraseContainer" class="list-item">
diff --git a/chrome/browser/search/search_suggest/search_suggest_service_unittest.cc b/chrome/browser/search/search_suggest/search_suggest_service_unittest.cc
index 5e0f55c..119de9c 100644
--- a/chrome/browser/search/search_suggest/search_suggest_service_unittest.cc
+++ b/chrome/browser/search/search_suggest/search_suggest_service_unittest.cc
@@ -18,7 +18,6 @@
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/search_test_utils.h"
 #include "components/search_engines/template_url_service.h"
-#include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/test_signin_client.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "services/identity/public/cpp/identity_test_environment.h"
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index 158fcf1..3d8427d 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -1622,6 +1622,10 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreTest, MAYBE_CorrectLoadingOrder) {
+  // TODO(https://crbug.com/923051): Flaky in single process mash.
+  if (features::IsSingleProcessMash())
+    return;
+
   const int activation_order[] = {4, 2, 5, 0, 3, 1};
   Profile* profile = browser()->profile();
 
diff --git a/chrome/browser/signin/dice_response_handler_unittest.cc b/chrome/browser/signin/dice_response_handler_unittest.cc
index 722a8e4d..1e106139 100644
--- a/chrome/browser/signin/dice_response_handler_unittest.cc
+++ b/chrome/browser/signin/dice_response_handler_unittest.cc
@@ -12,10 +12,8 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
 #include "base/scoped_observer.h"
-#include "base/test/test_mock_time_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/time/time.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/signin/core/browser/about_signin_internals.h"
@@ -94,8 +92,9 @@
 
  protected:
   DiceResponseHandlerTest()
-      : loop_(base::MessageLoop::TYPE_IO),  // URLRequestContext requires IO.
-        task_runner_(new base::TestMockTimeTaskRunner()),
+      : scoped_task_environment_(
+            base::test::ScopedTaskEnvironment::MainThreadType::
+                IO_MOCK_TIME),  // URLRequestContext requires IO.
         signin_client_(&pref_service_),
         token_service_(&pref_service_,
                        std::make_unique<FakeOAuth2TokenServiceDelegate>()),
@@ -119,8 +118,6 @@
                                 signin::AccountConsistencyMethod::kDice),
         reconcilor_blocked_count_(0),
         reconcilor_unblocked_count_(0) {
-    loop_.SetTaskRunner(task_runner_);
-    DCHECK_EQ(task_runner_, base::ThreadTaskRunnerHandle::Get());
     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
     AboutSigninInternals::RegisterPrefs(pref_service_.registry());
     AccountTrackerService::RegisterPrefs(pref_service_.registry());
@@ -147,7 +144,6 @@
     account_tracker_service_.Shutdown();
     token_service_.Shutdown();
     signin_client_.Shutdown();
-    task_runner_->ClearPendingTasks();
   }
 
   void InitializeDiceResponseHandler(
@@ -198,9 +194,8 @@
     return identity_test_env_.identity_manager();
   }
 
-  base::MessageLoop loop_;
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
   base::ScopedTempDir temp_dir_;
-  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
   DiceTestSigninClient signin_client_;
   FakeProfileOAuth2TokenService token_service_;
@@ -469,7 +464,7 @@
   EXPECT_EQ(
       1u, dice_response_handler_->GetPendingDiceTokenFetchersCountForTesting());
   // Force a timeout.
-  task_runner_->FastForwardBy(
+  scoped_task_environment_.FastForwardBy(
       base::TimeDelta::FromSeconds(kDiceTokenFetchTimeoutSeconds + 1));
   EXPECT_EQ(
       0u, dice_response_handler_->GetPendingDiceTokenFetchersCountForTesting());
diff --git a/chrome/browser/signin/signin_global_error_unittest.cc b/chrome/browser/signin/signin_global_error_unittest.cc
index d26bc9a6..7fc6ce51 100644
--- a/chrome/browser/signin/signin_global_error_unittest.cc
+++ b/chrome/browser/signin/signin_global_error_unittest.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/signin/signin_error_controller_factory.h"
 #include "chrome/browser/signin/signin_global_error_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/signin/signin_profile_attributes_updater_factory.cc b/chrome/browser/signin/signin_profile_attributes_updater_factory.cc
index a7443243..c5187ff 100644
--- a/chrome/browser/signin/signin_profile_attributes_updater_factory.cc
+++ b/chrome/browser/signin/signin_profile_attributes_updater_factory.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/signin/signin_error_controller_factory.h"
 #include "chrome/browser/signin/signin_profile_attributes_updater.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/signin/core/browser/signin_manager.h"
 
 // static
 SigninProfileAttributesUpdater*
diff --git a/chrome/browser/signin/signin_ui_util_unittest.cc b/chrome/browser/signin/signin_ui_util_unittest.cc
index 562456b..9cea25a 100644
--- a/chrome/browser/signin/signin_ui_util_unittest.cc
+++ b/chrome/browser/signin/signin_ui_util_unittest.cc
@@ -9,14 +9,9 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "build/buildflag.h"
-#include "chrome/browser/signin/fake_gaia_cookie_manager_service_builder.h"
-#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
-#include "chrome/browser/signin/fake_signin_manager_builder.h"
-#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/signin/scoped_account_consistency.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/signin_promo.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "components/google/core/browser/google_url_tracker.h"
@@ -137,10 +132,8 @@
 
   // BrowserWithTestWindowTest:
   TestingProfile::TestingFactories GetTestingFactories() override {
-    return {{SigninManagerFactory::GetInstance(),
-             base::BindRepeating(&BuildFakeSigninManagerForTesting)},
-            {ProfileOAuth2TokenServiceFactory::GetInstance(),
-             base::BindRepeating(&BuildFakeProfileOAuth2TokenService)}};
+    return IdentityTestEnvironmentProfileAdaptor::
+        GetIdentityTestEnvironmentFactories();
   }
 
   // BrowserWithTestWindowTest:
@@ -148,11 +141,6 @@
     return new SigninUiUtilTestBrowserWindow();
   }
 
-  // Returns the token service.
-  ProfileOAuth2TokenService* GetTokenService() {
-    return ProfileOAuth2TokenServiceFactory::GetForProfile(profile());
-  }
-
   // Returns the identity manager.
   identity::IdentityManager* GetIdentityManager() {
     return IdentityManagerFactory::GetForProfile(profile());
diff --git a/chrome/browser/spellchecker/spellcheck_language_policy_handler.cc b/chrome/browser/spellchecker/spellcheck_language_policy_handler.cc
index 1eee088..7760642 100644
--- a/chrome/browser/spellchecker/spellcheck_language_policy_handler.cc
+++ b/chrome/browser/spellchecker/spellcheck_language_policy_handler.cc
@@ -41,21 +41,19 @@
 
   const base::Value::ListStorage& languages = value->GetList();
 
-  std::unique_ptr<base::ListValue> forced_language_list =
-      std::make_unique<base::ListValue>();
+  std::vector<base::Value> forced_language_list;
   for (const base::Value& language : languages) {
     std::string current_language =
         spellcheck::GetCorrespondingSpellCheckLanguage(
             base::TrimWhitespaceASCII(language.GetString(), base::TRIM_ALL));
     if (!current_language.empty()) {
-      forced_language_list->GetList().push_back(base::Value(current_language));
+      forced_language_list.emplace_back(std::move(current_language));
     } else {
       LOG(WARNING) << "Unknown language requested: \"" << language << "\"";
     }
   }
 
-  prefs->SetValue(spellcheck::prefs::kSpellCheckEnable,
-                  std::make_unique<base::Value>(true));
+  prefs->SetValue(spellcheck::prefs::kSpellCheckEnable, base::Value(true));
   prefs->SetValue(spellcheck::prefs::kSpellCheckForcedDictionaries,
-                  std::move(forced_language_list));
+                  base::Value(std::move(forced_language_list)));
 }
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc
index 0f265da..2ad81c0 100644
--- a/chrome/browser/sync/profile_sync_service_android.cc
+++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -434,10 +434,10 @@
       sync_service_->GetUserSettings()->GetExplicitPassphraseTime();
   base::string16 passphrase_time_str =
       base::TimeFormatShortDate(passphrase_time);
-  return base::android::ConvertUTF16ToJavaString(env,
-      l10n_util::GetStringFUTF16(
-        IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
-        passphrase_time_str));
+  return base::android::ConvertUTF16ToJavaString(
+      env, l10n_util::GetStringFUTF16(
+               IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE_ANDROID,
+               passphrase_time_str));
 }
 
 ScopedJavaLocalRef<jstring>
@@ -449,9 +449,10 @@
       sync_service_->GetUserSettings()->GetExplicitPassphraseTime();
   base::string16 passphrase_time_str =
       base::TimeFormatShortDate(passphrase_time);
-  return base::android::ConvertUTF16ToJavaString(env,
-      l10n_util::GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
-        passphrase_time_str));
+  return base::android::ConvertUTF16ToJavaString(
+      env, l10n_util::GetStringFUTF16(
+               IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID,
+               passphrase_time_str));
 }
 
 ScopedJavaLocalRef<jstring>
diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc
index aa7c4a93..efc045b 100644
--- a/chrome/browser/sync/sync_ui_util_unittest.cc
+++ b/chrome/browser/sync/sync_ui_util_unittest.cc
@@ -56,7 +56,6 @@
 const char kTestGaiaId[] = "gaia-id-test_user@test.com";
 const char kTestUser[] = "test_user@test.com";
 const char kRefreshToken[] = "refresh_token";
-const char kPassword[] = "password";
 
 }  // namespace
 
@@ -105,7 +104,7 @@
       // report "auth in progress" when checked from the test later on.
       primary_account_mutator
           ->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-              kRefreshToken, kTestGaiaId, kTestUser, kPassword,
+              kRefreshToken, kTestGaiaId, kTestUser,
               base::BindOnce([](const std::string& refresh_token) {
                 // Check that the token is properly passed along.
                 EXPECT_EQ(kRefreshToken, refresh_token);
diff --git a/chrome/browser/sync/test/integration/encryption_helper.cc b/chrome/browser/sync/test/integration/encryption_helper.cc
index 389c94f..f2fd767a 100644
--- a/chrome/browser/sync/test/integration/encryption_helper.cc
+++ b/chrome/browser/sync/test/integration/encryption_helper.cc
@@ -169,7 +169,8 @@
     : SingleClientStatusChangeChecker(service), desired_state_(desired_state) {}
 
 bool PassphraseRequiredStateChecker::IsExitConditionSatisfied() {
-  return service()->IsPassphraseRequiredForDecryption() == desired_state_;
+  return service()->GetUserSettings()->IsPassphraseRequiredForDecryption() ==
+         desired_state_;
 }
 
 std::string PassphraseRequiredStateChecker::GetDebugMessage() const {
diff --git a/chrome/browser/sync/test/integration/secondary_account_helper.cc b/chrome/browser/sync/test/integration/secondary_account_helper.cc
index c2a9d4d5..61aefbb 100644
--- a/chrome/browser/sync/test/integration/secondary_account_helper.cc
+++ b/chrome/browser/sync/test/integration/secondary_account_helper.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h"
 #include "services/identity/public/cpp/identity_manager.h"
 #include "services/identity/public/cpp/identity_test_utils.h"
 #include "services/identity/public/cpp/primary_account_mutator.h"
@@ -31,14 +30,13 @@
     network::TestURLLoaderFactory* test_url_loader_factory,
     content::BrowserContext* context) {
   GaiaCookieManagerServiceFactory::GetInstance()->SetTestingFactory(
-      context,
-      base::BindRepeating(&BuildFakeGaiaCookieManagerServiceWithURLLoader,
-                          test_url_loader_factory));
+      context, base::BindRepeating(&BuildGaiaCookieManagerServiceWithURLLoader,
+                                   test_url_loader_factory));
 }
 
 }  // namespace
 
-ScopedFakeGaiaCookieManagerServiceFactory SetUpFakeGaiaCookieManagerService(
+ScopedGaiaCookieManagerServiceFactory SetUpGaiaCookieManagerService(
     network::TestURLLoaderFactory* test_url_loader_factory) {
   return BrowserContextDependencyManager::GetInstance()
       ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
@@ -69,15 +67,15 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
-void SignInSecondaryAccount(Profile* profile, const std::string& email) {
+void SignInSecondaryAccount(
+    Profile* profile,
+    network::TestURLLoaderFactory* test_url_loader_factory,
+    const std::string& email) {
   identity::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForProfile(profile);
   AccountInfo account_info =
       identity::MakeAccountAvailable(identity_manager, email);
-  FakeGaiaCookieManagerService* fake_cookie_service =
-      static_cast<FakeGaiaCookieManagerService*>(
-          GaiaCookieManagerServiceFactory::GetForProfile(profile));
-  identity::SetCookieAccounts(fake_cookie_service, identity_manager,
+  identity::SetCookieAccounts(identity_manager, test_url_loader_factory,
                               {{account_info.email, account_info.gaia}});
 }
 
diff --git a/chrome/browser/sync/test/integration/secondary_account_helper.h b/chrome/browser/sync/test/integration/secondary_account_helper.h
index ad21a70..e7d74c4 100644
--- a/chrome/browser/sync/test/integration/secondary_account_helper.h
+++ b/chrome/browser/sync/test/integration/secondary_account_helper.h
@@ -23,14 +23,15 @@
 
 namespace secondary_account_helper {
 
-using ScopedFakeGaiaCookieManagerServiceFactory = std::unique_ptr<
+using ScopedGaiaCookieManagerServiceFactory = std::unique_ptr<
     base::CallbackList<void(content::BrowserContext*)>::Subscription>;
 
-// Sets up a factory to create a FakeGaiaCookieManagerService. Meant to be
+// Sets up a factory to create a GaiaCookieManagerService which uses the
+// provided |test_url_loader_factory| for cookie-related requests. Meant to be
 // called from SetUpInProcessBrowserTestFixture. The caller should hold on to
 // the returned object for the duration of the test, e.g. store it in a member
 // of the test fixture class.
-ScopedFakeGaiaCookieManagerServiceFactory SetUpFakeGaiaCookieManagerService(
+ScopedGaiaCookieManagerServiceFactory SetUpGaiaCookieManagerService(
     network::TestURLLoaderFactory* test_url_loader_factory);
 
 #if defined(OS_CHROMEOS)
@@ -45,7 +46,10 @@
 #endif  // defined(OS_CHROMEOS)
 
 // Makes a non-primary account available with both a refresh token and cookie.
-void SignInSecondaryAccount(Profile* profile, const std::string& email);
+void SignInSecondaryAccount(
+    Profile* profile,
+    network::TestURLLoaderFactory* test_url_loader_factory,
+    const std::string& email);
 
 #if !defined(OS_CHROMEOS)
 // Makes the given account Chrome's primary one. The account must already be
diff --git a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
index c3ad502..a987cd01 100644
--- a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
@@ -38,8 +38,8 @@
   ~SingleClientSecondaryAccountSyncTest() override {}
 
   void SetUpInProcessBrowserTestFixture() override {
-    fake_gaia_cookie_manager_factory_ =
-        secondary_account_helper::SetUpFakeGaiaCookieManagerService(
+    test_gaia_cookie_manager_factory_ =
+        secondary_account_helper::SetUpGaiaCookieManagerService(
             &test_url_loader_factory_);
   }
 
@@ -55,8 +55,8 @@
  private:
   base::test::ScopedFeatureList features_;
 
-  secondary_account_helper::ScopedFakeGaiaCookieManagerServiceFactory
-      fake_gaia_cookie_manager_factory_;
+  secondary_account_helper::ScopedGaiaCookieManagerServiceFactory
+      test_gaia_cookie_manager_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SingleClientSecondaryAccountSyncTest);
 };
@@ -79,7 +79,8 @@
 
   // Since standalone transport is disabled, just signing in (without making the
   // account Chrome's primary one) should *not* start the Sync machinery.
-  secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
+  secondary_account_helper::SignInSecondaryAccount(
+      profile(), &test_url_loader_factory_, "user@email.com");
   EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
             GetSyncService(0)->GetTransportState());
 }
@@ -103,7 +104,8 @@
   // Since secondary account support is disabled, just signing in (without
   // making the account Chrome's primary one) should *not* start the Sync
   // machinery.
-  secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
+  secondary_account_helper::SignInSecondaryAccount(
+      profile(), &test_url_loader_factory_, "user@email.com");
   EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
             GetSyncService(0)->GetTransportState());
 }
@@ -115,7 +117,8 @@
   // Signing in (without making the account Chrome's primary one or explicitly
   // setting up Sync) should trigger starting the Sync machinery in standalone
   // transport mode.
-  secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
+  secondary_account_helper::SignInSecondaryAccount(
+      profile(), &test_url_loader_factory_, "user@email.com");
   if (browser_defaults::kSyncAutoStarts) {
     EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING,
               GetSyncService(0)->GetTransportState());
@@ -152,7 +155,8 @@
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
   // Set up Sync in transport mode for a non-primary account.
-  secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
+  secondary_account_helper::SignInSecondaryAccount(
+      profile(), &test_url_loader_factory_, "user@email.com");
   ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
   ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
             GetSyncService(0)->GetTransportState());
diff --git a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
index 2bff3f38..edf5b2b 100644
--- a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
@@ -1071,8 +1071,8 @@
   ~SingleClientWalletSecondaryAccountSyncTest() override {}
 
   void SetUpInProcessBrowserTestFixture() override {
-    fake_gaia_cookie_manager_factory_ =
-        secondary_account_helper::SetUpFakeGaiaCookieManagerService(
+    test_gaia_cookie_manager_factory_ =
+        secondary_account_helper::SetUpGaiaCookieManagerService(
             &test_url_loader_factory_);
   }
 
@@ -1086,8 +1086,8 @@
   Profile* profile() { return GetProfile(0); }
 
  private:
-  secondary_account_helper::ScopedFakeGaiaCookieManagerServiceFactory
-      fake_gaia_cookie_manager_factory_;
+  secondary_account_helper::ScopedGaiaCookieManagerServiceFactory
+      test_gaia_cookie_manager_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SingleClientWalletSecondaryAccountSyncTest);
 };
@@ -1104,7 +1104,8 @@
       {CreateDefaultSyncWalletCard(), CreateDefaultSyncPaymentsCustomerData()});
 
   // Set up Sync in transport mode for a non-primary account.
-  secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
+  secondary_account_helper::SignInSecondaryAccount(
+      profile(), &test_url_loader_factory_, "user@email.com");
   ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
   ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
             GetSyncService(0)->GetTransportState());
@@ -1165,7 +1166,8 @@
   GetFakeServer()->SetWalletData({CreateDefaultSyncWalletCard()});
 
   // Set up Sync in transport mode for a non-primary account.
-  secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
+  secondary_account_helper::SignInSecondaryAccount(
+      profile(), &test_url_loader_factory_, "user@email.com");
   ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
   ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
             GetSyncService(0)->GetTransportState());
diff --git a/chrome/browser/sync/test/integration/sync_integration_test_util.cc b/chrome/browser/sync/test/integration/sync_integration_test_util.cc
index d9afa063..9fd987e 100644
--- a/chrome/browser/sync/test/integration/sync_integration_test_util.cc
+++ b/chrome/browser/sync/test/integration/sync_integration_test_util.cc
@@ -42,7 +42,7 @@
     : SingleClientStatusChangeChecker(service) {}
 
 bool PassphraseRequiredChecker::IsExitConditionSatisfied() {
-  return service()->IsPassphraseRequired();
+  return service()->GetUserSettings()->IsPassphraseRequired();
 }
 
 std::string PassphraseRequiredChecker::GetDebugMessage() const {
@@ -54,8 +54,8 @@
     : SingleClientStatusChangeChecker(service) {}
 
 bool PassphraseAcceptedChecker::IsExitConditionSatisfied() {
-  return !service()->IsPassphraseRequired() &&
-         service()->IsUsingSecondaryPassphrase();
+  return !service()->GetUserSettings()->IsPassphraseRequired() &&
+         service()->GetUserSettings()->IsUsingSecondaryPassphrase();
 }
 
 std::string PassphraseAcceptedChecker::GetDebugMessage() const {
diff --git a/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc b/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc
index 6275a98..3c55345 100644
--- a/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc
@@ -62,8 +62,9 @@
   EXPECT_FALSE(GetSyncService(kDecryptingClientId)
                    ->GetUserSettings()
                    ->SetDecryptionPassphrase("incorrect passphrase"));
-  EXPECT_TRUE(
-      GetSyncService(kDecryptingClientId)->IsPassphraseRequiredForDecryption());
+  EXPECT_TRUE(GetSyncService(kDecryptingClientId)
+                  ->GetUserSettings()
+                  ->IsPassphraseRequiredForDecryption());
 }
 
 IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest, ClientsCanSyncData) {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 3364625e..21ea97e 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1460,8 +1460,6 @@
       "ash/vpn_list_forwarder.h",
       "ash/wallpaper_controller_client.cc",
       "ash/wallpaper_controller_client.h",
-      "ash/wallpaper_policy_handler.cc",
-      "ash/wallpaper_policy_handler.h",
       "ash/window_properties.cc",
       "ash/window_properties.h",
       "browser_commands_chromeos.cc",
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index 06f3204..28e4d34b 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -1232,15 +1232,15 @@
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::make_unique<chromeos::FakeChromeUserManager>());
 
+    // Initialize the rest.
+    ChromeLauncherControllerTest::SetUp();
+
     // Initialize WallpaperControllerClient.
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
     wallpaper_controller_client_->InitForTesting(
         test_wallpaper_controller_.CreateInterfacePtr());
 
-    // Initialize the rest.
-    ChromeLauncherControllerTest::SetUp();
-
     // AvatarMenu and multiple profiles works after user logged in.
     profile_manager()->SetLoggedIn(true);
 
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index 345a218..b9bfa3f 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -33,8 +33,7 @@
     const base::FilePath& user_data_path,
     const base::FilePath& chromeos_wallpapers_path,
     const base::FilePath& chromeos_custom_wallpapers_path,
-    const base::FilePath& device_policy_wallpaper_path,
-    bool is_device_wallpaper_policy_enforced) {
+    const base::FilePath& device_policy_wallpaper_path) {
   was_client_set_ = true;
 }
 
@@ -88,7 +87,8 @@
   NOTIMPLEMENTED();
 }
 
-void TestWallpaperController::SetDeviceWallpaperPolicyEnforced(bool enforced) {
+void TestWallpaperController::SetDevicePolicyWallpaperPath(
+    const base::FilePath& device_policy_wallpaper_path) {
   NOTIMPLEMENTED();
 }
 
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index 69d26bee..9ae5e9a 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -39,8 +39,7 @@
             const base::FilePath& user_data_path,
             const base::FilePath& chromeos_wallpapers_path,
             const base::FilePath& chromeos_custom_wallpapers_path,
-            const base::FilePath& device_policy_wallpaper_path,
-            bool is_device_wallpaper_policy_enforced) override;
+            const base::FilePath& device_policy_wallpaper_path) override;
   void SetCustomWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& file_name,
@@ -70,7 +69,8 @@
   void SetPolicyWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& data) override;
-  void SetDeviceWallpaperPolicyEnforced(bool enforced) override;
+  void SetDevicePolicyWallpaperPath(
+      const base::FilePath& device_policy_wallpaper_path) override;
   void SetThirdPartyWallpaper(
       ash::mojom::WallpaperUserInfoPtr user_info,
       const std::string& wallpaper_files_id,
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.cc b/chrome/browser/ui/ash/wallpaper_controller_client.cc
index 251d7f82..b9f05c9 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.cc
@@ -9,6 +9,7 @@
 #include "base/path_service.h"
 #include "base/sha1.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/customization/customization_wallpaper_util.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
@@ -19,8 +20,10 @@
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/pref_names.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
+#include "chromeos/settings/cros_settings_names.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/user_manager/known_user.h"
 #include "components/user_manager/user_manager.h"
@@ -132,7 +135,15 @@
 }  // namespace
 
 WallpaperControllerClient::WallpaperControllerClient()
-    : policy_handler_(this), binding_(this), weak_factory_(this) {
+    : binding_(this), weak_factory_(this) {
+  local_state_ = g_browser_process->local_state();
+  show_user_names_on_signin_subscription_ =
+      chromeos::CrosSettings::Get()->AddSettingsObserver(
+          chromeos::kAccountsPrefShowUserNamesOnSignIn,
+          base::BindRepeating(
+              &WallpaperControllerClient::ShowWallpaperOnLoginScreen,
+              weak_factory_.GetWeakPtr()));
+
   DCHECK(!g_wallpaper_controller_client_instance);
   g_wallpaper_controller_client_instance = this;
 }
@@ -144,6 +155,12 @@
 }
 
 void WallpaperControllerClient::Init() {
+  pref_registrar_.Init(local_state_);
+  pref_registrar_.Add(
+      prefs::kDeviceWallpaperImageFilePath,
+      base::BindRepeating(
+          &WallpaperControllerClient::DeviceWallpaperImageFilePathChanged,
+          weak_factory_.GetWeakPtr()));
   content::ServiceManagerConnection::GetForProcess()
       ->GetConnector()
       ->BindInterface(ash::mojom::kServiceName, &wallpaper_controller_);
@@ -432,16 +449,9 @@
   wallpaper_controller_->ShouldShowWallpaperSetting(std::move(callback));
 }
 
-void WallpaperControllerClient::OnDeviceWallpaperChanged() {
-  wallpaper_controller_->SetDeviceWallpaperPolicyEnforced(true /*enforced=*/);
-}
-
-void WallpaperControllerClient::OnDeviceWallpaperPolicyCleared() {
-  wallpaper_controller_->SetDeviceWallpaperPolicyEnforced(false /*enforced=*/);
-}
-
-void WallpaperControllerClient::OnShowUserNamesOnLoginPolicyChanged() {
-  ShowWallpaperOnLoginScreen();
+void WallpaperControllerClient::DeviceWallpaperImageFilePathChanged() {
+  wallpaper_controller_->SetDevicePolicyWallpaperPath(
+      GetDeviceWallpaperImageFilePath());
 }
 
 void WallpaperControllerClient::FlushForTesting() {
@@ -462,11 +472,12 @@
   CHECK(base::PathService::Get(chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS,
                                &chromeos_custom_wallpapers_path));
 
+  base::FilePath device_policy_wallpaper_path =
+      GetDeviceWallpaperImageFilePath();
+
   wallpaper_controller_->Init(
       std::move(client), user_data_path, chromeos_wallpapers_path,
-      chromeos_custom_wallpapers_path,
-      policy_handler_.device_wallpaper_file_path(),
-      policy_handler_.IsDeviceWallpaperPolicyEnforced());
+      chromeos_custom_wallpapers_path, device_policy_wallpaper_path);
 }
 
 void WallpaperControllerClient::ShowWallpaperOnLoginScreen() {
@@ -478,7 +489,7 @@
   user_manager::User* public_session = FindPublicSession(users);
 
   // Show the default signin wallpaper if there's no user to display.
-  if ((!policy_handler_.ShouldShowUserNamesOnLogin() && !public_session) ||
+  if ((!ShouldShowUserNamesOnLogin() && !public_session) ||
       !HasNonDeviceLocalAccounts(users)) {
     ShowSigninWallpaper();
     return;
@@ -558,3 +569,15 @@
       content::NotificationService::AllSources(),
       content::NotificationService::NoDetails());
 }
+
+bool WallpaperControllerClient::ShouldShowUserNamesOnLogin() const {
+  bool show_user_names = true;
+  chromeos::CrosSettings::Get()->GetBoolean(
+      chromeos::kAccountsPrefShowUserNamesOnSignIn, &show_user_names);
+  return show_user_names;
+}
+
+base::FilePath WallpaperControllerClient::GetDeviceWallpaperImageFilePath() {
+  return base::FilePath(
+      local_state_->GetString(prefs::kDeviceWallpaperImageFilePath));
+}
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.h b/chrome/browser/ui/ash/wallpaper_controller_client.h
index 2c590ae..5c4e79e 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.h
@@ -5,16 +5,18 @@
 #ifndef CHROME_BROWSER_UI_ASH_WALLPAPER_CONTROLLER_CLIENT_H_
 #define CHROME_BROWSER_UI_ASH_WALLPAPER_CONTROLLER_CLIENT_H_
 
+#include <memory>
+
 #include "ash/public/cpp/wallpaper_types.h"
 #include "ash/public/interfaces/wallpaper.mojom.h"
 #include "base/macros.h"
-#include "chrome/browser/ui/ash/wallpaper_policy_handler.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "components/prefs/pref_change_registrar.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 // Handles method calls sent from ash to chrome. Also sends messages from chrome
 // to ash.
-class WallpaperControllerClient : public ash::mojom::WallpaperControllerClient,
-                                  public WallpaperPolicyHandler::Delegate {
+class WallpaperControllerClient : public ash::mojom::WallpaperControllerClient {
  public:
   WallpaperControllerClient();
   ~WallpaperControllerClient() override;
@@ -97,11 +99,6 @@
       ash::mojom::WallpaperController::ShouldShowWallpaperSettingCallback
           callback);
 
-  // chromeos::WallpaperPolicyHandler::Delegate:
-  void OnDeviceWallpaperChanged() override;
-  void OnDeviceWallpaperPolicyCleared() override;
-  void OnShowUserNamesOnLoginPolicyChanged() override;
-
   // Flushes the mojo pipe to ash.
   void FlushForTesting();
 
@@ -123,10 +120,27 @@
   void OnReadyToSetWallpaper() override;
   void OnFirstWallpaperAnimationFinished() override;
 
+  void DeviceWallpaperImageFilePathChanged();
+
+  // Returns true if user names should be shown on the login screen.
+  bool ShouldShowUserNamesOnLogin() const;
+
+  base::FilePath GetDeviceWallpaperImageFilePath();
+
   // WallpaperController interface in ash.
   ash::mojom::WallpaperControllerPtr wallpaper_controller_;
 
-  WallpaperPolicyHandler policy_handler_;
+  PrefService* local_state_;
+
+  // The registrar used to watch DeviceWallpaperImageFilePath pref changes.
+  PrefChangeRegistrar pref_registrar_;
+
+  // Observes if user names should be shown on the login screen, which
+  // determines whether a user wallpaper or a default wallpaper should be shown.
+  // TODO(wzang|784495): Views-based login should observe this and send
+  // different requests accordingly.
+  std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
+      show_user_names_on_signin_subscription_;
 
   // Binds to the client interface.
   mojo::Binding<ash::mojom::WallpaperControllerClient> binding_;
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc b/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc
index f71e972..14bea4c 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc
@@ -7,16 +7,20 @@
 #include "base/test/scoped_task_environment.h"
 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/ui/ash/test_wallpaper_controller.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
 
 class WallpaperControllerClientTest : public testing::Test {
  public:
-  WallpaperControllerClientTest() = default;
+  WallpaperControllerClientTest()
+      : local_state_(TestingBrowserProcess::GetGlobal()) {}
   ~WallpaperControllerClientTest() override = default;
 
  private:
+  ScopedTestingLocalState local_state_;
   chromeos::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
   base::test::ScopedTaskEnvironment scoped_task_environment_;
 
diff --git a/chrome/browser/ui/ash/wallpaper_policy_handler.cc b/chrome/browser/ui/ash/wallpaper_policy_handler.cc
deleted file mode 100644
index 836f827..0000000
--- a/chrome/browser/ui/ash/wallpaper_policy_handler.cc
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2017 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/wallpaper_policy_handler.h"
-
-#include "base/bind.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/task/post_task.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/customization/customization_wallpaper_downloader.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/common/chrome_paths.h"
-#include "chromeos/settings/cros_settings_names.h"
-#include "crypto/sha2.h"
-#include "url/gurl.h"
-
-using chromeos::CrosSettings;
-
-namespace {
-
-// The directory and file name to save the downloaded device policy wallpaper.
-constexpr char kDeviceWallpaperDir[] = "device_wallpaper";
-constexpr char kDeviceWallpaperFile[] = "device_wallpaper_image.jpg";
-
-// A helper function to check the existing/downloaded device wallpaper file's
-// hash value matches with the hash value provided in the policy settings.
-bool CheckWallpaperFileMatchHash(const base::FilePath& device_wallpaper_file,
-                                 const std::string& hash) {
-  std::string image_data;
-  if (base::ReadFileToString(device_wallpaper_file, &image_data)) {
-    std::string sha_hash = crypto::SHA256HashString(image_data);
-    if (base::ToLowerASCII(base::HexEncode(
-            sha_hash.c_str(), sha_hash.size())) == base::ToLowerASCII(hash)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace
-
-WallpaperPolicyHandler::WallpaperPolicyHandler(Delegate* delegate)
-    : delegate_(delegate), weak_factory_(this) {
-  DCHECK(delegate_);
-  device_wallpaper_image_subscription_ =
-      CrosSettings::Get()->AddSettingsObserver(
-          chromeos::kDeviceWallpaperImage,
-          base::BindRepeating(
-              &WallpaperPolicyHandler::DeviceWallpaperPolicyChanged,
-              weak_factory_.GetWeakPtr()));
-  show_user_names_on_signin_subscription_ =
-      chromeos::CrosSettings::Get()->AddSettingsObserver(
-          chromeos::kAccountsPrefShowUserNamesOnSignIn,
-          base::Bind(
-              &WallpaperPolicyHandler::ShowUserNamesOnSignInPolicyChanged,
-              weak_factory_.GetWeakPtr()));
-
-  // Initialize the desired file path for device policy wallpaper. The path will
-  // be used by WallpaperController to access the wallpaper file.
-  base::FilePath chromeos_wallpapers_path;
-  CHECK(base::PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS,
-                               &chromeos_wallpapers_path));
-  device_wallpaper_file_path_ =
-      chromeos_wallpapers_path.Append(kDeviceWallpaperDir)
-          .Append(kDeviceWallpaperFile);
-}
-
-WallpaperPolicyHandler::~WallpaperPolicyHandler() {
-  device_wallpaper_image_subscription_.reset();
-  show_user_names_on_signin_subscription_.reset();
-}
-
-bool WallpaperPolicyHandler::IsDeviceWallpaperPolicyEnforced() {
-  if (!g_browser_process->platform_part()
-           ->browser_policy_connector_chromeos()
-           ->IsEnterpriseManaged()) {
-    return false;
-  }
-
-  std::string url, hash;
-  return GetDeviceWallpaperPolicyStrings(&url, &hash);
-}
-
-bool WallpaperPolicyHandler::ShouldShowUserNamesOnLogin() {
-  bool show_user_names;
-  chromeos::CrosSettings::Get()->GetBoolean(
-      chromeos::kAccountsPrefShowUserNamesOnSignIn, &show_user_names);
-  return show_user_names;
-}
-
-bool WallpaperPolicyHandler::GetDeviceWallpaperPolicyStrings(
-    std::string* url,
-    std::string* hash) {
-  const base::DictionaryValue* dict = nullptr;
-  if (!CrosSettings::Get()->GetDictionary(chromeos::kDeviceWallpaperImage,
-                                          &dict) ||
-      !dict->GetStringWithoutPathExpansion("url", url) ||
-      !dict->GetStringWithoutPathExpansion("hash", hash)) {
-    return false;
-  }
-  return true;
-}
-
-void WallpaperPolicyHandler::DeviceWallpaperPolicyChanged() {
-  // First check if the device policy was cleared.
-  const base::DictionaryValue* dict = nullptr;
-  if (!CrosSettings::Get()->GetDictionary(chromeos::kDeviceWallpaperImage,
-                                          &dict)) {
-    // In this case delete the local device wallpaper file if it exists and
-    // inform its delegate.
-    base::PostTaskWithTraits(
-        FROM_HERE,
-        {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
-         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
-        base::BindOnce(base::IgnoreResult(&base::DeleteFile),
-                       device_wallpaper_file_path_, false /*=recursive*/));
-    delegate_->OnDeviceWallpaperPolicyCleared();
-    return;
-  }
-
-  // Check if the device wallpaper already exists and matches the new provided
-  // hash. Fetch the wallpaper from the provided url if it doesn't exist.
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::MayBlock()},
-      base::BindOnce(&base::PathExists, device_wallpaper_file_path_),
-      base::BindOnce(&WallpaperPolicyHandler::OnDeviceWallpaperFileExists,
-                     weak_factory_.GetWeakPtr()));
-}
-
-void WallpaperPolicyHandler::ShowUserNamesOnSignInPolicyChanged() {
-  delegate_->OnShowUserNamesOnLoginPolicyChanged();
-}
-
-void WallpaperPolicyHandler::OnDeviceWallpaperFileExists(bool exists) {
-  std::string url, hash;
-  if (!GetDeviceWallpaperPolicyStrings(&url, &hash)) {
-    // Do nothing if the strings can not be retrieved.
-    return;
-  }
-
-  if (exists) {
-    base::PostTaskWithTraitsAndReplyWithResult(
-        FROM_HERE, {base::MayBlock()},
-        base::BindOnce(&CheckWallpaperFileMatchHash,
-                       device_wallpaper_file_path_, hash),
-        base::BindOnce(
-            &WallpaperPolicyHandler::OnCheckExistingDeviceWallpaperMatchHash,
-            weak_factory_.GetWeakPtr(), url, hash));
-  } else {
-    GURL wallpaper_url(url);
-    device_wallpaper_downloader_.reset(
-        new chromeos::CustomizationWallpaperDownloader(
-            wallpaper_url, device_wallpaper_file_path_.DirName(),
-            device_wallpaper_file_path_,
-            base::BindRepeating(
-                &WallpaperPolicyHandler::OnDeviceWallpaperDownloaded,
-                weak_factory_.GetWeakPtr(), hash)));
-    device_wallpaper_downloader_->Start();
-  }
-}
-
-void WallpaperPolicyHandler::OnCheckExistingDeviceWallpaperMatchHash(
-    const std::string& url,
-    const std::string& hash,
-    bool match) {
-  if (match) {
-    // Notify its delegate that device wallpaper is ready.
-    delegate_->OnDeviceWallpaperChanged();
-    return;
-  }
-
-  GURL wallpaper_url(url);
-  device_wallpaper_downloader_.reset(
-      new chromeos::CustomizationWallpaperDownloader(
-          wallpaper_url, device_wallpaper_file_path_.DirName(),
-          device_wallpaper_file_path_,
-          base::BindRepeating(
-              &WallpaperPolicyHandler::OnDeviceWallpaperDownloaded,
-              weak_factory_.GetWeakPtr(), hash)));
-  device_wallpaper_downloader_->Start();
-}
-
-void WallpaperPolicyHandler::OnDeviceWallpaperDownloaded(
-    const std::string& hash,
-    bool success,
-    const GURL& url) {
-  // Do nothing if device wallpaper download failed.
-  if (!success)
-    return;
-
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::MayBlock()},
-      base::BindOnce(&CheckWallpaperFileMatchHash, device_wallpaper_file_path_,
-                     hash),
-      base::BindOnce(
-          &WallpaperPolicyHandler::OnCheckFetchedDeviceWallpaperMatchHash,
-          weak_factory_.GetWeakPtr()));
-}
-
-void WallpaperPolicyHandler::OnCheckFetchedDeviceWallpaperMatchHash(
-    bool match) {
-  // Do nothing if the provided hash doesn't match with the downloaded image.
-  if (!match)
-    return;
-
-  // Notify its delegate that device wallpaper is ready.
-  delegate_->OnDeviceWallpaperChanged();
-}
diff --git a/chrome/browser/ui/ash/wallpaper_policy_handler.h b/chrome/browser/ui/ash/wallpaper_policy_handler.h
deleted file mode 100644
index 31b1fa72..0000000
--- a/chrome/browser/ui/ash/wallpaper_policy_handler.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2017 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_WALLPAPER_POLICY_HANDLER_H_
-#define CHROME_BROWSER_UI_ASH_WALLPAPER_POLICY_HANDLER_H_
-
-#include "ash/public/interfaces/wallpaper.mojom.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "url/gurl.h"
-
-namespace chromeos {
-class CustomizationWallpaperDownloader;
-}  // namespace chromeos
-
-// This class observes changes of device policies related to wallpaper, such as
-// kDeviceWallpaperImage and kAccountsPrefShowUserNamesOnSignIn.
-//
-// It's responsible for downloading the new device policy controlled wallpaper
-// and saving it to local file system if the provided hash value matches the
-// downloaded wallpaper. It then notifies its delegate about the changes. The
-// delegate will decide if/when to set device policy controlled wallpaper.
-class WallpaperPolicyHandler {
- public:
-  // Delegate of WallpaperPolicyHandler.
-  class Delegate {
-   public:
-    virtual void OnDeviceWallpaperChanged() = 0;
-    virtual void OnDeviceWallpaperPolicyCleared() = 0;
-    virtual void OnShowUserNamesOnLoginPolicyChanged() = 0;
-
-   protected:
-    virtual ~Delegate() {}
-  };
-
-  explicit WallpaperPolicyHandler(Delegate* delegate);
-  ~WallpaperPolicyHandler();
-
-  // Returns true if the device wallpaper policy is currently in effect.
-  bool IsDeviceWallpaperPolicyEnforced();
-
-  // Returns true if user names should be shown on the login screen.
-  bool ShouldShowUserNamesOnLogin();
-
-  base::FilePath device_wallpaper_file_path() {
-    return device_wallpaper_file_path_;
-  }
-
- private:
-  // Gets the device policy controlled wallpaper's url and hash values. Returns
-  // false if the values can't be retrieved.
-  bool GetDeviceWallpaperPolicyStrings(std::string* url, std::string* hash);
-
-  // This is called whenever the device wallpaper policy changes.
-  void DeviceWallpaperPolicyChanged();
-
-  // Called when kAccountsPrefShowUserNamesOnSignIn changes.
-  void ShowUserNamesOnSignInPolicyChanged();
-
-  void OnDeviceWallpaperFileExists(bool exists);
-  void OnCheckExistingDeviceWallpaperMatchHash(const std::string& url,
-                                               const std::string& hash,
-                                               bool match);
-  void OnDeviceWallpaperDownloaded(const std::string& hash,
-                                   bool success,
-                                   const GURL& url);
-  void OnCheckFetchedDeviceWallpaperMatchHash(bool match);
-
-  base::FilePath device_wallpaper_file_path_;
-  Delegate* delegate_;
-
-  std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
-      device_wallpaper_image_subscription_;
-  std::unique_ptr<chromeos::CustomizationWallpaperDownloader>
-      device_wallpaper_downloader_;
-
-  // Observes if user names should be shown on the login screen, which
-  // determines whether a user wallpaper or a default wallpaper should be shown.
-  // TODO(wzang|784495): Views-based login should observe this and send
-  // different requests accordingly.
-  std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
-      show_user_names_on_signin_subscription_;
-
-  base::WeakPtrFactory<WallpaperPolicyHandler> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(WallpaperPolicyHandler);
-};
-
-#endif  // CHROME_BROWSER_UI_ASH_WALLPAPER_POLICY_HANDLER_H_
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
index 66f27be..8a4ebd8 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -101,7 +101,6 @@
   syncer::ModelTypeSet GetPreferredDataTypes() const override {
     return GetActiveDataTypes();
   }
-  bool IsUsingSecondaryPassphrase() const override { return false; }
 
   void set_synced_types(SyncedTypes synced_types) {
     synced_types_ = synced_types;
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
index 75f1e8f..0a6a9542 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
+++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -99,7 +99,7 @@
 
   DCHECK(primary_account_mutator_);
   primary_account_mutator_->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-      refresh_token, gaia_id, email, password,
+      refresh_token, gaia_id, email,
       base::BindOnce(&OneClickSigninSyncStarter::ConfirmSignin,
                      weak_pointer_factory_.GetWeakPtr(), profile_mode));
 }
diff --git a/chrome/browser/ui/sync/sync_promo_ui_unittest.cc b/chrome/browser/ui/sync/sync_promo_ui_unittest.cc
index 7fbee0a45..08c01016 100644
--- a/chrome/browser/ui/sync/sync_promo_ui_unittest.cc
+++ b/chrome/browser/ui/sync/sync_promo_ui_unittest.cc
@@ -11,8 +11,6 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "build/build_config.h"
-#include "chrome/browser/signin/fake_signin_manager_builder.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/browser_sync/browser_sync_switches.h"
@@ -27,9 +25,6 @@
   void SetUp() override {
     testing::Test::SetUp();
     TestingProfile::Builder builder;
-    builder.AddTestingFactory(
-        SigninManagerFactory::GetInstance(),
-        base::BindRepeating(&BuildFakeSigninManagerForTesting));
     profile_ = builder.Build();
   }
 
diff --git a/chrome/browser/ui/views/frame/test_with_browser_view.cc b/chrome/browser/ui/views/frame/test_with_browser_view.cc
index 9e8f1e11..1ad2154 100644
--- a/chrome/browser/ui/views/frame/test_with_browser_view.cc
+++ b/chrome/browser/ui/views/frame/test_with_browser_view.cc
@@ -27,7 +27,7 @@
 #include "components/omnibox/browser/test_scheme_classifier.h"
 #include "components/search_engines/search_terms_data.h"
 #include "components/search_engines/template_url_service.h"
-#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h"
+#include "components/signin/core/browser/list_accounts_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "services/network/test/test_url_loader_factory.h"
 
@@ -104,10 +104,7 @@
       profile, base::BindRepeating(&CreateAutocompleteClassifier));
 
   // Configure the GaiaCookieManagerService to return no accounts.
-  FakeGaiaCookieManagerService* gcms =
-      static_cast<FakeGaiaCookieManagerService*>(
-          GaiaCookieManagerServiceFactory::GetForProfile(profile));
-  gcms->SetListAccountsResponseHttpNotFound();
+  signin::SetListAccountsResponseHttpNotFound(test_url_loader_factory());
   return profile;
 }
 
@@ -119,6 +116,6 @@
 
 TestingProfile::TestingFactories TestWithBrowserView::GetTestingFactories() {
   return {{GaiaCookieManagerServiceFactory::GetInstance(),
-           base::BindRepeating(&BuildFakeGaiaCookieManagerServiceWithURLLoader,
+           base::BindRepeating(&BuildGaiaCookieManagerServiceWithURLLoader,
                                test_url_loader_factory())}};
 }
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
index df7a297..7f5455c9 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -34,8 +34,22 @@
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/grid_layout.h"
+#include "url/url_constants.h"
 
 namespace payments {
+namespace {
+
+base::string16 GetPaymentHandlerDialogTitle(
+    content::WebContents* web_contents,
+    const base::string16& https_prefix) {
+  return web_contents == nullptr ||
+                 base::StartsWith(web_contents->GetTitle(), https_prefix,
+                                  base::CompareCase::SENSITIVE)
+             ? base::string16()
+             : web_contents->GetTitle();
+}
+
+}  // namespace
 
 class ReadOnlyOriginView : public views::View {
  public:
@@ -144,7 +158,9 @@
           std::make_unique<views::ProgressBar>(/*preferred_height=*/2)),
       separator_(std::make_unique<views::Separator>()),
       first_navigation_complete_callback_(
-          std::move(first_navigation_complete_callback)) {
+          std::move(first_navigation_complete_callback)),
+      https_prefix_(base::UTF8ToUTF16(url::kHttpsScheme) +
+                    base::UTF8ToUTF16(url::kStandardSchemeSeparator)) {
   progress_bar_->set_owned_by_client();
   progress_bar_->set_foreground_color(gfx::kGoogleBlue500);
   progress_bar_->set_background_color(SK_ColorTRANSPARENT);
@@ -156,10 +172,7 @@
 PaymentHandlerWebFlowViewController::~PaymentHandlerWebFlowViewController() {}
 
 base::string16 PaymentHandlerWebFlowViewController::GetSheetTitle() {
-  if (web_contents())
-    return web_contents()->GetTitle();
-
-  return l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE);
+  return GetPaymentHandlerDialogTitle(web_contents(), https_prefix_);
 }
 
 void PaymentHandlerWebFlowViewController::FillContentView(
@@ -191,8 +204,8 @@
                           : target_.GetOrigin();
   std::unique_ptr<views::Background> background = GetHeaderBackground();
   return std::make_unique<ReadOnlyOriginView>(
-      web_contents() == nullptr ? base::string16() : web_contents()->GetTitle(),
-      origin, state()->selected_instrument()->icon_image_skia(),
+      GetPaymentHandlerDialogTitle(web_contents(), https_prefix_), origin,
+      state()->selected_instrument()->icon_image_skia(),
       background->get_color(), this);
 }
 
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
index b084d99..f2577ef 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
@@ -87,6 +87,7 @@
   std::unique_ptr<views::ProgressBar> progress_bar_;
   std::unique_ptr<views::Separator> separator_;
   PaymentHandlerOpenWindowCallback first_navigation_complete_callback_;
+  base::string16 https_prefix_;
 };
 
 }  // namespace payments
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
index b96017d1..e08e6c0 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
@@ -294,13 +294,11 @@
     GetCapabilityCallback callback,
     const base::DictionaryValue& capability) {
   base::Value capabilities(base::Value::Type::DICTIONARY);
-  std::unique_ptr<base::DictionaryValue> cdd =
-      ValidateCddForPrintPreview(capability);
+  base::Value cdd = ValidateCddForPrintPreview(capability.Clone());
   // Leave |capabilities| empty if |cdd| is empty.
-  if (!cdd->empty()) {
-    capabilities.SetKey(kSettingCapabilities,
-                        base::Value::FromUniquePtrValue(std::move(cdd)));
-  }
+  if (!cdd.DictEmpty())
+    capabilities.SetKey(kSettingCapabilities, std::move(cdd));
+
   std::move(callback).Run(std::move(capabilities));
 }
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
index d18bdd0a..7191e3c 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
@@ -110,37 +110,37 @@
 
 }  // namespace
 
-std::unique_ptr<base::DictionaryValue> ValidateCddForPrintPreview(
-    const base::DictionaryValue& cdd) {
-  auto validated_cdd =
-      base::DictionaryValue::From(base::Value::ToUniquePtrValue(cdd.Clone()));
-  const base::Value* caps = cdd.FindKey(kPrinter);
-  if (!caps || !caps->is_dict())
-    return validated_cdd;
-  validated_cdd->RemoveKey(kPrinter);
-  auto out_caps = std::make_unique<base::DictionaryValue>();
-  for (const auto& capability : caps->DictItems()) {
-    const auto& key = capability.first;
-    const base::Value& value = capability.second;
+base::Value ValidateCddForPrintPreview(base::Value cdd) {
+  base::Value* caps =
+      cdd.FindKeyOfType(kPrinter, base::Value::Type::DICTIONARY);
+  if (!caps)
+    return cdd;
 
-    const base::Value* list = nullptr;
-    if (value.is_dict())
-      list = value.FindKeyOfType(kOptionKey, base::Value::Type::LIST);
-    else if (value.is_list())
-      list = &value;
+  base::Value out_caps(base::Value::Type::DICTIONARY);
+  for (auto capability : caps->DictItems()) {
+    const auto& key = capability.first;
+    base::Value* value = &capability.second;
+
+    base::Value* list = nullptr;
+    if (value->is_dict())
+      list = value->FindKeyOfType(kOptionKey, base::Value::Type::LIST);
+    else if (value->is_list())
+      list = value;
+
     if (!list) {
-      out_caps->SetKey(key, value.Clone());
+      out_caps.SetKey(key, std::move(*value));
       continue;
     }
 
     bool is_vendor_capability = key == kVendorCapabilityKey;
-    base::Value out_list = GetFilteredList(
-        list, is_vendor_capability ? VendorCapabilityInvalid : ValueIsNull);
-    if (out_list.GetList().empty())  // leave out empty lists.
+    base::EraseIf(list->GetList(),
+                  is_vendor_capability ? VendorCapabilityInvalid : ValueIsNull);
+    if (list->GetList().empty())  // leave out empty lists.
       continue;
+
     if (is_vendor_capability) {
       // Need to also filter the individual capability lists.
-      for (auto& vendor_option : out_list.GetList()) {
+      for (auto& vendor_option : list->GetList()) {
         const base::Value* option_type =
             vendor_option.FindKeyOfType(kTypeKey, base::Value::Type::STRING);
         if (option_type->GetString() != kSelectString)
@@ -148,22 +148,21 @@
 
         base::Value* options_dict = vendor_option.FindKeyOfType(
             kSelectCapKey, base::Value::Type::DICTIONARY);
-        const base::Value* options_list =
+        base::Value* options_list =
             options_dict->FindKeyOfType(kOptionKey, base::Value::Type::LIST);
-        options_dict->SetKey(kOptionKey,
-                             GetFilteredList(options_list, ValueIsNull));
+        base::EraseIf(options_list->GetList(), ValueIsNull);
       }
     }
-    if (value.is_dict()) {
+    if (value->is_dict()) {
       base::Value option_dict(base::Value::Type::DICTIONARY);
-      option_dict.SetKey(kOptionKey, std::move(out_list));
-      out_caps->SetKey(key, std::move(option_dict));
+      option_dict.SetKey(kOptionKey, std::move(*list));
+      out_caps.SetKey(key, std::move(option_dict));
     } else {
-      out_caps->SetKey(key, std::move(out_list));
+      out_caps.SetKey(key, std::move(*list));
     }
   }
-  validated_cdd->SetDictionary(kPrinter, std::move(out_caps));
-  return validated_cdd;
+  cdd.SetKey(kPrinter, std::move(out_caps));
+  return cdd;
 }
 
 void ConvertPrinterListForCallback(
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_utils.h b/chrome/browser/ui/webui/print_preview/print_preview_utils.h
index ed8a23fa..4ebe961 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_utils.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_utils.h
@@ -34,11 +34,10 @@
     PrinterHandler::GetPrintersDoneCallback done_callback,
     const PrinterList& printer_list);
 
-// Returns a unique_ptr to a sanitized version of |cdd| to prevent possible JS
+// Returns a sanitized version of |cdd| to prevent possible JS
 // errors in Print Preview. Will remove null items from lists or options lists
 // and remove any lists/options that are empty or only contain null values.
-std::unique_ptr<base::DictionaryValue> ValidateCddForPrintPreview(
-    const base::DictionaryValue& cdd);
+base::Value ValidateCddForPrintPreview(base::Value cdd);
 
 // Starts a local print of |print_data| with print settings dictionary
 // |job_settings|. Runs |callback| on failure or success.
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_utils_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_utils_unittest.cc
index ed32d2a..2fed881 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_utils_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_utils_unittest.cc
@@ -189,7 +189,7 @@
   }
 }
 
-void ValidatePrinter(const base::DictionaryValue* cdd_out,
+void ValidatePrinter(const base::Value* cdd_out,
                      const base::DictionaryValue& printer) {
   const base::Value* printer_out =
       cdd_out->FindKeyOfType(kPrinter, base::Value::Type::DICTIONARY);
@@ -217,8 +217,8 @@
   base::DictionaryValue printer = GetCapabilitiesFull();
   base::DictionaryValue cdd;
   cdd.SetKey(kPrinter, printer.Clone());
-  auto cdd_out = ValidateCddForPrintPreview(cdd);
-  ValidatePrinter(cdd_out.get(), printer);
+  auto cdd_out = ValidateCddForPrintPreview(std::move(cdd));
+  ValidatePrinter(&cdd_out, printer);
 }
 
 TEST_F(PrintPreviewUtilsTest, FilterBadList) {
@@ -230,8 +230,8 @@
   printer.SetKey(kMediaSizes, base::Value(list_media));
   base::DictionaryValue cdd;
   cdd.SetKey(kPrinter, printer.Clone());
-  auto cdd_out = ValidateCddForPrintPreview(cdd);
-  ValidatePrinter(cdd_out.get(), printer);
+  auto cdd_out = ValidateCddForPrintPreview(std::move(cdd));
+  ValidatePrinter(&cdd_out, printer);
 }
 
 TEST_F(PrintPreviewUtilsTest, FilterBadOptionOneElement) {
@@ -245,8 +245,8 @@
   printer.SetKey(kDpi, std::move(options));
   base::DictionaryValue cdd;
   cdd.SetKey(kPrinter, printer.Clone());
-  auto cdd_out = ValidateCddForPrintPreview(cdd);
-  ValidatePrinter(cdd_out.get(), printer);
+  auto cdd_out = ValidateCddForPrintPreview(std::move(cdd));
+  ValidatePrinter(&cdd_out, printer);
 }
 
 TEST_F(PrintPreviewUtilsTest, FilterBadOptionAllElement) {
@@ -260,8 +260,8 @@
   printer.SetKey(kDpi, std::move(options));
   base::DictionaryValue cdd;
   cdd.SetKey(kPrinter, printer.Clone());
-  auto cdd_out = ValidateCddForPrintPreview(cdd);
-  ValidatePrinter(cdd_out.get(), printer);
+  auto cdd_out = ValidateCddForPrintPreview(std::move(cdd));
+  ValidatePrinter(&cdd_out, printer);
 }
 
 TEST_F(PrintPreviewUtilsTest, FilterBadVendorCapabilityAllElement) {
@@ -277,8 +277,8 @@
   select_cap_0->SetKey(kOptionKey, base::Value(option_list));
   base::DictionaryValue cdd;
   cdd.SetKey(kPrinter, printer.Clone());
-  auto cdd_out = ValidateCddForPrintPreview(cdd);
-  ValidatePrinter(cdd_out.get(), printer);
+  auto cdd_out = ValidateCddForPrintPreview(std::move(cdd));
+  ValidatePrinter(&cdd_out, printer);
 }
 
 TEST_F(PrintPreviewUtilsTest, FilterBadVendorCapabilityOneElement) {
@@ -305,8 +305,8 @@
 
   base::DictionaryValue cdd;
   cdd.SetKey(kPrinter, printer.Clone());
-  auto cdd_out = ValidateCddForPrintPreview(cdd);
-  ValidatePrinter(cdd_out.get(), printer);
+  auto cdd_out = ValidateCddForPrintPreview(std::move(cdd));
+  ValidatePrinter(&cdd_out, printer);
 }
 
 }  // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc b/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc
index 31e0f25..87ad1eb 100644
--- a/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc
@@ -191,7 +191,7 @@
   printer_info_and_caps.SetDictionary(kSettingCapabilities,
                                       std::move(capabilities_copy));
   std::move(capabilities_callback_)
-      .Run(std::move(*ValidateCddForPrintPreview(printer_info_and_caps)));
+      .Run(ValidateCddForPrintPreview(std::move(printer_info_and_caps)));
   privet_capabilities_operation_.reset();
 }
 
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 8f7248f..5e01286 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -1544,11 +1544,12 @@
                                                profile->GetPrefs()) != 0);
 
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
+      ProfileSyncServiceFactory::GetSyncServiceForProfile(profile);
   if (sync_service && sync_service->CanSyncFeatureStart() &&
       sync_service->GetPreferredDataTypes().Has(syncer::AUTOFILL_PROFILE)) {
-    html_source->AddBoolean("isUsingSecondaryPassphrase",
-                            sync_service->IsUsingSecondaryPassphrase());
+    html_source->AddBoolean(
+        "isUsingSecondaryPassphrase",
+        sync_service->GetUserSettings()->IsUsingSecondaryPassphrase());
     html_source->AddBoolean(
         "uploadToGoogleActive",
         syncer::GetUploadToGoogleState(
@@ -1888,8 +1889,6 @@
   }
 #endif
 
-  html_source->AddString("syncErrorHelpUrl", chrome::kSyncErrorsHelpURL);
-
   html_source->AddString("activityControlsUrl",
                          chrome::kGoogleAccountActivityControlsURL);
 
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index 4b906465..c8b09336 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -12,6 +12,7 @@
 #include "base/i18n/time_formatting.h"
 #include "base/json/json_reader.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
@@ -1023,12 +1024,15 @@
   if (!passphrase_time.is_null()) {
     base::string16 passphrase_time_str =
         base::TimeFormatShortDate(passphrase_time);
-    args.SetString("enterPassphraseBody",
-                   GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
-                                   passphrase_time_str));
+    args.SetString(
+        "enterPassphraseBody",
+        GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
+                        base::ASCIIToUTF16(chrome::kSyncErrorsHelpURL),
+                        passphrase_time_str));
     args.SetString(
         "enterGooglePassphraseBody",
         GetStringFUTF16(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
+                        base::ASCIIToUTF16(chrome::kSyncErrorsHelpURL),
                         passphrase_time_str));
     switch (passphrase_type) {
       case syncer::PassphraseType::FROZEN_IMPLICIT_PASSPHRASE:
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index e7ef619..5a30b61e 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -913,6 +913,10 @@
 const char kMostRecentlyUsedNetworkFileShareURL[] =
     "network_file_shares.most_recently_used_url";
 
+// A string pref storing the path of device wallpaper image file.
+const char kDeviceWallpaperImageFilePath[] =
+    "policy.device_wallpaper_image_file_path";
+
 #endif  // defined(OS_CHROMEOS)
 
 // A boolean pref set to true if a Home button to open the Home pages should be
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 3ebba0b..ea42e89a 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -290,6 +290,7 @@
 extern const char kNetworkFileSharesPreconfiguredShares[];
 extern const char kMostRecentlyUsedNetworkFileShareURL[];
 extern const char kParentAccessCodeConfig[];
+extern const char kDeviceWallpaperImageFilePath[];
 #endif  // defined(OS_CHROMEOS)
 extern const char kShowHomeButton[];
 extern const char kSpeechRecognitionFilterProfanities[];
diff --git a/components/OWNERS b/components/OWNERS
index 50c10c4..d2fb0cf 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -11,7 +11,7 @@
 per-file crash_strings.grdp=file://components/crash/OWNERS
 per-file dom_distiller_strings.grdp=file://components/dom_distiller/OWNERS
 per-file error_page_strings.grdp=file://components/error_page/OWNERS
-per-file management_strings.grdp=file://components/policy/OWNERS
+per-file management_strings.grdp=file://docs/privacy/OWNERS
 per-file ntp_snippets_strings.grdp=file://components/ntp_snippets/OWNERS
 per-file omnibox_strings.grdp=file://components/omnibox/OWNERS
 per-file page_info_strings.grdp=file://chrome/browser/ui/page_info/OWNERS
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc
index 13e96eb..ffc1f9c 100644
--- a/components/autofill/core/browser/autofill_experiments.cc
+++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -20,6 +20,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_service_utils.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/variations/variations_associated_data.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "google_apis/gaia/google_service_auth_error.h"
@@ -70,7 +71,7 @@
   // Users who have enabled a passphrase have chosen to not make their sync
   // information accessible to Google. Since upload makes credit card data
   // available to other Google systems, disable it for passphrase users.
-  if (sync_service->IsUsingSecondaryPassphrase())
+  if (sync_service->GetUserSettings()->IsUsingSecondaryPassphrase())
     return false;
 
   // Don't offer upload for users that are only syncing locally, since they
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index 845b39ac..4baaf2a 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -1223,7 +1223,8 @@
 
   // We should never get in a state where we have no encrypted datatypes
   // enabled, and yet we still think we require a passphrase for decryption.
-  DCHECK(!IsPassphraseRequiredForDecryption() || IsEncryptedDatatypeEnabled());
+  DCHECK(!GetUserSettings()->IsPassphraseRequiredForDecryption() ||
+         IsEncryptedDatatypeEnabled());
 
   // Notify listeners that configuration is done.
   for (auto& observer : observers_)
@@ -1330,14 +1331,6 @@
   return user_settings_->IsPassphraseRequired();
 }
 
-bool ProfileSyncService::IsPassphraseRequiredForDecryption() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // If there is an encrypted datatype enabled and we don't have the proper
-  // passphrase, we must prompt the user for a passphrase. The only way for the
-  // user to avoid entering their passphrase is to disable the encrypted types.
-  return IsEncryptedDatatypeEnabled() && IsPassphraseRequired();
-}
-
 base::Time ProfileSyncService::GetLastSyncedTime() const {
   return sync_prefs_.GetLastSyncedTime();
 }
@@ -1411,11 +1404,6 @@
   return data_type_manager_->GetActiveDataTypes();
 }
 
-bool ProfileSyncService::IsUsingSecondaryPassphrase() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return user_settings_->IsUsingSecondaryPassphrase();
-}
-
 void ProfileSyncService::SyncAllowedByPlatformChanged(bool allowed) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
@@ -1478,7 +1466,7 @@
     if (base::FeatureList::IsEnabled(
             autofill::features::kAutofillEnableAccountWalletStorage) &&
         base::FeatureList::IsEnabled(switches::kSyncUSSAutofillWalletData)) {
-      if (!IsUsingSecondaryPassphrase() ||
+      if (!GetUserSettings()->IsUsingSecondaryPassphrase() ||
           base::FeatureList::IsEnabled(
               switches::
                   kSyncAllowWalletDataInTransportModeWithCustomPassphrase)) {
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h
index 83e22ca7..710e157 100644
--- a/components/browser_sync/profile_sync_service.h
+++ b/components/browser_sync/profile_sync_service.h
@@ -204,8 +204,6 @@
   void AddObserver(syncer::SyncServiceObserver* observer) override;
   void RemoveObserver(syncer::SyncServiceObserver* observer) override;
   bool HasObserver(const syncer::SyncServiceObserver* observer) const override;
-  bool IsPassphraseRequiredForDecryption() const override;
-  bool IsUsingSecondaryPassphrase() const override;
   syncer::UserShare* GetUserShare() const override;
   syncer::SyncTokenStatus GetSyncTokenStatus() const override;
   bool QueryDetailedSyncStatus(syncer::SyncStatus* result) const override;
diff --git a/components/browser_sync/profile_sync_service_mock.cc b/components/browser_sync/profile_sync_service_mock.cc
index 8c0004d..2e2c1d4 100644
--- a/components/browser_sync/profile_sync_service_mock.cc
+++ b/components/browser_sync/profile_sync_service_mock.cc
@@ -37,14 +37,6 @@
       user_settings_.GetChosenDataTypes());
 }
 
-bool ProfileSyncServiceMock::IsPassphraseRequiredForDecryption() const {
-  return user_settings_.IsPassphraseRequiredForDecryption();
-}
-
-bool ProfileSyncServiceMock::IsUsingSecondaryPassphrase() const {
-  return user_settings_.IsUsingSecondaryPassphrase();
-}
-
 std::unique_ptr<syncer::SyncSetupInProgressHandle>
 ProfileSyncServiceMock::GetSetupInProgressHandleConcrete() {
   return browser_sync::ProfileSyncService::GetSetupInProgressHandle();
diff --git a/components/browser_sync/profile_sync_service_mock.h b/components/browser_sync/profile_sync_service_mock.h
index be370f65..5ac4ce0 100644
--- a/components/browser_sync/profile_sync_service_mock.h
+++ b/components/browser_sync/profile_sync_service_mock.h
@@ -49,9 +49,6 @@
   MOCK_METHOD1(AddObserver, void(syncer::SyncServiceObserver*));
   MOCK_METHOD1(RemoveObserver, void(syncer::SyncServiceObserver*));
 
-  bool IsPassphraseRequiredForDecryption() const override;
-  bool IsUsingSecondaryPassphrase() const override;
-
   MOCK_CONST_METHOD0(GetUserShare, syncer::UserShare*());
 
   MOCK_CONST_METHOD1(QueryDetailedSyncStatus,
diff --git a/components/browsing_data/core/history_notice_utils.cc b/components/browsing_data/core/history_notice_utils.cc
index 0254b5a..379df8e8 100644
--- a/components/browsing_data/core/history_notice_utils.cc
+++ b/components/browsing_data/core/history_notice_utils.cc
@@ -12,6 +12,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/history/core/browser/web_history_service.h"
 #include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/version_info/version_info.h"
 
 namespace {
@@ -60,7 +61,8 @@
   if (!sync_service || !sync_service->IsSyncFeatureActive() ||
       !sync_service->GetActiveDataTypes().Has(
           syncer::HISTORY_DELETE_DIRECTIVES) ||
-      sync_service->IsUsingSecondaryPassphrase() || !history_service) {
+      sync_service->GetUserSettings()->IsUsingSecondaryPassphrase() ||
+      !history_service) {
     callback.Run(false);
     return;
   }
@@ -101,7 +103,8 @@
   if (!sync_service || !sync_service->IsSyncFeatureActive() ||
       !sync_service->GetActiveDataTypes().Has(
           syncer::HISTORY_DELETE_DIRECTIVES) ||
-      sync_service->IsUsingSecondaryPassphrase() || !history_service) {
+      sync_service->GetUserSettings()->IsUsingSecondaryPassphrase() ||
+      !history_service) {
     callback.Run(false);
     return;
   }
diff --git a/components/chrome_cleaner/public/constants/result_codes.h b/components/chrome_cleaner/public/constants/result_codes.h
index 0a48fff..8993f81 100644
--- a/components/chrome_cleaner/public/constants/result_codes.h
+++ b/components/chrome_cleaner/public/constants/result_codes.h
@@ -227,6 +227,16 @@
   // result, we don't allow it.
   RESULT_CODE_WRONG_ARCHITECTURE = 56,
 
+  // The process failed to complete in a reasonable amount of time and our
+  // watchdog terminated the process. At that time the engine was scanning the
+  // registry.
+  RESULT_CODE_WATCHDOG_TIMEOUT_WHILE_SCANNING_REGISTRY = 57,
+
+  // The process failed to complete in a reasonable amount of time and our
+  // watchdog terminated the process. At that time the engine was scanning the
+  // file system.
+  RESULT_CODE_WATCHDOG_TIMEOUT_WHILE_SCANNING_FILES = 58,
+
   // WHEN YOU ADD NEW EXIT CODES, DON'T FORGET TO UPDATE THE MONITORING RULES.
   // See http://go/chrome-cleaner-exit-codes. (Google internal only - external
   // contributors please ask one of the OWNERS to do the update.)
diff --git a/components/invalidation/impl/fcm_invalidation_listener.cc b/components/invalidation/impl/fcm_invalidation_listener.cc
index ec0e30d5..9eade211 100644
--- a/components/invalidation/impl/fcm_invalidation_listener.cc
+++ b/components/invalidation/impl/fcm_invalidation_listener.cc
@@ -168,9 +168,10 @@
 }
 
 void FCMInvalidationListener::RequestDetailedStatus(
-    base::Callback<void(const base::DictionaryValue&)> callback) const {
+    const base::RepeatingCallback<void(const base::DictionaryValue&)>& callback)
+    const {
   network_channel_->RequestDetailedStatus(callback);
-  callback.Run(*CollectDebugData());
+  callback.Run(CollectDebugData());
 }
 
 void FCMInvalidationListener::StopForTest() {
@@ -240,21 +241,19 @@
   EmitStateChange();
 }
 
-std::unique_ptr<base::DictionaryValue>
-FCMInvalidationListener::CollectDebugData() const {
-  std::unique_ptr<base::DictionaryValue> return_value =
+base::DictionaryValue FCMInvalidationListener::CollectDebugData() const {
+  base::DictionaryValue status =
       per_user_topic_registration_manager_->CollectDebugData();
-  return_value->SetString("FCM channel state",
-                          InvalidatorStateToString(fcm_network_state_));
-  return_value->SetString(
-      "Subscription channel state",
-      InvalidatorStateToString(subscription_channel_state_));
+  status.SetString("InvalidationListener.FCM-channel-state",
+                   InvalidatorStateToString(fcm_network_state_));
+  status.SetString("InvalidationListener.Subscription-channel-state",
+                   InvalidatorStateToString(subscription_channel_state_));
   for (const Topic& topic : registered_topics_) {
-    if (!return_value->HasKey(topic)) {
-      return_value->SetString(topic, "Unregistered");
+    if (!status.HasKey(topic)) {
+      status.SetString(topic, "Unregistered");
     }
   }
-  return return_value;
+  return status;
 }
 
 }  // namespace syncer
diff --git a/components/invalidation/impl/fcm_invalidation_listener.h b/components/invalidation/impl/fcm_invalidation_listener.h
index 66e57e990..ed04fcf 100644
--- a/components/invalidation/impl/fcm_invalidation_listener.h
+++ b/components/invalidation/impl/fcm_invalidation_listener.h
@@ -92,7 +92,8 @@
   void DoRegistrationUpdate();
 
   void RequestDetailedStatus(
-      base::Callback<void(const base::DictionaryValue&)> callback) const;
+      const base::RepeatingCallback<void(const base::DictionaryValue&)>&
+          callback) const;
 
   void StopForTest();
 
@@ -126,7 +127,7 @@
   void EmitSavedInvalidations(const TopicInvalidationMap& to_emit);
 
   // Generate a Dictionary with all the debugging information.
-  std::unique_ptr<base::DictionaryValue> CollectDebugData() const;
+  base::DictionaryValue CollectDebugData() const;
 
   std::unique_ptr<FCMSyncNetworkChannel> network_channel_;
   UnackedInvalidationsMap unacked_invalidations_map_;
diff --git a/components/invalidation/impl/fcm_invalidation_service.cc b/components/invalidation/impl/fcm_invalidation_service.cc
index 96b3f947..ac78e9f 100644
--- a/components/invalidation/impl/fcm_invalidation_service.cc
+++ b/components/invalidation/impl/fcm_invalidation_service.cc
@@ -127,7 +127,8 @@
 void FCMInvalidationService::RequestDetailedStatus(
     base::RepeatingCallback<void(const base::DictionaryValue&)> return_callback)
     const {
-  return_callback.Run(*diagnostic_info_.CollectDebugData());
+  return_callback.Run(diagnostic_info_.CollectDebugData());
+  invalidator_registrar_.RequestDetailedStatus(return_callback);
   if (IsStarted()) {
     invalidator_->RequestDetailedStatus(return_callback);
   }
@@ -258,27 +259,25 @@
 
 FCMInvalidationService::Diagnostics::Diagnostics() {}
 
-std::unique_ptr<base::DictionaryValue>
-FCMInvalidationService::Diagnostics::CollectDebugData() const {
-  std::unique_ptr<base::DictionaryValue> status =
-      std::make_unique<base::DictionaryValue>();
+base::DictionaryValue FCMInvalidationService::Diagnostics::CollectDebugData()
+    const {
+  base::DictionaryValue status;
 
-  status->SetString("Active account login",
-                    base::TimeFormatShortDateAndTime(active_account_login));
-  status->SetString(
-      "Active account token updated",
+  status.SetString("InvalidationService.Active-account-login",
+                   base::TimeFormatShortDateAndTime(active_account_login));
+  status.SetString(
+      "InvalidationService.Active-account-token-updated",
       base::TimeFormatShortDateAndTime(active_account_token_updated));
-  status->SetString(
-      "Active account logged out",
-      base::TimeFormatShortDateAndTime(active_account_logged_out));
-  status->SetString("Instance id requested",
-                    base::TimeFormatShortDateAndTime(instance_id_requested));
-  status->SetString("Instance id received",
-                    base::TimeFormatShortDateAndTime(instance_id_received));
-  status->SetString("Service was stopped",
-                    base::TimeFormatShortDateAndTime(service_was_stopped));
-  status->SetString("Service was started",
-                    base::TimeFormatShortDateAndTime(service_was_started));
+  status.SetString("InvalidationService.Active-account-logged-out",
+                   base::TimeFormatShortDateAndTime(active_account_logged_out));
+  status.SetString("InvalidationService.IID-requested",
+                   base::TimeFormatShortDateAndTime(instance_id_requested));
+  status.SetString("InvalidationService.IID-received",
+                   base::TimeFormatShortDateAndTime(instance_id_received));
+  status.SetString("InvalidationService.Service-stopped",
+                   base::TimeFormatShortDateAndTime(service_was_stopped));
+  status.SetString("InvalidationService.Service-started",
+                   base::TimeFormatShortDateAndTime(service_was_started));
   return status;
 }
 
diff --git a/components/invalidation/impl/fcm_invalidation_service.h b/components/invalidation/impl/fcm_invalidation_service.h
index 465a265..5c24a36 100644
--- a/components/invalidation/impl/fcm_invalidation_service.h
+++ b/components/invalidation/impl/fcm_invalidation_service.h
@@ -86,7 +86,7 @@
     Diagnostics();
 
     // Collect all the internal variables in a single readable dictionary.
-    std::unique_ptr<base::DictionaryValue> CollectDebugData() const;
+    base::DictionaryValue CollectDebugData() const;
 
     base::Time active_account_login;
     base::Time active_account_token_updated;
diff --git a/components/invalidation/impl/fcm_network_handler.cc b/components/invalidation/impl/fcm_network_handler.cc
index c673286..9f9fef6 100644
--- a/components/invalidation/impl/fcm_network_handler.cc
+++ b/components/invalidation/impl/fcm_network_handler.cc
@@ -244,33 +244,34 @@
 
 void FCMNetworkHandler::RequestDetailedStatus(
     base::Callback<void(const base::DictionaryValue&)> callback) {
-  callback.Run(*diagnostic_info_.CollectDebugData());
+  callback.Run(diagnostic_info_.CollectDebugData());
 }
 
 FCMNetworkHandlerDiagnostic::FCMNetworkHandlerDiagnostic() {}
 
-std::unique_ptr<base::DictionaryValue>
-FCMNetworkHandlerDiagnostic::CollectDebugData() const {
-  std::unique_ptr<base::DictionaryValue> status(new base::DictionaryValue);
-  status->SetString("Registration result code",
-                    RegistrationResultToString(registration_result));
-  status->SetString("Token", token);
-  status->SetString(
-      "When token was requested",
+base::DictionaryValue FCMNetworkHandlerDiagnostic::CollectDebugData() const {
+  base::DictionaryValue status;
+  status.SetString("NetworkHandler.Registration-result-code",
+                   RegistrationResultToString(registration_result));
+  status.SetString("NetworkHandler.Token", token);
+  status.SetString(
+      "NetworkHandler.Token-was-requested",
       base::TimeFormatShortDateAndTime(instance_id_token_requested));
-  status->SetString(
-      "When Token was received",
+  status.SetString(
+      "NetworkHandler.Token-was-received",
       base::TimeFormatShortDateAndTime(instance_id_token_was_received));
-  status->SetString("When token verification started",
-                    base::TimeFormatShortDateAndTime(
-                        instance_id_token_verification_requested));
-  status->SetString("When token was verified", base::TimeFormatShortDateAndTime(
-                                                   instance_id_token_verified));
-  status->SetString("Verification result code",
-                    RegistrationResultToString(token_verification_result));
-  status->SetBoolean("Token change when verified", token_changed);
-  status->SetInteger("Token validation requests",
-                     token_validation_requested_num);
+  status.SetString("NetworkHandler.Token-verification-started",
+                   base::TimeFormatShortDateAndTime(
+                       instance_id_token_verification_requested));
+  status.SetString(
+      "NetworkHandler.Token-was-verified",
+      base::TimeFormatShortDateAndTime(instance_id_token_verified));
+  status.SetString("NetworkHandler.Verification-result-code",
+                   RegistrationResultToString(token_verification_result));
+  status.SetBoolean("NetworkHandler.Token-changed-when-verified",
+                    token_changed);
+  status.SetInteger("NetworkHandler.Token-validation-requests",
+                    token_validation_requested_num);
   return status;
 }
 
diff --git a/components/invalidation/impl/fcm_network_handler.h b/components/invalidation/impl/fcm_network_handler.h
index 9a9f2db2..4c283de 100644
--- a/components/invalidation/impl/fcm_network_handler.h
+++ b/components/invalidation/impl/fcm_network_handler.h
@@ -28,7 +28,7 @@
   FCMNetworkHandlerDiagnostic();
 
   // Collect all the internal variables in a single readable dictionary.
-  std::unique_ptr<base::DictionaryValue> CollectDebugData() const;
+  base::DictionaryValue CollectDebugData() const;
 
   std::string RegistrationResultToString(
       const instance_id::InstanceID::Result result) const;
diff --git a/components/invalidation/impl/invalidator_registrar_with_memory.cc b/components/invalidation/impl/invalidator_registrar_with_memory.cc
index 3bd24df5..7596d09b 100644
--- a/components/invalidation/impl/invalidator_registrar_with_memory.cc
+++ b/components/invalidation/impl/invalidator_registrar_with_memory.cc
@@ -6,6 +6,7 @@
 
 #include <cstddef>
 #include <iterator>
+#include <string>
 #include <utility>
 
 #include "base/logging.h"
@@ -79,4 +80,24 @@
   return registered_topics;
 }
 
+void InvalidatorRegistrarWithMemory::RequestDetailedStatus(
+    base::RepeatingCallback<void(const base::DictionaryValue&)> callback)
+    const {
+  callback.Run(CollectDebugData());
+}
+
+base::DictionaryValue InvalidatorRegistrarWithMemory::CollectDebugData() const {
+  base::DictionaryValue return_value;
+  return_value.SetInteger("InvalidatorRegistrarWithMemory.Handlers",
+                          handler_name_to_topics_map_.size());
+  for (const auto& handler_to_topics : handler_name_to_topics_map_) {
+    const std::string& handler = handler_to_topics.first;
+    for (const auto& topic : handler_to_topics.second) {
+      return_value.SetString("InvalidatorRegistrarWithMemory." + topic,
+                             handler);
+    }
+  }
+  return return_value;
+}
+
 }  // namespace syncer
diff --git a/components/invalidation/impl/invalidator_registrar_with_memory.h b/components/invalidation/impl/invalidator_registrar_with_memory.h
index a00e421f..c3eb971 100644
--- a/components/invalidation/impl/invalidator_registrar_with_memory.h
+++ b/components/invalidation/impl/invalidator_registrar_with_memory.h
@@ -53,7 +53,14 @@
   // handlers that have been unregistered).
   TopicSet GetAllRegisteredIds() const override;
 
+  void RequestDetailedStatus(
+      base::RepeatingCallback<void(const base::DictionaryValue&)> callback)
+      const;
+
  private:
+  // Generate a Dictionary with all the debugging information.
+  base::DictionaryValue CollectDebugData() const;
+
   std::unordered_map<std::string, InvalidationHandler*>
       handler_name_to_handler_;
   HandlerNameTopicsMap handler_name_to_topics_map_;
diff --git a/components/invalidation/impl/per_user_topic_registration_manager.cc b/components/invalidation/impl/per_user_topic_registration_manager.cc
index 2e7f05a..420959ee 100644
--- a/components/invalidation/impl/per_user_topic_registration_manager.cc
+++ b/components/invalidation/impl/per_user_topic_registration_manager.cc
@@ -424,16 +424,15 @@
     observer.OnSubscriptionChannelStateChanged(invalidator_state);
 }
 
-std::unique_ptr<base::DictionaryValue>
-PerUserTopicRegistrationManager::CollectDebugData() const {
-  std::unique_ptr<base::DictionaryValue> return_value(
-      new base::DictionaryValue());
+base::DictionaryValue PerUserTopicRegistrationManager::CollectDebugData()
+    const {
+  base::DictionaryValue status;
   for (const auto& topic_to_private_topic : topic_to_private_topic_) {
-    return_value->SetString(topic_to_private_topic.first,
-                            topic_to_private_topic.second);
+    status.SetString(topic_to_private_topic.first,
+                     topic_to_private_topic.second);
   }
-  return_value->SetString("Instance id token", token_);
-  return return_value;
+  status.SetString("Instance id token", token_);
+  return status;
 }
 
 }  // namespace syncer
diff --git a/components/invalidation/impl/per_user_topic_registration_manager.h b/components/invalidation/impl/per_user_topic_registration_manager.h
index 998138b..2af273d 100644
--- a/components/invalidation/impl/per_user_topic_registration_manager.h
+++ b/components/invalidation/impl/per_user_topic_registration_manager.h
@@ -71,7 +71,7 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
-  std::unique_ptr<base::DictionaryValue> CollectDebugData() const;
+  base::DictionaryValue CollectDebugData() const;
 
   bool HaveAllRequestsFinishedForTest() const {
     return registration_statuses_.empty();
diff --git a/components/management_strings.grdp b/components/management_strings.grdp
index 9e66e7b7..5ba9cdb9 100644
--- a/components/management_strings.grdp
+++ b/components/management_strings.grdp
@@ -1,4 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Strings for the management disclosure panel
+
+  Disclosing admin capabilities to managed users is an important part of
+  striking a balance between the data needs of admins and the privacy
+  expectations of users.
+
+  Please consult with the privacy team when adding or changing strings.
+-->
+
 <grit-part>
   <message name="IDS_MANAGEMENT_TITLE" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment">
     <ph name="PRODUCT_NAME">$1<ex>Chrome OS</ex></ph> management
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc
index 62dfb775..f965102 100644
--- a/components/password_manager/core/browser/new_password_form_manager.cc
+++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -501,7 +501,6 @@
   result->password_overridden_ = password_overridden_;
   result->retry_password_form_password_update_ =
       retry_password_form_password_update_;
-  result->likely_form_filling_ = likely_form_filling_;
   result->is_submitted_ = is_submitted_;
 
   return result;
@@ -1067,7 +1066,8 @@
   saved_usernames.erase(base::string16());
 
   metrics_recorder_->CalculateFillingAssistanceMetric(
-      submitted_form, saved_usernames, saved_passwords);
+      submitted_form, saved_usernames, saved_passwords,
+      form_fetcher_->GetInteractionsStats());
 #endif
 }
 
diff --git a/components/password_manager/core/browser/new_password_form_manager.h b/components/password_manager/core/browser/new_password_form_manager.h
index a0a71c6..248192eb 100644
--- a/components/password_manager/core/browser/new_password_form_manager.h
+++ b/components/password_manager/core/browser/new_password_form_manager.h
@@ -152,14 +152,6 @@
   }
 
   FormSaver* form_saver() { return form_saver_.get(); }
-
-  const VotesUploader& votes_uploader() const { return votes_uploader_; }
-
-  LikelyFormFilling likely_form_filling() const { return likely_form_filling_; }
-
-  void set_likely_form_filling(LikelyFormFilling likely_form_filling) {
-    likely_form_filling_ = likely_form_filling;
-  }
 #endif
 
   // TODO(https://crbug.com/831123): Remove it when the old form parsing is
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
index c794b9d..dd0e2146 100644
--- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -1143,15 +1143,11 @@
 TEST_F(NewPasswordFormManagerTest, Clone) {
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
   fetcher_->SetNonFederated({}, 0u);
+
   // Provisionally save in order to create pending credentials.
   ASSERT_TRUE(
       form_manager_->ProvisionallySaveIfIsManaged(submitted_form_, &driver_));
 
-  // Make sure likely_form_filling is not in the default state anymore.
-  EXPECT_EQ(LikelyFormFilling::kNoFilling,
-            form_manager_->likely_form_filling());
-  form_manager_->set_likely_form_filling(LikelyFormFilling::kFillOnPageLoad);
-
   std::unique_ptr<NewPasswordFormManager> cloned_manager =
       form_manager_->Clone();
 
@@ -1163,15 +1159,12 @@
   EXPECT_EQ(form_manager_->metrics_recorder(),
             cloned_manager->metrics_recorder());
 
-  EXPECT_EQ(form_manager_->votes_uploader(), cloned_manager->votes_uploader());
   EXPECT_EQ(form_manager_->GetPendingCredentials(),
             cloned_manager->GetPendingCredentials());
   ASSERT_TRUE(cloned_manager->GetSubmittedForm());
   EXPECT_EQ(*form_manager_->GetSubmittedForm(),
             *cloned_manager->GetSubmittedForm());
   EXPECT_TRUE(cloned_manager->is_submitted());
-  EXPECT_EQ(form_manager_->likely_form_filling(),
-            cloned_manager->likely_form_filling());
 }
 
 // Extracts the information whether parsing was successful from a metric
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 096889ce..4a8b29e 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -1036,7 +1036,6 @@
   result->is_possible_change_password_form_without_username_ =
       is_possible_change_password_form_without_username_;
   result->votes_uploader_ = votes_uploader_;
-  result->likely_form_filling_ = likely_form_filling_;
 
   return result;
 }
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h
index 824f965..a1f422a 100644
--- a/components/password_manager/core/browser/password_form_manager.h
+++ b/components/password_manager/core/browser/password_form_manager.h
@@ -224,8 +224,6 @@
       size_t filtered_count) override;
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(PasswordFormManagerTest, Clone_DataIsCopied);
-
   // Through |driver|, supply the associated frame with appropriate information
   // (fill data, whether to allow password generation, etc.).
   void ProcessFrameInternal(const base::WeakPtr<PasswordManagerDriver>& driver);
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 731c70db..67f7741 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -4117,41 +4117,6 @@
   EXPECT_EQ(pending, passed);
 }
 
-// Check that a cloned PasswordFormManager correctly copies the data.
-TEST_F(PasswordFormManagerTest, Clone_DataIsCopied) {
-  // Construct some non-default data.
-  fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
-  form_manager()->ProvisionallySave(*observed_form());
-
-  EXPECT_NE(autofill::PasswordForm(), form_manager()->pending_credentials_);
-  auto flip_bool = [](bool& b) { b = !b; };
-  flip_bool(form_manager()->is_new_login_);
-  flip_bool(form_manager()->has_generated_password_);
-  form_manager()->generated_password_.push_back('c');
-  flip_bool(form_manager()->password_overridden_);
-  flip_bool(form_manager()->retry_password_form_password_update_);
-  flip_bool(form_manager()->is_possible_change_password_form_without_username_);
-  form_manager()->votes_uploader_.set_is_manual_generation(
-      !form_manager()->votes_uploader_.is_manual_generation());
-  EXPECT_NE(LikelyFormFilling::kNoFilling,
-            form_manager()->likely_form_filling_);
-
-  // Clone the manager and make sure the copied data matches.
-  std::unique_ptr<const PasswordFormManager> clone = form_manager()->Clone();
-  EXPECT_EQ(form_manager()->pending_credentials_, clone->pending_credentials_);
-  EXPECT_EQ(form_manager()->is_new_login_, clone->is_new_login_);
-  EXPECT_EQ(form_manager()->has_generated_password_,
-            clone->has_generated_password_);
-  EXPECT_EQ(form_manager()->generated_password_, clone->generated_password_);
-  EXPECT_EQ(form_manager()->password_overridden_, clone->password_overridden_);
-  EXPECT_EQ(form_manager()->retry_password_form_password_update_,
-            clone->retry_password_form_password_update_);
-  EXPECT_EQ(form_manager()->is_possible_change_password_form_without_username_,
-            clone->is_possible_change_password_form_without_username_);
-  EXPECT_EQ(form_manager()->votes_uploader_, clone->votes_uploader_);
-  EXPECT_EQ(form_manager()->likely_form_filling_, clone->likely_form_filling_);
-}
-
 // Verifies that URL keyed metrics are recorded for the filling of passwords
 // into forms and HTTP Basic auth.
 TEST_F(PasswordFormManagerTest, TestUkmForFilling) {
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc
index 360fb3a..e407765 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder.cc
+++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -13,7 +13,9 @@
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/password_generation_util.h"
 #include "components/password_manager/core/browser/form_fetcher.h"
+#include "components/password_manager/core/browser/password_bubble_experiment.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
+#include "components/password_manager/core/browser/statistics_table.h"
 
 using autofill::FieldPropertiesFlags;
 using autofill::FormData;
@@ -121,6 +123,26 @@
   return result;
 }
 
+// Returns whether any value of |submitted_form| is listed in the
+// |interactions_stats| has having been prompted to save as a credential and
+// being ignored too often.
+bool BlacklistedBySmartBubble(
+    const FormData& submitted_form,
+    const std::vector<InteractionsStats>& interactions_stats) {
+  const int show_threshold =
+      password_bubble_experiment::GetSmartBubbleDismissalThreshold();
+  for (const FormFieldData& field : submitted_form.fields) {
+    const base::string16& value =
+        field.typed_value.empty() ? field.value : field.typed_value;
+    for (const InteractionsStats& stat : interactions_stats) {
+      if (stat.username_value == value &&
+          stat.dismissal_count >= show_threshold)
+        return true;
+    }
+  }
+  return false;
+}
+
 }  // namespace
 
 PasswordFormMetricsRecorder::PasswordFormMetricsRecorder(
@@ -400,9 +422,28 @@
 void PasswordFormMetricsRecorder::CalculateFillingAssistanceMetric(
     const FormData& submitted_form,
     const std::set<base::string16>& saved_usernames,
-    const std::set<base::string16>& saved_passwords) {
+    const std::set<base::string16>& saved_passwords,
+    const std::vector<InteractionsStats>& interactions_stats) {
+  // If the user asked to never save credentials on a domain, an entry with
+  // empty password exists for that domain.
+  bool blacklisted =
+      saved_passwords.find(base::string16()) != saved_passwords.end();
+  if (blacklisted && saved_passwords.size() == 1u) {
+    // Note that we miss a nuance here:
+    //
+    // It is possible that the user logs in to a.example.com but b.example.com
+    // is blacklisted. We would still report kNoStoredCredentialsAndBlacklisted
+    // even though the user has not blacklisted a.example.com and is asked
+    // whether they want to save the credentials.
+    filling_assistance_ = FillingAssistance::kNoSavedCredentialsAndBlacklisted;
+    return;
+  }
+
   if (saved_passwords.empty()) {
-    filling_assistance_ = FillingAssistance::kNoSavedCredentials;
+    filling_assistance_ =
+        BlacklistedBySmartBubble(submitted_form, interactions_stats)
+            ? FillingAssistance::kNoSavedCredentialsAndBlacklistedBySmartBubble
+            : FillingAssistance::kNoSavedCredentials;
     return;
   }
 
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.h b/components/password_manager/core/browser/password_form_metrics_recorder.h
index 1b14be4..265a010 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder.h
+++ b/components/password_manager/core/browser/password_form_metrics_recorder.h
@@ -29,6 +29,7 @@
 namespace password_manager {
 
 class FormFetcher;
+struct InteractionsStats;
 
 // The pupose of this class is to record various types of metrics about the
 // behavior of the PasswordFormManager and its interaction with the user and
@@ -266,7 +267,12 @@
     kNoSavedCredentials = 5,
     // Neither user input nor filling.
     kNoUserInputNoFillingInPasswordFields = 6,
-    kMaxValue = kNoUserInputNoFillingInPasswordFields,
+    // Domain is blacklisted and no other credentials exist.
+    kNoSavedCredentialsAndBlacklisted = 7,
+    // No credentials exist and the user has ignored the save bubble too often,
+    // meaning that they won't be asked to save credentials anymore.
+    kNoSavedCredentialsAndBlacklistedBySmartBubble = 8,
+    kMaxValue = kNoSavedCredentialsAndBlacklistedBySmartBubble,
   };
 
   // The maximum number of combinations of the ManagerAction, UserAction and
@@ -398,7 +404,8 @@
   void CalculateFillingAssistanceMetric(
       const autofill::FormData& submitted_form,
       const std::set<base::string16>& saved_usernames,
-      const std::set<base::string16>& saved_passwords);
+      const std::set<base::string16>& saved_passwords,
+      const std::vector<InteractionsStats>& interactions_stats);
 
  private:
   friend class base::RefCounted<PasswordFormMetricsRecorder>;
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
index 8bb5d4c3..d9fd683 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
+++ b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
@@ -14,6 +14,7 @@
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
+#include "components/password_manager/core/browser/statistics_table.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
@@ -712,6 +713,7 @@
   std::vector<FieldInfo> fields;
   std::vector<std::string> saved_usernames;
   std::vector<std::string> saved_passwords;
+  std::vector<InteractionsStats> interactions_stats;
 
   base::Optional<PasswordFormMetricsRecorder::FillingAssistance> expectation;
 };
@@ -766,9 +768,11 @@
 
   auto recorder =
       CreatePasswordFormMetricsRecorder(true /*is_main_frame_secure*/, nullptr);
-  if (test_case.submission_detected)
+  if (test_case.submission_detected) {
     recorder->CalculateFillingAssistanceMetric(form_data, saved_usernames,
-                                               saved_passwords);
+                                               saved_passwords,
+                                               test_case.interactions_stats);
+  }
 
   if (test_case.submission_is_successful)
     recorder->LogSubmitPassed();
@@ -988,4 +992,52 @@
        .expectation = PasswordFormMetricsRecorder::FillingAssistance::kManual});
 }
 
+TEST(PasswordFormMetricsRecorder, FillingAssistanceBlacklistedDomain) {
+  CheckFillingAssistanceTestCase(
+      {.description_for_logging = "Submission while domain is blacklisted",
+       .fields = {{.value = "user1"},
+                  {.value = "password1", .is_password = true}},
+       // A blacklisted domain is represented as empty username and password
+       // but empty username elements are stripped before
+       // PasswordFormMetricsRecorder::CalculateFillingAssistanceMetric is
+       // called.
+       .saved_usernames = {},
+       .saved_passwords = {""},
+       .expectation = PasswordFormMetricsRecorder::FillingAssistance::
+           kNoSavedCredentialsAndBlacklisted});
+}
+
+TEST(PasswordFormMetricsRecorder,
+     FillingAssistanceBlacklistedDomainWithCredential) {
+  CheckFillingAssistanceTestCase(
+      {.description_for_logging =
+           "Submission while domain is blacklisted but a credential is stored",
+       .fields = {{.value = "user1", .automatically_filled = true},
+                  {.value = "password1",
+                   .is_password = true,
+                   .automatically_filled = true}},
+       // A blacklisted domain is represented as empty username and password
+       // but empty username elements are stripped before
+       // PasswordFormMetricsRecorder::CalculateFillingAssistanceMetric is
+       // called.
+       .saved_usernames = {"user1"},
+       .saved_passwords = {"", "password1"},
+       .expectation =
+           PasswordFormMetricsRecorder::FillingAssistance::kAutomatic});
+}
+
+TEST(PasswordFormMetricsRecorder, FillingAssistanceBlacklistedBySmartBubble) {
+  CheckFillingAssistanceTestCase(
+      {.description_for_logging = "Submission without saved credentials while "
+                                  "smart bubble suppresses saving",
+       .fields = {{.value = "user1"},
+                  {.value = "password1", .is_password = true}},
+       .saved_usernames = {},
+       .saved_passwords = {},
+       .interactions_stats = {{.username_value = ASCIIToUTF16("user1"),
+                               .dismissal_count = 10}},
+       .expectation = PasswordFormMetricsRecorder::FillingAssistance::
+           kNoSavedCredentialsAndBlacklistedBySmartBubble});
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/statistics_table.cc b/components/password_manager/core/browser/statistics_table.cc
index da129d5..d9105d4 100644
--- a/components/password_manager/core/browser/statistics_table.cc
+++ b/components/password_manager/core/browser/statistics_table.cc
@@ -41,8 +41,6 @@
 
 }  // namespace
 
-InteractionsStats::InteractionsStats() = default;
-
 bool operator==(const InteractionsStats& lhs, const InteractionsStats& rhs) {
   return lhs.origin_domain == rhs.origin_domain &&
          lhs.username_value == rhs.username_value &&
diff --git a/components/password_manager/core/browser/statistics_table.h b/components/password_manager/core/browser/statistics_table.h
index af880c957..b24389e0 100644
--- a/components/password_manager/core/browser/statistics_table.h
+++ b/components/password_manager/core/browser/statistics_table.h
@@ -21,8 +21,6 @@
 
 // The statistics containing user interactions with a site.
 struct InteractionsStats {
-  InteractionsStats();
-
   // The domain of the site.
   GURL origin_domain;
 
diff --git a/components/password_manager/core/browser/votes_uploader.cc b/components/password_manager/core/browser/votes_uploader.cc
index d29b32f1..b52b9cd 100644
--- a/components/password_manager/core/browser/votes_uploader.cc
+++ b/components/password_manager/core/browser/votes_uploader.cc
@@ -6,7 +6,6 @@
 
 #include <ctype.h>
 #include <map>
-#include <tuple>
 
 #include "base/metrics/histogram_macros.h"
 #include "base/rand_util.h"
@@ -532,22 +531,4 @@
   form_structure->set_password_length_vote(randomized_length);
 }
 
-bool VotesUploader::operator==(const VotesUploader& other) const {
-  return std::tie(client_, generation_popup_was_shown_, is_manual_generation_,
-                  generation_element_, has_username_edited_vote_,
-                  has_username_correction_vote_, username_correction_vote_,
-                  has_passwords_revealed_vote_, password_overridden_,
-                  is_possible_change_password_form_, has_generated_password_,
-                  generated_password_changed_) ==
-         std::tie(
-             other.client_, other.generation_popup_was_shown_,
-             other.is_manual_generation_, other.generation_element_,
-             other.has_username_edited_vote_,
-             other.has_username_correction_vote_,
-             other.username_correction_vote_,
-             other.has_passwords_revealed_vote_, other.password_overridden_,
-             other.is_possible_change_password_form_,
-             other.has_generated_password_, other.generated_password_changed_);
-}
-
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/votes_uploader.h b/components/password_manager/core/browser/votes_uploader.h
index 89fb7b4..a8318d1 100644
--- a/components/password_manager/core/browser/votes_uploader.h
+++ b/components/password_manager/core/browser/votes_uploader.h
@@ -84,8 +84,6 @@
   void GeneratePasswordAttributesVote(const base::string16& password_value,
                                       autofill::FormStructure* form_structure);
 
-  bool operator==(const VotesUploader& other) const;
-
   bool get_generation_popup_was_shown() const {
     return generation_popup_was_shown_;
   }
diff --git a/components/scheduling_metrics/task_duration_metric_reporter.h b/components/scheduling_metrics/task_duration_metric_reporter.h
index b2a9b818..84a7d568 100644
--- a/components/scheduling_metrics/task_duration_metric_reporter.h
+++ b/components/scheduling_metrics/task_duration_metric_reporter.h
@@ -35,7 +35,7 @@
             static_cast<int>(TaskClass::kCount),
             static_cast<int>(TaskClass::kCount) + 1,
             1000 * 1000,
-            base::HistogramBase::kUmaTargetedHistogramFlag)){};
+            base::HistogramBase::kUmaTargetedHistogramFlag)) {}
 
   void RecordTask(TaskClass task_class, base::TimeDelta duration) {
     DCHECK_LT(static_cast<int>(task_class),
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc
index 2d29bae..5f171f23 100644
--- a/components/signin/core/browser/account_reconcilor_unittest.cc
+++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -2206,11 +2206,10 @@
 }
 
 TEST_F(AccountReconcilorTest, AuthErrorTriggersListAccount) {
-  class TestGaiaCookieObserver : public GaiaCookieManagerService::Observer {
+  class TestGaiaCookieObserver : public identity::IdentityManager::Observer {
    public:
-    void OnGaiaAccountsInCookieUpdated(
-        const std::vector<gaia::ListedAccount>& accounts,
-        const std::vector<gaia::ListedAccount>& signed_out_accounts,
+    void OnAccountsInCookieUpdated(
+        const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
         const GoogleServiceAuthError& error) override {
       cookies_updated_ = true;
     }
@@ -2233,7 +2232,7 @@
   const std::string account_id = account_info.account_id;
   identity_test_env()->SetRefreshTokenForAccount(account_id);
   TestGaiaCookieObserver observer;
-  cookie_manager_service()->AddObserver(&observer);
+  identity_test_env()->identity_manager()->AddObserver(&observer);
   AccountReconcilor* reconcilor = GetMockReconcilor();
   base::RunLoop().RunUntilIdle();
   ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -2257,7 +2256,7 @@
   EXPECT_TRUE(observer.cookies_updated_);
   testing::Mock::VerifyAndClearExpectations(GetMockReconcilor());
 
-  cookie_manager_service()->RemoveObserver(&observer);
+  identity_test_env()->identity_manager()->RemoveObserver(&observer);
 }
 
 #if !defined(OS_CHROMEOS)
diff --git a/components/signin/core/browser/fake_signin_manager.cc b/components/signin/core/browser/fake_signin_manager.cc
index 8fe75e3..50a187a3 100644
--- a/components/signin/core/browser/fake_signin_manager.cc
+++ b/components/signin/core/browser/fake_signin_manager.cc
@@ -56,11 +56,9 @@
     const std::string& refresh_token,
     const std::string& gaia_id,
     const std::string& username,
-    const std::string& password,
     OAuthTokenFetchedCallback oauth_fetched_callback) {
   set_auth_in_progress(
       account_tracker_service()->SeedAccountInfo(gaia_id, username));
-  set_password(password);
   username_ = username;
 
   possibly_invalid_gaia_id_.assign(gaia_id);
@@ -77,9 +75,8 @@
 }
 
 void FakeSigninManager::SignIn(const std::string& gaia_id,
-                               const std::string& username,
-                               const std::string& password) {
-  StartSignInWithRefreshToken(std::string(), gaia_id, username, password,
+                               const std::string& username) {
+  StartSignInWithRefreshToken(std::string(), gaia_id, username,
                               OAuthTokenFetchedCallback());
   CompletePendingSignin();
 }
@@ -123,7 +120,6 @@
     return;
 
   set_auth_in_progress(std::string());
-  set_password(std::string());
   AccountInfo account_info = GetAuthenticatedAccountInfo();
   const std::string account_id = GetAuthenticatedAccountId();
   const std::string username = account_info.email;
diff --git a/components/signin/core/browser/fake_signin_manager.h b/components/signin/core/browser/fake_signin_manager.h
index 5c7de4a6..0c5239e 100644
--- a/components/signin/core/browser/fake_signin_manager.h
+++ b/components/signin/core/browser/fake_signin_manager.h
@@ -48,11 +48,7 @@
     possibly_invalid_account_id_ = account_id;
   }
 
-  void set_password(const std::string& password) { password_ = password; }
-
-  void SignIn(const std::string& gaia_id,
-              const std::string& username,
-              const std::string& password);
+  void SignIn(const std::string& gaia_id, const std::string& username);
 
   void ForceSignOut();
 
@@ -62,7 +58,6 @@
       const std::string& refresh_token,
       const std::string& gaia_id,
       const std::string& username,
-      const std::string& password,
       OAuthTokenFetchedCallback oauth_fetched_callback) override;
 
   void CompletePendingSignin() override;
diff --git a/components/signin/core/browser/signin_client.h b/components/signin/core/browser/signin_client.h
index 8aaa8c2..202cfda 100644
--- a/components/signin/core/browser/signin_client.h
+++ b/components/signin/core/browser/signin_client.h
@@ -61,11 +61,6 @@
   // Signin component is being used.
   virtual std::string GetProductVersion() = 0;
 
-  // Called after Google signin has succeeded and GetUserInfo has returned.
-  virtual void PostSignedIn(const std::string& account_id,
-                            const std::string& username,
-                            const std::string& password) {}
-
   // Called before Google sign-out started. Implementers must run the
   // |on_signout_decision_reached|, passing a SignoutDecision to allow/disallow
   // sign-out to continue. When to disallow sign-out is implementation specific.
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc
index d569d57..c896fc7 100644
--- a/components/signin/core/browser/signin_manager.cc
+++ b/components/signin/core/browser/signin_manager.cc
@@ -58,8 +58,7 @@
 
 bool SigninManager::PrepareForSignin(SigninType type,
                                      const std::string& gaia_id,
-                                     const std::string& username,
-                                     const std::string& password) {
+                                     const std::string& username) {
   std::string account_id =
       account_tracker_service()->PickAccountIdForAccount(gaia_id, username);
   DCHECK(!account_id.empty());
@@ -83,7 +82,6 @@
   possibly_invalid_account_id_.assign(account_id);
   possibly_invalid_gaia_id_.assign(gaia_id);
   possibly_invalid_email_.assign(username);
-  password_.assign(password);
   signin_manager_signed_in_ = false;
   user_info_fetched_by_account_tracker_ = false;
   return true;
@@ -93,13 +91,12 @@
     const std::string& refresh_token,
     const std::string& gaia_id,
     const std::string& username,
-    const std::string& password,
     OAuthTokenFetchedCallback callback) {
   DCHECK(!IsAuthenticated());
   SigninType signin_type = refresh_token.empty()
                                ? SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN
                                : SIGNIN_TYPE_WITH_REFRESH_TOKEN;
-  if (!PrepareForSignin(signin_type, gaia_id, username, password)) {
+  if (!PrepareForSignin(signin_type, gaia_id, username)) {
     return;
   }
 
@@ -121,7 +118,6 @@
   possibly_invalid_gaia_id_ = source.possibly_invalid_gaia_id_;
   possibly_invalid_email_ = source.possibly_invalid_email_;
   temp_refresh_token_ = source.temp_refresh_token_;
-  password_ = source.password_;
   source.signin_client()->AfterCredentialsCopied();
 }
 
@@ -131,7 +127,6 @@
   possibly_invalid_account_id_.clear();
   possibly_invalid_gaia_id_.clear();
   possibly_invalid_email_.clear();
-  password_.clear();
   type_ = SIGNIN_TYPE_NONE;
   temp_refresh_token_.clear();
 }
@@ -425,16 +420,12 @@
 
   signin_metrics::LogSigninProfile(signin_client()->IsFirstRun(),
                                    signin_client()->GetInstallDate());
-
-  PostSignedIn();
 }
 
 void SigninManager::FireGoogleSigninSucceeded() {
   const AccountInfo account_info = GetAuthenticatedAccountInfo();
-  for (auto& observer : observer_list_) {
+  for (auto& observer : observer_list_)
     observer.GoogleSigninSucceeded(account_info);
-    observer.GoogleSigninSucceededWithPassword(account_info, password_);
-  }
 }
 
 void SigninManager::FireGoogleSignedOut(const AccountInfo& account_info) {
@@ -443,26 +434,15 @@
   }
 }
 
-void SigninManager::PostSignedIn() {
-  if (!signin_manager_signed_in_ || !user_info_fetched_by_account_tracker_)
-    return;
-
-  signin_client()->PostSignedIn(GetAuthenticatedAccountId(),
-                                GetAuthenticatedAccountInfo().email, password_);
-  password_.clear();
-}
-
 void SigninManager::OnAccountUpdated(const AccountInfo& info) {
   if (!info.IsValid())
     return;
 
   user_info_fetched_by_account_tracker_ = true;
-  PostSignedIn();
 }
 
 void SigninManager::OnAccountUpdateFailed(const std::string& account_id) {
   user_info_fetched_by_account_tracker_ = true;
-  PostSignedIn();
 }
 
 void SigninManager::OnRefreshTokensLoaded() {
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h
index cf3bbc1..a0eeed28 100644
--- a/components/signin/core/browser/signin_manager.h
+++ b/components/signin/core/browser/signin_manager.h
@@ -104,7 +104,6 @@
       const std::string& refresh_token,
       const std::string& gaia_id,
       const std::string& username,
-      const std::string& password,
       OAuthTokenFetchedCallback oauth_fetched_callback);
 
   // Copies auth credentials from one SigninManager to this one. This is used
@@ -201,14 +200,13 @@
 
   // Called to setup the transient signin data during one of the
   // StartSigninXXX methods.  |type| indicates which of the methods is being
-  // used to perform the signin while |username| and |password| identify the
-  // account to be signed in. Returns false and generates an auth error if the
-  // passed |username| is not allowed by policy.  |gaia_id| is the obfuscated
-  // gaia id corresponding to |username|.
+  // used to perform the signin while |username| identifies the account to be
+  // signed in. Returns false and generates an auth error if the passed
+  // |username| is not allowed by policy.  |gaia_id| is the obfuscated gaia id
+  // corresponding to |username|.
   bool PrepareForSignin(SigninType type,
                         const std::string& gaia_id,
-                        const std::string& username,
-                        const std::string& password);
+                        const std::string& username);
 
   // Persists |account_id| as the currently signed-in account, and triggers
   // a sign-in success notification.
@@ -220,10 +218,6 @@
   // Send all observers |GoogleSignedOut| notifications.
   void FireGoogleSignedOut(const AccountInfo& account_info);
 
-  // Waits for the AccountTrackerService, then sends GoogleSigninSucceeded to
-  // the client and clears the local password.
-  void PostSignedIn();
-
   // AccountTrackerService::Observer:
   void OnAccountUpdated(const AccountInfo& info) override;
   void OnAccountUpdateFailed(const std::string& account_id) override;
@@ -255,7 +249,6 @@
   std::string possibly_invalid_account_id_;
   std::string possibly_invalid_gaia_id_;
   std::string possibly_invalid_email_;
-  std::string password_;  // This is kept empty whenever possible.
 
   // The type of sign being performed.  This value is valid only between a call
   // to one of the StartSigninXXX methods and when the sign in is either
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h
index f75a647f..3099703b 100644
--- a/components/signin/core/browser/signin_manager_base.h
+++ b/components/signin/core/browser/signin_manager_base.h
@@ -55,22 +55,6 @@
     // This method is not called during a reauth.
     virtual void GoogleSigninSucceeded(const AccountInfo& account_info) {}
 
-    // Called when a user signs into Google services such as sync. Also passes
-    // the password of the Google account that was used to sign in.
-    // This method is not called during a reauth.
-    //
-    // Observers should override |GoogleSigninSucceeded| if they are not
-    // interested in the password thas was used during the sign-in.
-    //
-    // Note: The password is always empty on mobile as the user signs in to
-    // Chrome with accounts that were added to the device, so Chrome does not
-    // have access to the password.
-    // DEPRECATED: password will be empty if login is using DICE workflow; the
-    // method will be removed once all login is using the DICE workflow.
-    virtual void GoogleSigninSucceededWithPassword(
-        const AccountInfo& account_info,
-        const std::string& password) {}
-
     // Called when the currently signed-in user for a user has been signed out.
     virtual void GoogleSignedOut(const AccountInfo& account_info) {}
 
@@ -78,8 +62,7 @@
     virtual ~Observer() {}
 
    private:
-    // SigninManagers that fire |GoogleSigninSucceededWithPassword|
-    // notifications.
+    // SigninManagers that fire notifications.
     friend class SigninManager;
     friend class FakeSigninManager;
   };
diff --git a/components/signin/core/browser/signin_manager_unittest.cc b/components/signin/core/browser/signin_manager_unittest.cc
index 5cb99d8..ef48ab2 100644
--- a/components/signin/core/browser/signin_manager_unittest.cc
+++ b/components/signin/core/browser/signin_manager_unittest.cc
@@ -40,14 +40,12 @@
   TestSigninManagerObserver()
       : num_failed_signins_(0),
         num_successful_signins_(0),
-        num_successful_signins_with_password_(0),
         num_signouts_(0) {}
 
   ~TestSigninManagerObserver() override {}
 
   int num_failed_signins_;
   int num_successful_signins_;
-  int num_successful_signins_with_password_;
   int num_signouts_;
 
  private:
@@ -60,11 +58,6 @@
     num_successful_signins_++;
   }
 
-  void GoogleSigninSucceededWithPassword(const AccountInfo& account_info,
-                                         const std::string& password) override {
-    num_successful_signins_with_password_++;
-  }
-
   void GoogleSignedOut(const AccountInfo& account_info) override {
     num_signouts_++;
   }
@@ -145,7 +138,6 @@
 
     // Should go into token service and stop.
     EXPECT_EQ(1, test_observer_.num_successful_signins_);
-    EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
     EXPECT_EQ(0, test_observer_.num_failed_signins_);
   }
 
@@ -175,7 +167,7 @@
 
   std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
   manager_->StartSignInWithRefreshToken(
-      "rt", "gaia_id", "user@gmail.com", "password",
+      "rt", "gaia_id", "user@gmail.com",
       SigninManager::OAuthTokenFetchedCallback());
 
   ExpectSignInWithRefreshTokenSuccess();
@@ -190,9 +182,8 @@
   CreateSigninManager();
   EXPECT_FALSE(manager_->IsAuthenticated());
 
-  // Since the password is empty, must verify the gaia cookies first.
   manager_->StartSignInWithRefreshToken(
-      "rt", "gaia_id", "user@gmail.com", "password",
+      "rt", "gaia_id", "user@gmail.com",
       base::BindOnce(&SigninManagerTest::CompleteSigninCallback,
                      base::Unretained(this)));
 
@@ -211,30 +202,21 @@
   account_tracker()->SeedAccountInfo(gaia_id, email);
   account_fetcher()->OnRefreshTokensLoaded();
 
-  ASSERT_TRUE(signin_client()->get_signed_in_password().empty());
-
   manager_->StartSignInWithRefreshToken(
-      "rt1", gaia_id, email, "password",
-      SigninManager::OAuthTokenFetchedCallback());
-
-  // PostSignedIn is not called until the AccountTrackerService returns.
-  ASSERT_EQ("", signin_client()->get_signed_in_password());
+      "rt1", gaia_id, email, SigninManager::OAuthTokenFetchedCallback());
 
   account_fetcher()->FakeUserInfoFetchSuccess(
       account_tracker()->PickAccountIdForAccount(gaia_id, email), email,
       gaia_id, "google.com", "full_name", "given_name", "locale",
       "http://www.google.com");
 
-  // AccountTracker and SigninManager are both done and PostSignedIn was called.
-  ASSERT_EQ("password", signin_client()->get_signed_in_password());
-
   ExpectSignInWithRefreshTokenSuccess();
 }
 
 TEST_F(SigninManagerTest, SignOut) {
   CreateSigninManager();
   manager_->StartSignInWithRefreshToken(
-      "rt", "gaia_id", "user@gmail.com", "password",
+      "rt", "gaia_id", "user@gmail.com",
       SigninManager::OAuthTokenFetchedCallback());
   manager_->SignOut(signin_metrics::SIGNOUT_TEST,
                     signin_metrics::SignoutDelete::IGNORE_METRIC);
@@ -391,12 +373,10 @@
   EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email);
   EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
   EXPECT_EQ(0, test_observer_.num_successful_signins_);
-  EXPECT_EQ(0, test_observer_.num_successful_signins_with_password_);
 
   std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
   manager_->OnExternalSigninCompleted("user@gmail.com");
   EXPECT_EQ(1, test_observer_.num_successful_signins_);
-  EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
   EXPECT_EQ(0, test_observer_.num_failed_signins_);
   EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email);
   EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
@@ -407,19 +387,16 @@
   EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email);
   EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
   EXPECT_EQ(0, test_observer_.num_successful_signins_);
-  EXPECT_EQ(0, test_observer_.num_successful_signins_with_password_);
 
   std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
   manager_->OnExternalSigninCompleted("user@gmail.com");
   EXPECT_EQ(1, test_observer_.num_successful_signins_);
-  EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
   EXPECT_EQ(0, test_observer_.num_failed_signins_);
   EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email);
   EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
 
   manager_->OnExternalSigninCompleted("user@gmail.com");
   EXPECT_EQ(1, test_observer_.num_successful_signins_);
-  EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
   EXPECT_EQ(0, test_observer_.num_failed_signins_);
   EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email);
   EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
diff --git a/components/signin/core/browser/test_signin_client.cc b/components/signin/core/browser/test_signin_client.cc
index 889365f9..df99082 100644
--- a/components/signin/core/browser/test_signin_client.cc
+++ b/components/signin/core/browser/test_signin_client.cc
@@ -67,12 +67,6 @@
   std::move(callback).Run(false);
 }
 
-void TestSigninClient::PostSignedIn(const std::string& account_id,
-                  const std::string& username,
-                  const std::string& password) {
-  signed_in_password_ = password;
-}
-
 void TestSigninClient::PreSignOut(
     base::OnceCallback<void(SignoutDecision)> on_signout_decision_reached,
     signin_metrics::ProfileSignout signout_source_metric) {
diff --git a/components/signin/core/browser/test_signin_client.h b/components/signin/core/browser/test_signin_client.h
index 3b0e39f4..ef6fe58 100644
--- a/components/signin/core/browser/test_signin_client.h
+++ b/components/signin/core/browser/test_signin_client.h
@@ -38,19 +38,12 @@
   // once there is a unit test that requires it.
   PrefService* GetPrefs() override;
 
-  // Trace that this was called.
-  void PostSignedIn(const std::string& account_id,
-                    const std::string& username,
-                    const std::string& password) override;
-
   // Allow or disallow continuation of sign-out depending on value of
   // |is_signout_allowed_|;
   void PreSignOut(
       base::OnceCallback<void(SignoutDecision)> on_signout_decision_reached,
       signin_metrics::ProfileSignout signout_source_metric) override;
 
-  std::string get_signed_in_password() { return signed_in_password_; }
-
   // Returns the empty string.
   std::string GetProductVersion() override;
 
@@ -103,9 +96,6 @@
   bool is_signout_allowed_;
   std::vector<base::OnceClosure> delayed_network_calls_;
 
-  // Pointer to be filled by PostSignedIn.
-  std::string signed_in_password_;
-
   DISALLOW_COPY_AND_ASSIGN(TestSigninClient);
 };
 
diff --git a/components/signin/ios/browser/account_consistency_service_unittest.mm b/components/signin/ios/browser/account_consistency_service_unittest.mm
index d8275f82..acc44e7 100644
--- a/components/signin/ios/browser/account_consistency_service_unittest.mm
+++ b/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -221,7 +221,7 @@
   }
 
   void SignIn() {
-    signin_manager_->SignIn("12345", "user@gmail.com", "password");
+    signin_manager_->SignIn("12345", "user@gmail.com");
     EXPECT_EQ(0, web_view_load_expection_count_);
   }
 
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
index 4dd222b..59d5f17 100644
--- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
+++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
@@ -12,30 +12,23 @@
 }
 
 button {
+  background: #1A73E8;
   border: 0;
   border-radius: 2px;
   box-sizing: border-box;
-  color: #fff;
+  color: #ffffff;
   cursor: pointer;
-  float: right;
-  font-family: Roboto;
+  font-family: 'Google Sans', Roboto, sans-serif;
   font-size: 14px;
-  font-weight: 500;
+  font-weight: 550;
+  line-height: 16pt;
   margin: 0;
-  padding: 10px 24px;
+  padding: 7px 24px;
   transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
   user-select: none;
 }
 
-[dir='rtl'] button {
-  float: left;
-}
-
-.primary-button {
-  background: rgb(66, 133, 244);
-}
-
-.primary-button:active {
+button:active {
   background: rgb(50, 102, 213);
   outline: 0;
 }
@@ -44,6 +37,18 @@
   box-shadow: 0 1px 3px rgba(0, 0, 0, .50);
 }
 
+[dir='rtl'] button {
+  float: left;
+}
+
+.ask-permission-button {
+  float: right;
+}
+
+.go-back-button {
+  float: left;
+}
+
 #details {
   color: #696969;
   margin: 45px 0 50px;
@@ -83,11 +88,6 @@
   margin-bottom: 16px;
 }
 
-h2 {
-  font-size: 1.2em;
-  font-weight: normal;
-}
-
 html {
   -webkit-text-size-adjust: 100%;
   font-size: 125%;
@@ -103,13 +103,28 @@
 
 .main-frame-blocked {
   box-sizing: border-box;
-  font-size: 1em;
-  line-height: 1.6em;
   margin: 100px auto 0;
   max-width: 600px;
   width: 100%;
 }
 
+/* "Ask your Parent" title */
+.main-frame-blocked h1 {
+  color: #202124;
+  font-family: 'Google Sans', Roboto, sans-serif;
+  font-size: 24px;
+  font-weight: normal;
+  line-height: 32px;
+}
+
+/* "You need permission..." message */
+.main-frame-blocked p {
+  color: #3c4043;
+  font-family: Roboto;
+  font-size: 16px;
+  font-weight: normal;
+}
+
 #main-message > p:not([hidden]) {
   display: inline;
 }
@@ -138,13 +153,13 @@
   content: -webkit-image-set(
       url(default_100_percent/logo_avatar_circle_blue_color.png) 1x,
       url(default_200_percent/logo_avatar_circle_blue_color.png) 2x);
-  height: 45px;
+  height: 36px;
   margin-bottom: 5px;
   margin-right: 15px;
   margin-top: 5px;
   position: relative;
   user-select: none;
-  width: 45px;
+  width: 36px;
 }
 
 #feedback {
@@ -154,20 +169,22 @@
 .custodian-information {
   align-items: center;
   display: flex;
-  font-size: 15px;
+  font-family: Roboto;
   font-weight: 400;
   line-height: normal;
   margin-top: 14px;
 }
 
 .custodian-name {
-  color: rgba(0, 0, 0, 0.87);
-  padding: 1px 0;
+  color: #202124;
+  font-size: 16px;
+  line-height: 24px;
 }
 
 .custodian-email {
-  color: rgb(0, 0, 0, 0.54);
-  padding: 1px 0;
+  color: #5f6368;
+  font-size: 14px;
+  line-height: 20px;
 }
 
 
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
index c04f9249..7e6f621 100644
--- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
+++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
@@ -5,6 +5,7 @@
 <meta name="viewport"
     content="initial-scale=1, minimum-scale=1, width=device-width">
 <title>$i18n{blockPageTitle}</title>
+<link href="https://fonts.googleapis.com/css?family=Google+Sans" rel="stylesheet">
 <link rel="stylesheet" href="supervised_user_block_interstitial.css">
 <script src="../../../ui/webui/resources/js/cr.js"></script>
 <script src="../../../ui/webui/resources/js/util.js"></script>
@@ -38,7 +39,7 @@
     </div>
   </div>
   <div class="button-container">
-    <button id="request-access-button" class="primary-button">
+    <button id="request-access-button" class="ask-permission-button">
       $i18n{requestAccessButton}
     </button>
     <div id="details-button-container">
@@ -49,7 +50,7 @@
         $i18n{hideDetailsLink}
       </button>
     </div>
-    <button id="back-button" class="details-button small-link" hidden>
+    <button id="back-button" class="go-back-button" hidden>
       $i18n{backButton}
     </button>
   </div>
diff --git a/components/supervised_user_error_page/supervised_user_error_page.cc b/components/supervised_user_error_page/supervised_user_error_page.cc
index 133c8dae..da5c980 100644
--- a/components/supervised_user_error_page/supervised_user_error_page.cc
+++ b/components/supervised_user_error_page/supervised_user_error_page.cc
@@ -20,8 +20,8 @@
 
 namespace {
 
-static const int kAvatarSize1x = 45;
-static const int kAvatarSize2x = 90;
+static const int kAvatarSize1x = 36;
+static const int kAvatarSize2x = 72;
 
 bool ReasonIsAutomatic(FilteringBehaviorReason reason) {
   return reason == ASYNC_CHECKER || reason == BLACKLIST;
diff --git a/components/sync/base/enum_set.h b/components/sync/base/enum_set.h
index 2862d68..dee6838e 100644
--- a/components/sync/base/enum_set.h
+++ b/components/sync/base/enum_set.h
@@ -41,11 +41,20 @@
 
 template <typename E, E MinEnumValue, E MaxEnumValue>
 class EnumSet {
+ private:
+  using enum_underlying_type = std::underlying_type_t<E>;
+
+  static constexpr enum_underlying_type GetUnderlyingValue(E value) {
+    return static_cast<enum_underlying_type>(value);
+  }
+
  public:
   using EnumType = E;
   static const E kMinValue = MinEnumValue;
   static const E kMaxValue = MaxEnumValue;
-  static const size_t kValueCount = kMaxValue - kMinValue + 1;
+  static const size_t kValueCount =
+      GetUnderlyingValue(kMaxValue) - GetUnderlyingValue(kMinValue) + 1;
+
   static_assert(kMinValue < kMaxValue, "min value must be less than max value");
 
  private:
@@ -260,11 +269,13 @@
 
   // Converts a value to/from an index into |enums_|.
 
-  static constexpr size_t ToIndex(E value) { return value - MinEnumValue; }
+  static constexpr size_t ToIndex(E value) {
+    return GetUnderlyingValue(value) - GetUnderlyingValue(MinEnumValue);
+  }
 
   static E FromIndex(size_t i) {
     DCHECK_LT(i, kValueCount);
-    return static_cast<E>(MinEnumValue + i);
+    return static_cast<E>(GetUnderlyingValue(MinEnumValue) + i);
   }
 
   EnumBitSet enums_;
diff --git a/components/sync/base/enum_set_unittest.cc b/components/sync/base/enum_set_unittest.cc
index 7c6bea7..4f23136 100644
--- a/components/sync/base/enum_set_unittest.cc
+++ b/components/sync/base/enum_set_unittest.cc
@@ -11,7 +11,7 @@
 namespace syncer {
 namespace {
 
-enum TestEnum {
+enum class TestEnum {
   TEST_0,
   TEST_MIN = TEST_0,
   TEST_1,
@@ -22,25 +22,26 @@
   TEST_5
 };
 
-using TestEnumSet = EnumSet<TestEnum, TEST_MIN, TEST_MAX>;
+using TestEnumSet = EnumSet<TestEnum, TestEnum::TEST_MIN, TestEnum::TEST_MAX>;
 
 class EnumSetTest : public ::testing::Test {};
 
 TEST_F(EnumSetTest, ClassConstants) {
   TestEnumSet enums;
-  EXPECT_EQ(TEST_MIN, TestEnumSet::kMinValue);
-  EXPECT_EQ(TEST_MAX, TestEnumSet::kMaxValue);
+  EXPECT_EQ(TestEnum::TEST_MIN, TestEnumSet::kMinValue);
+  EXPECT_EQ(TestEnum::TEST_MAX, TestEnumSet::kMaxValue);
   EXPECT_EQ(static_cast<size_t>(5), TestEnumSet::kValueCount);
 }
 
 // Use static_assert to check that functions we expect to be compile time
 // evaluatable are really that way.
 TEST_F(EnumSetTest, ConstexprsAreValid) {
-  static_assert(TestEnumSet::All().Has(TEST_1),
+  static_assert(TestEnumSet::All().Has(TestEnum::TEST_1),
                 "expected All() to be integral constant expression");
-  static_assert(TestEnumSet::FromRange(TEST_1, TEST_3).Has(TEST_1),
+  static_assert(TestEnumSet::FromRange(TestEnum::TEST_1, TestEnum::TEST_3)
+                    .Has(TestEnum::TEST_1),
                 "expected FromRange() to be integral constant expression");
-  static_assert(TestEnumSet(TEST_1).Has(TEST_1),
+  static_assert(TestEnumSet(TestEnum::TEST_1).Has(TestEnum::TEST_1),
                 "expected TestEnumSet() to be integral constant expression");
 }
 
@@ -48,138 +49,146 @@
   const TestEnumSet enums;
   EXPECT_TRUE(enums.Empty());
   EXPECT_EQ(static_cast<size_t>(0), enums.Size());
-  EXPECT_FALSE(enums.Has(TEST_0));
-  EXPECT_FALSE(enums.Has(TEST_1));
-  EXPECT_FALSE(enums.Has(TEST_2));
-  EXPECT_FALSE(enums.Has(TEST_3));
-  EXPECT_FALSE(enums.Has(TEST_4));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_0));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_1));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_3));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_4));
 }
 
 TEST_F(EnumSetTest, OneArgConstructor) {
-  const TestEnumSet enums(TEST_3);
+  const TestEnumSet enums(TestEnum::TEST_3);
   EXPECT_FALSE(enums.Empty());
   EXPECT_EQ(static_cast<size_t>(1), enums.Size());
-  EXPECT_FALSE(enums.Has(TEST_0));
-  EXPECT_FALSE(enums.Has(TEST_1));
-  EXPECT_FALSE(enums.Has(TEST_2));
-  EXPECT_TRUE(enums.Has(TEST_3));
-  EXPECT_FALSE(enums.Has(TEST_4));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_0));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_1));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_3));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_4));
 }
 
 TEST_F(EnumSetTest, TwoArgConstructor) {
-  const TestEnumSet enums(TEST_3, TEST_1);
+  const TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_1);
   EXPECT_FALSE(enums.Empty());
   EXPECT_EQ(static_cast<size_t>(2), enums.Size());
-  EXPECT_FALSE(enums.Has(TEST_0));
-  EXPECT_TRUE(enums.Has(TEST_1));
-  EXPECT_FALSE(enums.Has(TEST_2));
-  EXPECT_TRUE(enums.Has(TEST_3));
-  EXPECT_FALSE(enums.Has(TEST_4));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_0));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_1));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_3));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_4));
 }
 
 TEST_F(EnumSetTest, ThreeArgConstructor) {
-  const TestEnumSet enums(TEST_3, TEST_1, TEST_0);
+  const TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_1, TestEnum::TEST_0);
   EXPECT_FALSE(enums.Empty());
   EXPECT_EQ(static_cast<size_t>(3), enums.Size());
-  EXPECT_TRUE(enums.Has(TEST_0));
-  EXPECT_TRUE(enums.Has(TEST_1));
-  EXPECT_FALSE(enums.Has(TEST_2));
-  EXPECT_TRUE(enums.Has(TEST_3));
-  EXPECT_FALSE(enums.Has(TEST_4));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_0));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_1));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_3));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_4));
 }
 
 TEST_F(EnumSetTest, DuplicatesInConstructor) {
-  EXPECT_EQ(TestEnumSet(TEST_3, TEST_1, TEST_0, TEST_3, TEST_1, TEST_3),
-            TestEnumSet(TEST_0, TEST_1, TEST_3));
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_3, TestEnum::TEST_1, TestEnum::TEST_0,
+                        TestEnum::TEST_3, TestEnum::TEST_1, TestEnum::TEST_3),
+            TestEnumSet(TestEnum::TEST_0, TestEnum::TEST_1, TestEnum::TEST_3));
 }
 
 TEST_F(EnumSetTest, All) {
   const TestEnumSet enums(TestEnumSet::All());
   EXPECT_FALSE(enums.Empty());
   EXPECT_EQ(static_cast<size_t>(5), enums.Size());
-  EXPECT_TRUE(enums.Has(TEST_0));
-  EXPECT_TRUE(enums.Has(TEST_1));
-  EXPECT_TRUE(enums.Has(TEST_2));
-  EXPECT_TRUE(enums.Has(TEST_3));
-  EXPECT_TRUE(enums.Has(TEST_4));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_0));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_1));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_2));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_3));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_4));
 }
 
 TEST_F(EnumSetTest, FromRange) {
-  EXPECT_EQ(TestEnumSet(TEST_1, TEST_2, TEST_3),
-            TestEnumSet::FromRange(TEST_1, TEST_3));
-  EXPECT_EQ(TestEnumSet::All(), TestEnumSet::FromRange(TEST_0, TEST_4));
-  EXPECT_EQ(TestEnumSet(TEST_1), TestEnumSet::FromRange(TEST_1, TEST_1));
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_1, TestEnum::TEST_2, TestEnum::TEST_3),
+            TestEnumSet::FromRange(TestEnum::TEST_1, TestEnum::TEST_3));
+  EXPECT_EQ(TestEnumSet::All(),
+            TestEnumSet::FromRange(TestEnum::TEST_0, TestEnum::TEST_4));
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_1),
+            TestEnumSet::FromRange(TestEnum::TEST_1, TestEnum::TEST_1));
 
-  using RestrictedRangeSet = EnumSet<TestEnum, TEST_1, TEST_MAX>;
-  EXPECT_EQ(RestrictedRangeSet(TEST_1, TEST_2, TEST_3),
-            RestrictedRangeSet::FromRange(TEST_1, TEST_3));
+  using RestrictedRangeSet =
+      EnumSet<TestEnum, TestEnum::TEST_1, TestEnum::TEST_MAX>;
+  EXPECT_EQ(
+      RestrictedRangeSet(TestEnum::TEST_1, TestEnum::TEST_2, TestEnum::TEST_3),
+      RestrictedRangeSet::FromRange(TestEnum::TEST_1, TestEnum::TEST_3));
   EXPECT_EQ(RestrictedRangeSet::All(),
-            RestrictedRangeSet::FromRange(TEST_1, TEST_4));
+            RestrictedRangeSet::FromRange(TestEnum::TEST_1, TestEnum::TEST_4));
 }
 
 TEST_F(EnumSetTest, Put) {
-  TestEnumSet enums(TEST_3);
-  enums.Put(TEST_2);
-  EXPECT_EQ(TestEnumSet(TEST_2, TEST_3), enums);
-  enums.Put(TEST_4);
-  EXPECT_EQ(TestEnumSet(TEST_2, TEST_3, TEST_4), enums);
+  TestEnumSet enums(TestEnum::TEST_3);
+  enums.Put(TestEnum::TEST_2);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_2, TestEnum::TEST_3), enums);
+  enums.Put(TestEnum::TEST_4);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_2, TestEnum::TEST_3, TestEnum::TEST_4),
+            enums);
 }
 
 TEST_F(EnumSetTest, PutAll) {
-  TestEnumSet enums(TEST_3, TEST_4);
-  enums.PutAll(TestEnumSet(TEST_2, TEST_3));
-  EXPECT_EQ(TestEnumSet(TEST_2, TEST_3, TEST_4), enums);
+  TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_4);
+  enums.PutAll(TestEnumSet(TestEnum::TEST_2, TestEnum::TEST_3));
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_2, TestEnum::TEST_3, TestEnum::TEST_4),
+            enums);
 }
 
 TEST_F(EnumSetTest, PutRange) {
   TestEnumSet enums;
-  enums.PutRange(TEST_1, TEST_3);
-  EXPECT_EQ(TestEnumSet(TEST_1, TEST_2, TEST_3), enums);
+  enums.PutRange(TestEnum::TEST_1, TestEnum::TEST_3);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_1, TestEnum::TEST_2, TestEnum::TEST_3),
+            enums);
 }
 
 TEST_F(EnumSetTest, RetainAll) {
-  TestEnumSet enums(TEST_3, TEST_4);
-  enums.RetainAll(TestEnumSet(TEST_2, TEST_3));
-  EXPECT_EQ(TestEnumSet(TEST_3), enums);
+  TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_4);
+  enums.RetainAll(TestEnumSet(TestEnum::TEST_2, TestEnum::TEST_3));
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_3), enums);
 }
 
 TEST_F(EnumSetTest, Remove) {
-  TestEnumSet enums(TEST_3, TEST_4);
-  enums.Remove(TEST_0);
-  enums.Remove(TEST_2);
-  EXPECT_EQ(TestEnumSet(TEST_3, TEST_4), enums);
-  enums.Remove(TEST_3);
-  EXPECT_EQ(TestEnumSet(TEST_4), enums);
-  enums.Remove(TEST_4);
-  enums.Remove(TEST_5);
+  TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_4);
+  enums.Remove(TestEnum::TEST_0);
+  enums.Remove(TestEnum::TEST_2);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_3, TestEnum::TEST_4), enums);
+  enums.Remove(TestEnum::TEST_3);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_4), enums);
+  enums.Remove(TestEnum::TEST_4);
+  enums.Remove(TestEnum::TEST_5);
   EXPECT_TRUE(enums.Empty());
 }
 
 TEST_F(EnumSetTest, RemoveAll) {
-  TestEnumSet enums(TEST_3, TEST_4);
-  enums.RemoveAll(TestEnumSet(TEST_2, TEST_3));
-  EXPECT_EQ(TestEnumSet(TEST_4), enums);
+  TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_4);
+  enums.RemoveAll(TestEnumSet(TestEnum::TEST_2, TestEnum::TEST_3));
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_4), enums);
 }
 
 TEST_F(EnumSetTest, Clear) {
-  TestEnumSet enums(TEST_3, TEST_4);
+  TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_4);
   enums.Clear();
   EXPECT_TRUE(enums.Empty());
 }
 
 TEST_F(EnumSetTest, Has) {
-  const TestEnumSet enums(TEST_3, TEST_4);
-  EXPECT_FALSE(enums.Has(TEST_0));
-  EXPECT_FALSE(enums.Has(TEST_1));
-  EXPECT_FALSE(enums.Has(TEST_2));
-  EXPECT_TRUE(enums.Has(TEST_3));
-  EXPECT_TRUE(enums.Has(TEST_4));
-  EXPECT_FALSE(enums.Has(TEST_5));
+  const TestEnumSet enums(TestEnum::TEST_3, TestEnum::TEST_4);
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_0));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_1));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_3));
+  EXPECT_TRUE(enums.Has(TestEnum::TEST_4));
+  EXPECT_FALSE(enums.Has(TestEnum::TEST_5));
 }
 
 TEST_F(EnumSetTest, HasAll) {
-  const TestEnumSet enums1(TEST_3, TEST_4);
-  const TestEnumSet enums2(TEST_2, TEST_3);
+  const TestEnumSet enums1(TestEnum::TEST_3, TestEnum::TEST_4);
+  const TestEnumSet enums2(TestEnum::TEST_2, TestEnum::TEST_3);
   const TestEnumSet enums3 = Union(enums1, enums2);
   EXPECT_TRUE(enums1.HasAll(enums1));
   EXPECT_FALSE(enums1.HasAll(enums2));
@@ -195,7 +204,7 @@
 }
 
 TEST_F(EnumSetTest, Iterators) {
-  const TestEnumSet enums1(TEST_3, TEST_4);
+  const TestEnumSet enums1(TestEnum::TEST_3, TestEnum::TEST_4);
   TestEnumSet enums2;
   for (TestEnumSet::Iterator it = enums1.begin(); it != enums1.end(); it++) {
     enums2.Put(*it);
@@ -204,7 +213,8 @@
 }
 
 TEST_F(EnumSetTest, RangeBasedForLoop) {
-  const TestEnumSet enums1(TEST_1, TEST_4, TEST_5);
+  const TestEnumSet enums1(TestEnum::TEST_1, TestEnum::TEST_4,
+                           TestEnum::TEST_5);
   TestEnumSet enums2;
   for (TestEnum e : enums1) {
     enums2.Put(e);
@@ -213,7 +223,7 @@
 }
 
 TEST_F(EnumSetTest, IteratorComparisonOperators) {
-  const TestEnumSet enums(TEST_1, TEST_3, TEST_5);
+  const TestEnumSet enums(TestEnum::TEST_1, TestEnum::TEST_3, TestEnum::TEST_5);
   const auto first_it = enums.begin();
   const auto second_it = ++enums.begin();
 
@@ -234,7 +244,7 @@
 }
 
 TEST_F(EnumSetTest, IteratorIncrementOperators) {
-  const TestEnumSet enums(TEST_1, TEST_3, TEST_5);
+  const TestEnumSet enums(TestEnum::TEST_1, TestEnum::TEST_3, TestEnum::TEST_5);
   const auto begin = enums.begin();
 
   auto post_inc_it = begin;
@@ -265,27 +275,28 @@
 }
 
 TEST_F(EnumSetTest, Union) {
-  const TestEnumSet enums1(TEST_3, TEST_4);
-  const TestEnumSet enums2(TEST_2, TEST_3);
+  const TestEnumSet enums1(TestEnum::TEST_3, TestEnum::TEST_4);
+  const TestEnumSet enums2(TestEnum::TEST_2, TestEnum::TEST_3);
   const TestEnumSet enums3 = Union(enums1, enums2);
 
-  EXPECT_EQ(TestEnumSet(TEST_2, TEST_3, TEST_4), enums3);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_2, TestEnum::TEST_3, TestEnum::TEST_4),
+            enums3);
 }
 
 TEST_F(EnumSetTest, Intersection) {
-  const TestEnumSet enums1(TEST_3, TEST_4);
-  const TestEnumSet enums2(TEST_2, TEST_3);
+  const TestEnumSet enums1(TestEnum::TEST_3, TestEnum::TEST_4);
+  const TestEnumSet enums2(TestEnum::TEST_2, TestEnum::TEST_3);
   const TestEnumSet enums3 = Intersection(enums1, enums2);
 
-  EXPECT_EQ(TestEnumSet(TEST_3), enums3);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_3), enums3);
 }
 
 TEST_F(EnumSetTest, Difference) {
-  const TestEnumSet enums1(TEST_3, TEST_4);
-  const TestEnumSet enums2(TEST_2, TEST_3);
+  const TestEnumSet enums1(TestEnum::TEST_3, TestEnum::TEST_4);
+  const TestEnumSet enums2(TestEnum::TEST_2, TestEnum::TEST_3);
   const TestEnumSet enums3 = Difference(enums1, enums2);
 
-  EXPECT_EQ(TestEnumSet(TEST_4), enums3);
+  EXPECT_EQ(TestEnumSet(TestEnum::TEST_4), enums3);
 }
 
 }  // namespace
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc
index a771388..3af491f 100644
--- a/components/sync/driver/about_sync_util.cc
+++ b/components/sync/driver/about_sync_util.cc
@@ -503,7 +503,8 @@
 
   // Encryption.
   if (service->IsSyncFeatureActive()) {
-    is_using_explicit_passphrase->Set(service->IsUsingSecondaryPassphrase());
+    is_using_explicit_passphrase->Set(
+        service->GetUserSettings()->IsUsingSecondaryPassphrase());
     is_passphrase_required->Set(
         service->GetUserSettings()->IsPassphraseRequired());
     passphrase_time->Set(
diff --git a/components/sync/driver/fake_sync_service.cc b/components/sync/driver/fake_sync_service.cc
index 18d2a51..94493dc5 100644
--- a/components/sync/driver/fake_sync_service.cc
+++ b/components/sync/driver/fake_sync_service.cc
@@ -90,14 +90,6 @@
   return error_;
 }
 
-bool FakeSyncService::IsPassphraseRequiredForDecryption() const {
-  return false;
-}
-
-bool FakeSyncService::IsUsingSecondaryPassphrase() const {
-  return false;
-}
-
 UserShare* FakeSyncService::GetUserShare() const {
   return user_share_.get();
 }
diff --git a/components/sync/driver/fake_sync_service.h b/components/sync/driver/fake_sync_service.h
index f83bdb2..54e2327 100644
--- a/components/sync/driver/fake_sync_service.h
+++ b/components/sync/driver/fake_sync_service.h
@@ -45,8 +45,6 @@
       override;
   bool IsSetupInProgress() const override;
   const GoogleServiceAuthError& GetAuthError() const override;
-  bool IsPassphraseRequiredForDecryption() const override;
-  bool IsUsingSecondaryPassphrase() const override;
   UserShare* GetUserShare() const override;
   void ReenableDatatype(ModelType type) override;
   void ReadyForStartChanged(syncer::ModelType type) override;
diff --git a/components/sync/driver/sync_policy_handler.cc b/components/sync/driver/sync_policy_handler.cc
index 84b8df8d..26105eb 100644
--- a/components/sync/driver/sync_policy_handler.cc
+++ b/components/sync/driver/sync_policy_handler.cc
@@ -23,7 +23,7 @@
   const base::Value* value = policies.GetValue(policy_name());
   bool disable_sync;
   if (value && value->GetAsBoolean(&disable_sync) && disable_sync)
-    prefs->SetValue(prefs::kSyncManaged, value->CreateDeepCopy());
+    prefs->SetValue(prefs::kSyncManaged, value->Clone());
 }
 
 }  // namespace syncer
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h
index b8121198..a69af93 100644
--- a/components/sync/driver/sync_service.h
+++ b/components/sync/driver/sync_service.h
@@ -301,18 +301,6 @@
   virtual bool HasObserver(const SyncServiceObserver* observer) const = 0;
 
   //////////////////////////////////////////////////////////////////////////////
-  // ENCRYPTION
-  //////////////////////////////////////////////////////////////////////////////
-
-  // Returns true if OnPassphraseRequired has been called for decryption and
-  // we have an encrypted data type enabled.
-  virtual bool IsPassphraseRequiredForDecryption() const = 0;
-
-  // Returns true if a secondary (explicit) passphrase is being used. Before the
-  // engine is initialized, this will always return false.
-  virtual bool IsUsingSecondaryPassphrase() const = 0;
-
-  //////////////////////////////////////////////////////////////////////////////
   // ACCESS TO INNER OBJECTS
   //////////////////////////////////////////////////////////////////////////////
 
diff --git a/components/sync/driver/sync_service_utils.cc b/components/sync/driver/sync_service_utils.cc
index 7cd72c3..a03cea8e 100644
--- a/components/sync/driver/sync_service_utils.cc
+++ b/components/sync/driver/sync_service_utils.cc
@@ -31,7 +31,7 @@
   // some data types are never encrypted (e.g. DEVICE_INFO), even if the
   // "encrypt everything" setting is enabled.
   if (sync_service->GetUserSettings()->GetEncryptedDataTypes().Has(type) &&
-      sync_service->IsUsingSecondaryPassphrase()) {
+      sync_service->GetUserSettings()->IsUsingSecondaryPassphrase()) {
     return UploadState::NOT_ACTIVE;
   }
 
diff --git a/components/sync/driver/test_sync_service.cc b/components/sync/driver/test_sync_service.cc
index 4ee9b849..7c8c326 100644
--- a/components/sync/driver/test_sync_service.cc
+++ b/components/sync/driver/test_sync_service.cc
@@ -83,10 +83,6 @@
   active_data_types_ = types;
 }
 
-void TestSyncService::SetIsUsingSecondaryPassphrase(bool enabled) {
-  using_secondary_passphrase_ = enabled;
-}
-
 void TestSyncService::SetLastCycleSnapshot(const SyncCycleSnapshot& snapshot) {
   last_cycle_snapshot_ = snapshot;
 }
@@ -110,7 +106,11 @@
 }
 
 void TestSyncService::SetPassphraseRequiredForDecryption(bool required) {
-  passphrase_required_for_decryption_ = required;
+  user_settings_.SetPassphraseRequiredForDecryption(required);
+}
+
+void TestSyncService::SetIsUsingSecondaryPassphrase(bool enabled) {
+  user_settings_.SetIsUsingSecondaryPassphrase(enabled);
 }
 
 SyncUserSettings* TestSyncService::GetUserSettings() {
@@ -188,14 +188,6 @@
   return false;
 }
 
-bool TestSyncService::IsPassphraseRequiredForDecryption() const {
-  return passphrase_required_for_decryption_;
-}
-
-bool TestSyncService::IsUsingSecondaryPassphrase() const {
-  return using_secondary_passphrase_;
-}
-
 UserShare* TestSyncService::GetUserShare() const {
   return nullptr;
 }
diff --git a/components/sync/driver/test_sync_service.h b/components/sync/driver/test_sync_service.h
index db392d0..11f10b94 100644
--- a/components/sync/driver/test_sync_service.h
+++ b/components/sync/driver/test_sync_service.h
@@ -36,7 +36,6 @@
   void SetFirstSetupComplete(bool first_setup_complete);
   void SetPreferredDataTypes(const ModelTypeSet& types);
   void SetActiveDataTypes(const ModelTypeSet& types);
-  void SetIsUsingSecondaryPassphrase(bool enabled);
   void SetLastCycleSnapshot(const SyncCycleSnapshot& snapshot);
   // Convenience versions of the above, for when the caller doesn't care about
   // the particular values in the snapshot, just whether there is one.
@@ -45,6 +44,7 @@
   void SetDetailedSyncStatus(bool engine_available, SyncStatus status);
   void SetPassphraseRequired(bool required);
   void SetPassphraseRequiredForDecryption(bool required);
+  void SetIsUsingSecondaryPassphrase(bool enabled);
 
   // SyncService implementation.
   syncer::SyncUserSettings* GetUserSettings() override;
@@ -75,9 +75,6 @@
   void RemoveObserver(SyncServiceObserver* observer) override;
   bool HasObserver(const SyncServiceObserver* observer) const override;
 
-  bool IsPassphraseRequiredForDecryption() const override;
-  bool IsUsingSecondaryPassphrase() const override;
-
   UserShare* GetUserShare() const override;
 
   SyncTokenStatus GetSyncTokenStatus() const override;
@@ -114,9 +111,6 @@
   ModelTypeSet preferred_data_types_;
   ModelTypeSet active_data_types_;
 
-  bool using_secondary_passphrase_ = false;
-  bool passphrase_required_for_decryption_ = false;
-
   bool detailed_sync_status_engine_available_ = false;
   SyncStatus detailed_sync_status_;
 
diff --git a/components/sync/driver/test_sync_user_settings.cc b/components/sync/driver/test_sync_user_settings.cc
index 21f61c8..85684d8 100644
--- a/components/sync/driver/test_sync_user_settings.cc
+++ b/components/sync/driver/test_sync_user_settings.cc
@@ -88,7 +88,7 @@
 void TestSyncUserSettings::EnableEncryptEverything() {}
 
 ModelTypeSet TestSyncUserSettings::GetEncryptedDataTypes() const {
-  if (!service_->IsUsingSecondaryPassphrase()) {
+  if (!IsUsingSecondaryPassphrase()) {
     // PASSWORDS are always encrypted.
     return ModelTypeSet(PASSWORDS);
   }
@@ -103,11 +103,11 @@
 }
 
 bool TestSyncUserSettings::IsPassphraseRequiredForDecryption() const {
-  return service_->IsPassphraseRequiredForDecryption();
+  return passphrase_required_for_decryption_;
 }
 
 bool TestSyncUserSettings::IsUsingSecondaryPassphrase() const {
-  return service_->IsUsingSecondaryPassphrase();
+  return using_secondary_passphrase_;
 }
 
 base::Time TestSyncUserSettings::GetExplicitPassphraseTime() const {
@@ -135,4 +135,12 @@
   passphrase_required_ = required;
 }
 
+void TestSyncUserSettings::SetPassphraseRequiredForDecryption(bool required) {
+  passphrase_required_for_decryption_ = required;
+}
+
+void TestSyncUserSettings::SetIsUsingSecondaryPassphrase(bool enabled) {
+  using_secondary_passphrase_ = enabled;
+}
+
 }  // namespace syncer
diff --git a/components/sync/driver/test_sync_user_settings.h b/components/sync/driver/test_sync_user_settings.h
index f2a3252f..83fde52 100644
--- a/components/sync/driver/test_sync_user_settings.h
+++ b/components/sync/driver/test_sync_user_settings.h
@@ -50,6 +50,8 @@
 
   void SetFirstSetupComplete(bool first_setup_complete);
   void SetPassphraseRequired(bool required);
+  void SetPassphraseRequiredForDecryption(bool required);
+  void SetIsUsingSecondaryPassphrase(bool enabled);
 
  private:
   TestSyncService* service_;
@@ -58,6 +60,8 @@
   bool sync_everything_enabled_ = true;
 
   bool passphrase_required_ = false;
+  bool passphrase_required_for_decryption_ = false;
+  bool using_secondary_passphrase_ = false;
 };
 
 }  // namespace syncer
diff --git a/components/sync/engine_impl/cycle/nudge_tracker.cc b/components/sync/engine_impl/cycle/nudge_tracker.cc
index fc224bbe..1b195d45 100644
--- a/components/sync/engine_impl/cycle/nudge_tracker.cc
+++ b/components/sync/engine_impl/cycle/nudge_tracker.cc
@@ -54,19 +54,19 @@
   ModelTypeSet protocol_types = ProtocolTypes();
   // Default initialize all the type trackers.
   for (ModelType type : protocol_types) {
-    type_trackers_.insert(
-        std::make_pair(type, std::make_unique<DataTypeTracker>()));
+    type_trackers_.emplace(type, std::make_unique<DataTypeTracker>());
   }
 }
 
 NudgeTracker::~NudgeTracker() {}
 
 bool NudgeTracker::IsSyncRequired() const {
-  if (IsRetryRequired())
+  if (IsRetryRequired()) {
     return true;
+  }
 
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->IsSyncRequired()) {
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->IsSyncRequired()) {
       return true;
     }
   }
@@ -75,14 +75,16 @@
 }
 
 bool NudgeTracker::IsGetUpdatesRequired() const {
-  if (invalidations_out_of_sync_)
+  if (invalidations_out_of_sync_) {
     return true;
+  }
 
-  if (IsRetryRequired())
+  if (IsRetryRequired()) {
     return true;
+  }
 
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->IsGetUpdatesRequired()) {
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->IsGetUpdatesRequired()) {
       return true;
     }
   }
@@ -90,26 +92,28 @@
 }
 
 bool NudgeTracker::IsRetryRequired() const {
-  if (sync_cycle_start_time_.is_null())
+  if (sync_cycle_start_time_.is_null()) {
     return false;
+  }
 
-  if (current_retry_time_.is_null())
+  if (current_retry_time_.is_null()) {
     return false;
+  }
 
   return current_retry_time_ <= sync_cycle_start_time_;
 }
 
 void NudgeTracker::RecordSuccessfulSyncCycle() {
   // If a retry was required, we've just serviced it.  Unset the flag.
-  if (IsRetryRequired())
+  if (IsRetryRequired()) {
     current_retry_time_ = base::TimeTicks();
+  }
 
   // A successful cycle while invalidations are enabled puts us back into sync.
   invalidations_out_of_sync_ = !invalidations_enabled_;
 
-  for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
-       it != type_trackers_.end(); ++it) {
-    it->second->RecordSuccessfulSyncCycle();
+  for (const auto& type_and_tracker : type_trackers_) {
+    type_and_tracker.second->RecordSuccessfulSyncCycle();
   }
 }
 
@@ -127,8 +131,9 @@
     if (type_delay.is_zero()) {
       type_delay = GetDefaultDelayForType(type, minimum_local_nudge_delay_);
     }
-    if (type_delay < delay)
+    if (type_delay < delay) {
       delay = type_delay;
+    }
   }
   return delay;
 }
@@ -191,15 +196,14 @@
 }
 
 void NudgeTracker::UpdateTypeThrottlingAndBackoffState() {
-  for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
-       it != type_trackers_.end(); ++it) {
-    it->second->UpdateThrottleOrBackoffState();
+  for (const auto& type_and_tracker : type_trackers_) {
+    type_and_tracker.second->UpdateThrottleOrBackoffState();
   }
 }
 
 bool NudgeTracker::IsAnyTypeBlocked() const {
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->IsBlocked()) {
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->IsBlocked()) {
       return true;
     }
   }
@@ -222,10 +226,11 @@
 
   // Return min of GetTimeUntilUnblock() values for all IsBlocked() types.
   base::TimeDelta time_until_next_unblock = base::TimeDelta::Max();
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->IsBlocked()) {
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->IsBlocked()) {
       time_until_next_unblock =
-          std::min(time_until_next_unblock, it->second->GetTimeUntilUnblock());
+          std::min(time_until_next_unblock,
+                   type_and_tracker.second->GetTimeUntilUnblock());
     }
   }
   DCHECK(!time_until_next_unblock.is_max());
@@ -242,9 +247,9 @@
 
 ModelTypeSet NudgeTracker::GetBlockedTypes() const {
   ModelTypeSet result;
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->IsBlocked()) {
-      result.Put(it->first);
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->IsBlocked()) {
+      result.Put(type_and_tracker.first);
     }
   }
   return result;
@@ -252,9 +257,9 @@
 
 ModelTypeSet NudgeTracker::GetNudgedTypes() const {
   ModelTypeSet result;
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->HasLocalChangePending()) {
-      result.Put(it->first);
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->HasLocalChangePending()) {
+      result.Put(type_and_tracker.first);
     }
   }
   return result;
@@ -262,9 +267,9 @@
 
 ModelTypeSet NudgeTracker::GetNotifiedTypes() const {
   ModelTypeSet result;
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->HasPendingInvalidation()) {
-      result.Put(it->first);
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->HasPendingInvalidation()) {
+      result.Put(type_and_tracker.first);
     }
   }
   return result;
@@ -272,9 +277,9 @@
 
 ModelTypeSet NudgeTracker::GetRefreshRequestedTypes() const {
   ModelTypeSet result;
-  for (auto it = type_trackers_.begin(); it != type_trackers_.end(); ++it) {
-    if (it->second->HasRefreshRequestPending()) {
-      result.Put(it->first);
+  for (const auto& type_and_tracker : type_trackers_) {
+    if (type_and_tracker.second->HasRefreshRequestPending()) {
+      result.Put(type_and_tracker.first);
     }
   }
   return result;
@@ -340,9 +345,8 @@
 }
 
 void NudgeTracker::SetHintBufferSize(size_t size) {
-  for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
-       it != type_trackers_.end(); ++it) {
-    it->second->UpdatePayloadBufferSize(size);
+  for (const auto& type_and_tracker : type_trackers_) {
+    type_and_tracker.second->UpdatePayloadBufferSize(size);
   }
 }
 
@@ -352,17 +356,20 @@
 
 void NudgeTracker::OnReceivedCustomNudgeDelays(
     const std::map<ModelType, base::TimeDelta>& delay_map) {
-  for (auto iter = delay_map.begin(); iter != delay_map.end(); ++iter) {
-    ModelType type = iter->first;
+  for (const auto& type_and_delay : delay_map) {
+    ModelType type = type_and_delay.first;
+    base::TimeDelta delay = type_and_delay.second;
     DCHECK(ProtocolTypes().Has(type));
     TypeTrackerMap::const_iterator type_iter = type_trackers_.find(type);
-    if (type_iter == type_trackers_.end())
+    if (type_iter == type_trackers_.end()) {
       continue;
+    }
+    DataTypeTracker* type_tracker = type_iter->second.get();
 
-    if (iter->second > minimum_local_nudge_delay_) {
-      type_iter->second->UpdateLocalNudgeDelay(iter->second);
+    if (delay > minimum_local_nudge_delay_) {
+      type_tracker->UpdateLocalNudgeDelay(delay);
     } else {
-      type_iter->second->UpdateLocalNudgeDelay(
+      type_tracker->UpdateLocalNudgeDelay(
           GetDefaultDelayForType(type, minimum_local_nudge_delay_));
     }
   }
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h
index 1470387f..81ded8d 100644
--- a/components/sync/protocol/proto_visitors.h
+++ b/components/sync/protocol/proto_visitors.h
@@ -488,10 +488,12 @@
   VISIT(invalidations_out_of_sync);
   VISIT(local_modification_nudges);
   VISIT(datatype_refresh_nudges);
+  VISIT(server_dropped_hints);
+  VISIT(initial_sync_in_progress);
+  VISIT(sync_for_resolve_conflict_in_progress);
 }
 
 VISIT_PROTO_FIELDS(const sync_pb::GetUpdatesCallerInfo& proto) {
-  VISIT_ENUM(source);
   VISIT(notifications_enabled);
 }
 
diff --git a/components/sync/user_events/user_event_service_impl.cc b/components/sync/user_events/user_event_service_impl.cc
index cc880cb..be026b2 100644
--- a/components/sync/user_events/user_event_service_impl.cc
+++ b/components/sync/user_events/user_event_service_impl.cc
@@ -12,6 +12,7 @@
 #include "base/time/time.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/sync/user_events/user_event_sync_bridge.h"
 
 using sync_pb::UserEventSpecifics;
@@ -105,7 +106,7 @@
   // secondary passphrase. Similarly, unless the Sync feature is enabled,
   // GetPreferredDataTypes() isn't meaningful.
   return sync_service_->IsEngineInitialized() &&
-         !sync_service_->IsUsingSecondaryPassphrase() &&
+         !sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase() &&
          sync_service_->IsSyncFeatureEnabled() &&
          sync_service_->GetPreferredDataTypes().Has(HISTORY_DELETE_DIRECTIVES);
 }
@@ -115,7 +116,7 @@
   // secondary passphrase. Similarly, unless the Sync feature is enabled,
   // GetPreferredDataTypes() isn't meaningful.
   return sync_service_->IsEngineInitialized() &&
-         !sync_service_->IsUsingSecondaryPassphrase() &&
+         !sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase() &&
          sync_service_->IsSyncFeatureEnabled() &&
          sync_service_->GetPreferredDataTypes().Has(USER_EVENTS);
 }
diff --git a/components/sync_ui_strings.grdp b/components/sync_ui_strings.grdp
index 4247f22..c475131 100644
--- a/components/sync_ui_strings.grdp
+++ b/components/sync_ui_strings.grdp
@@ -52,10 +52,24 @@
     <message name="IDS_SYNC_SERVICE_UNAVAILABLE" desc="Error message to display when the user domain entered by the user has sync disabled.">
       Sync is not available for your domain
     </message>
+    <message name="IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE" desc="Instructions for the dialog where the user enters their Sync passphrase.">
+    Your data was encrypted with your <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>sync passphrase<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="TIME">$2<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+    </message>
+    <message name="IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE" desc="Instructions for the dialog where the user needs to enter their previous google passphrase.">
+        Your data was encrypted with your <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Google password<ph name="END_LINK">&lt;/a&gt;</ph> as of <ph name="TIME">$2<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+    </message>
   </if>
-  <message name="IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE" desc="Instructions for the dialog where the user enters the passphrase.">
-    Your data was encrypted with your sync passphrase on <ph name="TIME">$1<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
-  </message>
+
+  <if expr="is_android">
+    <message name="IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID" desc="Instructions for the dialog where the user enters their Sync passphrase.">
+      Your data was encrypted with your <ph name="BEGIN_LINK">&lt;learnmore&gt;</ph>sync passphrase<ph name="END_LINK">&lt;/learnmore&gt;</ph> on <ph name="TIME">$1<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+    </message>
+    <message name="IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE_ANDROID" desc="Instructions for the dialog where the user needs to enter their previous google passphrase.">
+        Your data was encrypted with your <ph name="BEGIN_LINK">&lt;learnmore&gt;</ph>Google password<ph name="END_LINK">&lt;/learnmore&gt;</ph> as of <ph name="TIME">$1<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+    </message>
+
+  </if>
+
   <message name="IDS_SYNC_ENTER_PASSPHRASE_BODY" desc="Instructions for the dialog where the user enters the passphrase.">
     Your data is encrypted with your sync passphrase. Enter it to start sync.
   </message>
diff --git a/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE.png.sha1 b/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE.png.sha1
new file mode 100644
index 0000000..d591a93
--- /dev/null
+++ b/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE.png.sha1
@@ -0,0 +1 @@
+65f9fcb54fd03b79fcb9c349165115ba3ce192ea
\ No newline at end of file
diff --git a/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID.png.sha1 b/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID.png.sha1
new file mode 100644
index 0000000..085de346
--- /dev/null
+++ b/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID.png.sha1
@@ -0,0 +1 @@
+874727fdb430be8fa0f9565dcaa63bbbc6c796f6
\ No newline at end of file
diff --git a/components/ukm/observers/sync_disable_observer.cc b/components/ukm/observers/sync_disable_observer.cc
index 58ef844..724d71c 100644
--- a/components/ukm/observers/sync_disable_observer.cc
+++ b/components/ukm/observers/sync_disable_observer.cc
@@ -11,6 +11,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "components/sync/driver/sync_token_status.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/sync/engine/connection_status.h"
 #include "components/unified_consent/feature.h"
 #include "components/unified_consent/url_keyed_data_collection_consent_helper.h"
@@ -113,7 +114,8 @@
                     status.connection_status == syncer::CONNECTION_OK;
 
   state.passphrase_protected =
-      state.initialized && sync_service->IsUsingSecondaryPassphrase();
+      state.initialized &&
+      sync_service->GetUserSettings()->IsUsingSecondaryPassphrase();
   if (consent_helper) {
     state.anonymized_data_collection_state =
         consent_helper->IsEnabled() ? DataCollectionState::kEnabled
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc
index ba137a4..92632c3 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -164,6 +164,11 @@
   static void Done(void* texture_context) {
     DCHECK(texture_context);
     auto* helper = static_cast<PromiseTextureHelper*>(texture_context);
+    if (helper->shared_image_) {
+      DCHECK(helper->impl_on_gpu_);
+      if (helper->impl_on_gpu_->was_context_lost())
+        helper->shared_image_->OnContextLost();
+    }
     delete helper;
   }
 
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index 92f1560..d5d4d38 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -142,6 +142,8 @@
   void DestroySkImages(std::vector<sk_sp<SkImage>>&& images,
                        uint64_t sync_fence_release);
 
+  bool was_context_lost() { return context_state_->context_lost(); }
+
  private:
 // gpu::ImageTransportSurfaceDelegate implementation:
 #if defined(OS_WIN)
diff --git a/components/webdata/common/web_database_service.h b/components/webdata/common/web_database_service.h
index 58ef763..c626320 100644
--- a/components/webdata/common/web_database_service.h
+++ b/components/webdata/common/web_database_service.h
@@ -107,7 +107,7 @@
   // be stored or called.
   void RegisterDBErrorCallback(const DBLoadErrorCallback& callback);
 
-  bool db_loaded() const { return db_loaded_; };
+  bool db_loaded() const { return db_loaded_; }
 
  private:
   class BackendDelegate;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 67a46af..b699b0c2 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2139,123 +2139,22 @@
       this, validated_url, error_code, error_description);
 }
 
-// Called when the renderer navigates.  For every frame loaded, we'll get this
-// notification containing parameters identifying the navigation.
 void RenderFrameHostImpl::DidCommitProvisionalLoad(
     std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
         validated_params,
     mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) {
-  if (GetNavigationHandle()) {
-    main_frame_request_ids_ = {validated_params->request_id,
-                               GetNavigationHandle()->GetGlobalRequestID()};
-    if (deferred_main_frame_load_info_)
-      ResourceLoadComplete(std::move(deferred_main_frame_load_info_));
-  }
-  // DidCommitProvisionalLoad IPC should be associated with the URL being
-  // committed (not with the *last* committed URL that most other IPCs are
-  // associated with).
-  ScopedActiveURL scoped_active_url(
-      validated_params->url,
-      frame_tree_node()->frame_tree()->root()->current_origin());
+  DidCommitNavigation(nullptr /* committing_navigation_request */,
+                      std::move(validated_params), std::move(interface_params));
+}
 
-  ScopedCommitStateResetter commit_state_resetter(this);
-  RenderProcessHost* process = GetProcess();
-
-  TRACE_EVENT2("navigation", "RenderFrameHostImpl::DidCommitProvisionalLoad",
-               "url", validated_params->url.possibly_invalid_spec(), "details",
-               CommitAsTracedValue(validated_params.get()));
-
-  // If we're waiting for a cross-site beforeunload ack from this renderer and
-  // we receive a Navigate message from the main frame, then the renderer was
-  // navigating already and sent it before hearing the FrameMsg_Stop message.
-  // Treat this as an implicit beforeunload ack to allow the pending navigation
-  // to continue.
-  if (is_waiting_for_beforeunload_ack_ && unload_ack_is_for_navigation_ &&
-      !GetParent()) {
-    base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_;
-    ProcessBeforeUnloadACK(true /* proceed */, true /* treat_as_final_ack */,
-                           approx_renderer_start_time, base::TimeTicks::Now());
-  }
-
-  // If we're waiting for an unload ack from this frame and we receive a commit
-  // message, then the frame was navigating before it received the unload
-  // request.  It will either respond to the unload request soon or our timer
-  // will expire.  Either way, we should ignore this message, because we have
-  // already committed to destroying this RenderFrameHost.  Note that we
-  // intentionally do not ignore commits that happen while the current tab is
-  // being closed - see https://crbug.com/805705.
-  if (is_waiting_for_swapout_ack_)
-    return;
-
-  // Retroactive sanity check:
-  // - If this is the first real load committing in this frame, then by this
-  //   time the RenderFrameHost's InterfaceProvider implementation should have
-  //   already been bound to a message pipe whose client end is used to service
-  //   interface requests from the initial empty document.
-  // - Otherwise, the InterfaceProvider implementation should at this point be
-  //   bound to an interface connection servicing interface requests coming from
-  //   the document of the previously committed navigation.
-  DCHECK(document_scoped_interface_provider_binding_.is_bound());
-  if (interface_params) {
-    // As a general rule, expect the RenderFrame to have supplied the
-    // request end of a new InterfaceProvider connection that will be used by
-    // the new document to issue interface requests to access RenderFrameHost
-    // services.
-    auto interface_provider_request_of_previous_document =
-        document_scoped_interface_provider_binding_.Unbind();
-    dropped_interface_request_logger_ =
-        std::make_unique<DroppedInterfaceRequestLogger>(
-            std::move(interface_provider_request_of_previous_document));
-    BindInterfaceProviderRequest(
-        std::move(interface_params->interface_provider_request));
-
-    document_interface_broker_content_binding_.Close();
-    document_interface_broker_blink_binding_.Close();
-    BindDocumentInterfaceBrokerRequest(
-        std::move(interface_params->document_interface_broker_content_request),
-        std::move(interface_params->document_interface_broker_blink_request));
-
-  } else {
-    // If there had already been a real load committed in the frame, and this is
-    // not a same-document navigation, then both the active document as well as
-    // the global object was replaced in this browsing context. The RenderFrame
-    // should have rebound its InterfaceProvider to a new pipe, but failed to do
-    // so. Kill the renderer, and close the old binding to ensure that any
-    // pending interface requests originating from the previous document, hence
-    // possibly from a different security origin, will no longer be dispatched.
-    if (frame_tree_node_->has_committed_real_load()) {
-      document_scoped_interface_provider_binding_.Close();
-      document_interface_broker_content_binding_.Close();
-      document_interface_broker_blink_binding_.Close();
-      bad_message::ReceivedBadMessage(
-          process, bad_message::RFH_INTERFACE_PROVIDER_MISSING);
-      return;
-    }
-
-    // Otherwise, it is the first real load commited, for which the RenderFrame
-    // is allowed to, and will re-use the existing InterfaceProvider connection
-    // if the new document is same-origin with the initial empty document, and
-    // therefore the global object is not replaced.
-  }
-
-  if (!DidCommitNavigationInternal(validated_params.get(),
-                                   false /* is_same_document_navigation */))
-    return;
-
-  // Since we didn't early return, it's safe to keep the commit state.
-  commit_state_resetter.disable();
-
-  // For a top-level frame, there are potential security concerns associated
-  // with displaying graphics from a previously loaded page after the URL in
-  // the omnibar has been changed. It is unappealing to clear the page
-  // immediately, but if the renderer is taking a long time to issue any
-  // compositor output (possibly because of script deliberately creating this
-  // situation) then we clear it after a while anyway.
-  // See https://crbug.com/497588.
-  if (frame_tree_node_->IsMainFrame() && GetView()) {
-    RenderWidgetHostImpl::From(GetView()->GetRenderWidgetHost())
-        ->DidNavigate(validated_params->content_source_id);
-  }
+void RenderFrameHostImpl::DidCommitPerNavigationMojoInterfaceNavigation(
+    NavigationRequest* committing_navigation_request,
+    std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+        validated_params,
+    mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) {
+  DCHECK(committing_navigation_request);
+  DidCommitNavigation(committing_navigation_request,
+                      std::move(validated_params), std::move(interface_params));
 }
 
 void RenderFrameHostImpl::DidCommitSameDocumentNavigation(
@@ -2283,9 +2182,14 @@
                "frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url",
                validated_params->url.possibly_invalid_spec());
 
-  if (!DidCommitNavigationInternal(validated_params.get(),
-                                   true /* is_same_document_navigation*/))
+  // TODO(ahemery): We also create a NavigationRequest for browser initiated
+  // same document navigations, so implement the passing of this request to
+  // DidCommitNavigationInternal.
+  if (!DidCommitNavigationInternal(nullptr /* navigation_request */,
+                                   validated_params.get(),
+                                   true /* is_same_document_navigation*/)) {
     return;
+  }
 
   // Since we didn't early return, it's safe to keep the commit state.
   commit_state_resetter.disable();
@@ -5362,7 +5266,7 @@
 void RenderFrameHostImpl::UpdateSubresourceLoaderFactories() {
   DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
   // We only send loader factory bundle upon navigation, so
-  // bail out if the frame hasn't commited any yet.
+  // bail out if the frame hasn't committed any yet.
   if (!has_committed_any_navigation_)
     return;
   DCHECK(!IsOutOfProcessNetworkService() ||
@@ -6200,6 +6104,7 @@
 }
 
 bool RenderFrameHostImpl::DidCommitNavigationInternal(
+    NavigationRequest* navigation_request,
     FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params,
     bool is_same_document_navigation) {
   // Sanity-check the page transition for frame type.
@@ -6223,23 +6128,35 @@
   if (navigation_request_)
     was_discarded_ = navigation_request_->commit_params().was_discarded;
 
-  // Find the appropriate NavigationRequest for this navigation.
-  std::unique_ptr<NavigationRequest> navigation_request;
-
-  if (is_same_document_navigation) {
-    navigation_request =
-        TakeNavigationRequestForSameDocumentCommit(*validated_params);
-  } else {
-    navigation_request = TakeNavigationRequestForCommit(*validated_params);
+  std::unique_ptr<NavigationRequest> committed_request;
+  // |navigation_request| is committed, we pass full ownership to the Navigator.
+  if (navigation_request) {
+    auto it = navigation_requests_.find(
+        navigation_request->navigation_handle()->GetNavigationId());
+    // If we provided a navigation_request and it committed, it should always
+    // be in the map.
+    CHECK(it != navigation_requests_.end());
+    committed_request = std::move(it->second);
+    navigation_requests_.erase(it);
   }
-  DCHECK(navigation_request);
-  DCHECK(navigation_request->navigation_handle());
+
+  if (!committed_request) {
+    if (is_same_document_navigation) {
+      committed_request =
+          TakeNavigationRequestForSameDocumentCommit(*validated_params);
+    } else {
+      committed_request = TakeNavigationRequestForCommit(*validated_params);
+    }
+  }
+
+  DCHECK(committed_request);
+  DCHECK(committed_request->navigation_handle());
 
   UpdateSiteURL(validated_params->url, validated_params->url_is_unreachable);
 
   accessibility_reset_count_ = 0;
   frame_tree_node()->navigator()->DidNavigate(this, *validated_params,
-                                              std::move(navigation_request),
+                                              std::move(committed_request),
                                               is_same_document_navigation);
   if (!is_same_document_navigation)
     navigation_request_.reset();
@@ -6421,6 +6338,135 @@
   }
 }
 
+// Called when the renderer navigates.  For every frame loaded, we'll get this
+// notification containing parameters identifying the navigation.
+void RenderFrameHostImpl::DidCommitNavigation(
+    NavigationRequest* committing_navigation_request,
+    std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+        validated_params,
+    mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) {
+  NavigationHandleImpl* navigation_handle;
+  if (committing_navigation_request) {
+    navigation_handle = committing_navigation_request->navigation_handle();
+  } else {
+    navigation_handle = GetNavigationHandle();
+  }
+
+  if (navigation_handle) {
+    main_frame_request_ids_ = {validated_params->request_id,
+                               navigation_handle->GetGlobalRequestID()};
+    if (deferred_main_frame_load_info_)
+      ResourceLoadComplete(std::move(deferred_main_frame_load_info_));
+  }
+  // DidCommitProvisionalLoad IPC should be associated with the URL being
+  // committed (not with the *last* committed URL that most other IPCs are
+  // associated with).
+  ScopedActiveURL scoped_active_url(
+      validated_params->url,
+      frame_tree_node()->frame_tree()->root()->current_origin());
+
+  ScopedCommitStateResetter commit_state_resetter(this);
+  RenderProcessHost* process = GetProcess();
+
+  TRACE_EVENT2("navigation", "RenderFrameHostImpl::DidCommitProvisionalLoad",
+               "url", validated_params->url.possibly_invalid_spec(), "details",
+               CommitAsTracedValue(validated_params.get()));
+
+  // If we're waiting for a cross-site beforeunload ack from this renderer and
+  // we receive a Navigate message from the main frame, then the renderer was
+  // navigating already and sent it before hearing the FrameMsg_Stop message.
+  // Treat this as an implicit beforeunload ack to allow the pending navigation
+  // to continue.
+  if (is_waiting_for_beforeunload_ack_ && unload_ack_is_for_navigation_ &&
+      !GetParent()) {
+    base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_;
+    ProcessBeforeUnloadACK(true /* proceed */, true /* treat_as_final_ack */,
+                           approx_renderer_start_time, base::TimeTicks::Now());
+  }
+
+  // If we're waiting for an unload ack from this frame and we receive a commit
+  // message, then the frame was navigating before it received the unload
+  // request.  It will either respond to the unload request soon or our timer
+  // will expire.  Either way, we should ignore this message, because we have
+  // already committed to destroying this RenderFrameHost.  Note that we
+  // intentionally do not ignore commits that happen while the current tab is
+  // being closed - see https://crbug.com/805705.
+  if (is_waiting_for_swapout_ack_)
+    return;
+
+  // Retroactive sanity check:
+  // - If this is the first real load committing in this frame, then by this
+  //   time the RenderFrameHost's InterfaceProvider implementation should have
+  //   already been bound to a message pipe whose client end is used to service
+  //   interface requests from the initial empty document.
+  // - Otherwise, the InterfaceProvider implementation should at this point be
+  //   bound to an interface connection servicing interface requests coming from
+  //   the document of the previously committed navigation.
+  DCHECK(document_scoped_interface_provider_binding_.is_bound());
+  if (interface_params) {
+    // As a general rule, expect the RenderFrame to have supplied the
+    // request end of a new InterfaceProvider connection that will be used by
+    // the new document to issue interface requests to access RenderFrameHost
+    // services.
+    auto interface_provider_request_of_previous_document =
+        document_scoped_interface_provider_binding_.Unbind();
+    dropped_interface_request_logger_ =
+        std::make_unique<DroppedInterfaceRequestLogger>(
+            std::move(interface_provider_request_of_previous_document));
+    BindInterfaceProviderRequest(
+        std::move(interface_params->interface_provider_request));
+
+    document_interface_broker_content_binding_.Close();
+    document_interface_broker_blink_binding_.Close();
+    BindDocumentInterfaceBrokerRequest(
+        std::move(interface_params->document_interface_broker_content_request),
+        std::move(interface_params->document_interface_broker_blink_request));
+
+  } else {
+    // If there had already been a real load committed in the frame, and this is
+    // not a same-document navigation, then both the active document as well as
+    // the global object was replaced in this browsing context. The RenderFrame
+    // should have rebound its InterfaceProvider to a new pipe, but failed to do
+    // so. Kill the renderer, and close the old binding to ensure that any
+    // pending interface requests originating from the previous document, hence
+    // possibly from a different security origin, will no longer be dispatched.
+    if (frame_tree_node_->has_committed_real_load()) {
+      document_scoped_interface_provider_binding_.Close();
+      document_interface_broker_content_binding_.Close();
+      document_interface_broker_blink_binding_.Close();
+      bad_message::ReceivedBadMessage(
+          process, bad_message::RFH_INTERFACE_PROVIDER_MISSING);
+      return;
+    }
+
+    // Otherwise, it is the first real load committed, for which the RenderFrame
+    // is allowed to, and will re-use the existing InterfaceProvider connection
+    // if the new document is same-origin with the initial empty document, and
+    // therefore the global object is not replaced.
+  }
+
+  if (!DidCommitNavigationInternal(committing_navigation_request,
+                                   validated_params.get(),
+                                   false /* is_same_document_navigation */)) {
+    return;
+  }
+
+  // Since we didn't early return, it's safe to keep the commit state.
+  commit_state_resetter.disable();
+
+  // For a top-level frame, there are potential security concerns associated
+  // with displaying graphics from a previously loaded page after the URL in
+  // the omnibar has been changed. It is unappealing to clear the page
+  // immediately, but if the renderer is taking a long time to issue any
+  // compositor output (possibly because of script deliberately creating this
+  // situation) then we clear it after a while anyway.
+  // See https://crbug.com/497588.
+  if (frame_tree_node_->IsMainFrame() && GetView()) {
+    RenderWidgetHostImpl::From(GetView()->GetRenderWidgetHost())
+        ->DidNavigate(validated_params->content_source_id);
+  }
+}
+
 mojom::FrameNavigationControl::CommitNavigationCallback
 RenderFrameHostImpl::BuildCommitNavigationCallback(
     NavigationRequest* navigation_request) {
@@ -6448,9 +6494,8 @@
     NavigationRequest* navigation_request) {
   DCHECK(navigation_request);
   return base::BindOnce(
-      &RenderFrameHostImpl::OnCrossDocumentCommitProcessed,
-      base::Unretained(this),
-      navigation_request->navigation_handle()->GetNavigationId());
+      &RenderFrameHostImpl::DidCommitPerNavigationMojoInterfaceNavigation,
+      base::Unretained(this), navigation_request);
 }
 
 mojom::NavigationClient::CommitFailedNavigationCallback
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 180d0f0e..57296a8 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1118,6 +1118,17 @@
           validated_params,
       mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params)
       override;
+
+  // This function mimics DidCommitProvisionalLoad but is a direct mojo
+  // callback from NavigationClient::CommitNavigation.
+  // This only used when PerNavigationMojoInterface is enabled, and will
+  // replace DidCommitProvisionalLoad in the long run.
+  void DidCommitPerNavigationMojoInterfaceNavigation(
+      NavigationRequest* committing_navigation_request,
+      std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+          validated_params,
+      mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params);
+
   void DidCommitSameDocumentNavigation(
       std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
           validated_params) override;
@@ -1408,12 +1419,21 @@
   // an interstitial.
   void UpdateSiteURL(const GURL& url, bool url_is_unreachable);
 
+  // The actual implementation of DidCommitProvisionalLoad and
+  // DidCommitPerNavigationMojoInterfaceNavigation.
+  void DidCommitNavigation(
+      NavigationRequest* committing_navigation_request,
+      std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+          validated_params,
+      mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params);
+
   // Called when we receive the confirmation that a navigation committed in the
   // renderer. Used by both DidCommitSameDocumentNavigation and
   // DidCommitNavigation.
   // Returns true if the navigation did commit properly, false if the commit
   // state should be restored to its pre-commit value.
   bool DidCommitNavigationInternal(
+      NavigationRequest* navigation_request,
       FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params,
       bool is_same_document_navigation);
 
@@ -1686,6 +1706,12 @@
   // indexed by IDs. These are navigations that have passed ReadyToCommit stage
   // and are waiting for the renderer to send back a matching
   // OnCrossDocumentCommitProcessed.
+
+  // TODO(ahemery): We have this storage as a map because we actually want to
+  // find navigations by id with PerNavigationMojoInterface disabled.
+  // When the flag is always on, rework the structure to simply store an
+  // unindexed bunch of ongoing navigations and modify
+  // DidCommitNavigationInternal.
   std::map<int64_t, std::unique_ptr<NavigationRequest>> navigation_requests_;
 
   // Holds a same-document NavigationRequest while waiting for the navigation it
diff --git a/content/browser/media/session/media_session_service_impl_browsertest.cc b/content/browser/media/session/media_session_service_impl_browsertest.cc
index 1e7f3813..edd9e47 100644
--- a/content/browser/media/session/media_session_service_impl_browsertest.cc
+++ b/content/browser/media/session/media_session_service_impl_browsertest.cc
@@ -5,6 +5,7 @@
 #include "content/browser/media/session/media_session_service_impl.h"
 
 #include "base/command_line.h"
+#include "build/build_config.h"
 #include "content/browser/media/session/media_session_impl.h"
 #include "content/browser/media/session/media_session_player_observer.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -145,6 +146,10 @@
 // TODO(crbug.com/850870) Plug the leaks.
 #define MAYBE_ResetServiceWhenNavigatingAway \
   DISABLED_ResetServiceWhenNavigatingAway
+#elif defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX)
+// crbug.com/927234.
+#define MAYBE_ResetServiceWhenNavigatingAway \
+  DISABLED_ResetServiceWhenNavigatingAway
 #else
 #define MAYBE_ResetServiceWhenNavigatingAway ResetServiceWhenNavigatingAway
 #endif
@@ -175,8 +180,9 @@
 #define MAYBE_DontResetServiceForSameDocumentNavigation \
   DISABLED_DontResetServiceForSameDocumentNavigation
 #else
+// crbug.com/927234.
 #define MAYBE_DontResetServiceForSameDocumentNavigation \
-  DontResetServiceForSameDocumentNavigation
+  DISABLED_DontResetServiceForSameDocumentNavigation
 #endif
 IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
                        MAYBE_DontResetServiceForSameDocumentNavigation) {
diff --git a/content/browser/utility_process_host_browsertest.cc b/content/browser/utility_process_host_browsertest.cc
index 403e0853..2dbf010 100644
--- a/content/browser/utility_process_host_browsertest.cc
+++ b/content/browser/utility_process_host_browsertest.cc
@@ -153,7 +153,9 @@
 }
 
 #if defined(OS_WIN)
-IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest, LaunchElevatedProcess) {
+// Times out. crbug.com/927298.
+IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest,
+                       DISABLED_LaunchElevatedProcess) {
   RunUtilityProcess(true, false);
 }
 
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index e566a15..7abc0ae2 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -19,7 +19,6 @@
 import "services/service_manager/public/mojom/interface_provider.mojom";
 import "services/viz/public/interfaces/compositing/surface_id.mojom";
 import "third_party/blink/public/mojom/blob/blob_url_store.mojom";
-import "third_party/blink/public/mojom/frame/document_interface_broker.mojom";
 import "third_party/blink/public/mojom/feature_policy/feature_policy.mojom";
 import "third_party/blink/public/mojom/frame/navigation_initiator.mojom";
 import "third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom";
@@ -268,12 +267,6 @@
 // the frame is detached. Used by resource requests with "keepalive" specified.
 interface KeepAliveHandle {};
 
-struct DidCommitProvisionalLoadInterfaceParams {
-  service_manager.mojom.InterfaceProvider& interface_provider_request;
-  blink.mojom.DocumentInterfaceBroker& document_interface_broker_content_request;
-  blink.mojom.DocumentInterfaceBroker& document_interface_broker_blink_request;
-};
-
 // Implemented by the frame server (i.e. the browser process). For messages that
 // must be associated with the IPC channel.
 interface FrameHost {
diff --git a/content/common/frame_messages.mojom b/content/common/frame_messages.mojom
index e93e582..76a1e4a 100644
--- a/content/common/frame_messages.mojom
+++ b/content/common/frame_messages.mojom
@@ -4,6 +4,16 @@
 
 module content.mojom;
 
+import "services/service_manager/public/mojom/interface_provider.mojom";
+import "third_party/blink/public/mojom/frame/document_interface_broker.mojom";
+
 [Native]
 struct DidCommitProvisionalLoadParams;
 
+struct DidCommitProvisionalLoadInterfaceParams {
+  service_manager.mojom.InterfaceProvider& interface_provider_request;
+  blink.mojom.DocumentInterfaceBroker&
+      document_interface_broker_content_request;
+  blink.mojom.DocumentInterfaceBroker& document_interface_broker_blink_request;
+};
+
diff --git a/content/common/navigation_client.mojom b/content/common/navigation_client.mojom
index 64e54037..9fee08a7 100644
--- a/content/common/navigation_client.mojom
+++ b/content/common/navigation_client.mojom
@@ -6,6 +6,7 @@
 
 import "services/network/public/mojom/url_loader.mojom";
 import "services/network/public/mojom/url_loader_factory.mojom";
+import "content/common/frame_messages.mojom";
 import "content/public/common/transferrable_url_loader.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
 import "url/mojom/url.mojom";
@@ -62,7 +63,8 @@
       blink.mojom.ControllerServiceWorkerInfo? controller_service_worker_info,
       network.mojom.URLLoaderFactory? prefetch_loader_factory,
       mojo_base.mojom.UnguessableToken devtools_navigation_token)
-      => (blink.mojom.CommitResult commit_result);
+      => (DidCommitProvisionalLoadParams params,
+          DidCommitProvisionalLoadInterfaceParams? interface_params);
 
   // Tells the renderer that a failed navigation is ready to commit.
   //
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index c742644..e13b76bb 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -150,6 +150,7 @@
     "java/src/org/chromium/content/browser/SpeechRecognitionImpl.java",
     "java/src/org/chromium/content/browser/SyntheticGestureTarget.java",
     "java/src/org/chromium/content/browser/TracingControllerAndroidImpl.java",
+    "java/src/org/chromium/content/browser/UiThreadTaskTraitsImpl.java",
     "java/src/org/chromium/content/browser/ViewEventSinkImpl.java",
     "java/src/org/chromium/content/browser/WindowEventObserver.java",
     "java/src/org/chromium/content/browser/WindowEventObserverManager.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/UiThreadTaskTraitsImpl.java b/content/public/android/java/src/org/chromium/content/browser/UiThreadTaskTraitsImpl.java
new file mode 100644
index 0000000..f916245
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/UiThreadTaskTraitsImpl.java
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import org.chromium.base.task.TaskPriority;
+import org.chromium.base.task.TaskTraits;
+import org.chromium.content_public.browser.BrowserTaskExecutor;
+
+/**
+ * Provides the implementation needed in UiThreadTaskTraits.
+ */
+public class UiThreadTaskTraitsImpl {
+    private UiThreadTaskTraitsImpl() {}
+
+    // Corresponds to content::BrowserTaskTraitsExtension.
+    public static final byte EXTENSION_ID = 1;
+
+    // Keep in sync with content::BrowserTaskTraitsExtension::Serialize.
+    private static final byte NESTING_INDEX = 1;
+
+    private static final byte[] sDefaultExtensionData = getDefaultExtesionData();
+
+    public static final TaskTraits DEFAULT = new TaskTraits(EXTENSION_ID, sDefaultExtensionData);
+    public static final TaskTraits BEST_EFFORT = DEFAULT.taskPriority(TaskPriority.BEST_EFFORT);
+    public static final TaskTraits USER_VISIBLE = DEFAULT.taskPriority(TaskPriority.USER_VISIBLE);
+    public static final TaskTraits USER_BLOCKING = DEFAULT.taskPriority(TaskPriority.USER_BLOCKING);
+
+    static {
+        BrowserTaskExecutor.register();
+    }
+
+    private static byte[] getDefaultExtesionData() {
+        byte extensionData[] = new byte[TaskTraits.EXTENSION_STORAGE_SIZE];
+
+        // Note we don't specify the UI thread directly here because it's ID 0 and the array is
+        // initialized to zero.
+
+        // TODO(crbug.com/876272) Remove this if possible.
+        extensionData[NESTING_INDEX] = 1; // Allow the task to run in a nested RunLoop.
+        return extensionData;
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java b/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java
index 22c0aaa..2bca7dc 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java
@@ -12,6 +12,7 @@
 import org.chromium.base.task.TaskExecutor;
 import org.chromium.base.task.TaskRunner;
 import org.chromium.base.task.TaskTraits;
+import org.chromium.content.browser.UiThreadTaskTraitsImpl;
 
 import java.util.WeakHashMap;
 
@@ -60,7 +61,8 @@
         // In some tests we will get called multiple times.
         if (sRegistered) return;
 
-        PostTask.registerTaskExecutor(UiThreadTaskTraits.EXTENSION_ID, new BrowserTaskExecutor());
+        PostTask.registerTaskExecutor(
+                UiThreadTaskTraitsImpl.EXTENSION_ID, new BrowserTaskExecutor());
         sRegistered = true;
     }
 
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/UiThreadTaskTraits.java b/content/public/android/java/src/org/chromium/content_public/browser/UiThreadTaskTraits.java
index 5fb1659..9407606 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/UiThreadTaskTraits.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/UiThreadTaskTraits.java
@@ -5,6 +5,7 @@
 package org.chromium.content_public.browser;
 
 import org.chromium.base.task.TaskTraits;
+import org.chromium.content.browser.UiThreadTaskTraitsImpl;
 
 /**
  * Traits for tasks that need to run on the Browser UI thread. Keep in sync with
@@ -13,31 +14,12 @@
  * NB if you wish to post to the thread pool then use {@link TaskTraits} instead of {@link
  * UiThreadTaskTraits}.
  */
-public class UiThreadTaskTraits extends TaskTraits {
-    // Corresponds to content::BrowserTaskTraitsExtension.
-    static final byte EXTENSION_ID = 1;
+public class UiThreadTaskTraits {
+    private UiThreadTaskTraits() {}
 
-    private static final byte UI_THREAD_ID = 0; // Corresponds to content::BrowserThread::ID.
-
-    // Keep in sync with content::BrowserTaskTraitsExtension::Serialize.
-    private static final byte THREAD_INDEX = 0;
-    private static final byte NESTING_INDEX = 1;
-
-    private static final byte[] sDefaultExtensionData = getDefaultExtesionData();
-
-    public UiThreadTaskTraits() {
-        setExtensionId(EXTENSION_ID);
-        setExtensionData(sDefaultExtensionData);
-    }
-
-    private static byte[] getDefaultExtesionData() {
-        byte extensionData[] = new byte[TaskTraits.EXTENSION_STORAGE_SIZE];
-
-        // Note we don't specify the UI thread directly here because it's ID 0 and the array is
-        // initialized to zero.
-
-        // TODO(crbug.com/876272) Remove this if possible.
-        extensionData[NESTING_INDEX] = 1; // Allow the task to run in a nested RunLoop.
-        return extensionData;
-    }
+    // These are convenience constants for UI thread tasks at different priority levels.
+    public static final TaskTraits DEFAULT = UiThreadTaskTraitsImpl.DEFAULT;
+    public static final TaskTraits BEST_EFFORT = UiThreadTaskTraitsImpl.BEST_EFFORT;
+    public static final TaskTraits USER_VISIBLE = UiThreadTaskTraitsImpl.USER_VISIBLE;
+    public static final TaskTraits USER_BLOCKING = UiThreadTaskTraitsImpl.USER_BLOCKING;
 }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java
index 26042cc0..c7eb954 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java
@@ -63,7 +63,7 @@
     @MediumTest
     public void testSimpleUiThreadPostingBeforeNativeLoaded() throws Exception {
         TaskRunner uiThreadTaskRunner =
-                PostTask.createSingleThreadTaskRunner(new UiThreadTaskTraits());
+                PostTask.createSingleThreadTaskRunner(UiThreadTaskTraits.DEFAULT);
         try {
             List<Integer> orderList = new ArrayList<>();
             SchedulerTestHelpers.postRecordOrderTask(uiThreadTaskRunner, orderList, 1);
@@ -81,7 +81,7 @@
     @MediumTest
     public void testUiThreadTaskRunnerMigrationToNative() throws Exception {
         TaskRunner uiThreadTaskRunner =
-                PostTask.createSingleThreadTaskRunner(new UiThreadTaskTraits());
+                PostTask.createSingleThreadTaskRunner(UiThreadTaskTraits.DEFAULT);
         try {
             List<Integer> orderList = new ArrayList<>();
             SchedulerTestHelpers.postRecordOrderTask(uiThreadTaskRunner, orderList, 1);
@@ -103,8 +103,7 @@
     @MediumTest
     public void testSimpleUiThreadPostingAfterNativeLoaded() throws Exception {
         TaskRunner uiThreadTaskRunner =
-                PostTask.createSingleThreadTaskRunner(new UiThreadTaskTraits());
-
+                PostTask.createSingleThreadTaskRunner(UiThreadTaskTraits.DEFAULT);
         try {
             startContentMainOnUiThread();
 
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc
index ee0747e..2f14b11 100644
--- a/content/renderer/navigation_client.cc
+++ b/content/renderer/navigation_client.cc
@@ -32,7 +32,7 @@
   // race conditions leading to the early deletion of NavigationRequest would
   // unexpectedly abort the ongoing navigation. Remove when the races are fixed.
   ResetDisconnectionHandler();
-  render_frame_->CommitNavigation(
+  render_frame_->CommitPerNavigationMojoInterfaceNavigation(
       head, common_params, commit_params,
       std::move(url_loader_client_endpoints), std::move(subresource_loaders),
       std::move(subresource_overrides),
diff --git a/content/renderer/navigation_state.cc b/content/renderer/navigation_state.cc
index 14a24825..b7635f9d 100644
--- a/content/renderer/navigation_state.cc
+++ b/content/renderer/navigation_state.cc
@@ -4,7 +4,12 @@
 
 #include "content/renderer/navigation_state.h"
 
+#include <utility>
+
+#include "content/common/frame_messages.h"
+#include "content/public/common/navigation_policy.h"
 #include "content/renderer/internal_document_state_data.h"
+#include "third_party/blink/public/web/commit_result.mojom.h"
 
 namespace content {
 
@@ -18,10 +23,13 @@
     const CommitNavigationParams& commit_params,
     base::TimeTicks time_commit_requested,
     mojom::FrameNavigationControl::CommitNavigationCallback callback,
+    mojom::NavigationClient::CommitNavigationCallback
+        per_navigation_mojo_interface_callback,
     std::unique_ptr<NavigationClient> navigation_client) {
   return base::WrapUnique(new NavigationState(
       common_params, commit_params, time_commit_requested, false,
-      std::move(callback), std::move(navigation_client)));
+      std::move(callback), std::move(per_navigation_mojo_interface_callback),
+      std::move(navigation_client)));
 }
 
 // static
@@ -29,7 +37,7 @@
   return base::WrapUnique(new NavigationState(
       CommonNavigationParams(), CommitNavigationParams(), base::TimeTicks(),
       true, content::mojom::FrameNavigationControl::CommitNavigationCallback(),
-      nullptr));
+      content::mojom::NavigationClient::CommitNavigationCallback(), nullptr));
 }
 
 // static
@@ -53,12 +61,24 @@
     std::move(commit_callback_).Run(result);
 }
 
+void NavigationState::RunPerNavigationInterfaceCommitNavigationCallback(
+    std::unique_ptr<::FrameHostMsg_DidCommitProvisionalLoad_Params> params,
+    mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) {
+  DCHECK(IsPerNavigationMojoInterfaceEnabled());
+  if (per_navigation_mojo_interface_commit_callback_)
+    std::move(per_navigation_mojo_interface_commit_callback_)
+        .Run(std::move(params), std::move(interface_params));
+  navigation_client_.reset();
+}
+
 NavigationState::NavigationState(
     const CommonNavigationParams& common_params,
     const CommitNavigationParams& commit_params,
     base::TimeTicks time_commit_requested,
     bool is_content_initiated,
     mojom::FrameNavigationControl::CommitNavigationCallback callback,
+    mojom::NavigationClient::CommitNavigationCallback
+        per_navigation_mojo_interface_commit_callback,
     std::unique_ptr<NavigationClient> navigation_client)
     : request_committed_(false),
       was_within_same_document_(false),
@@ -67,6 +87,7 @@
       commit_params_(commit_params),
       time_commit_requested_(time_commit_requested),
       navigation_client_(std::move(navigation_client)),
-      commit_callback_(std::move(callback)) {}
-
+      commit_callback_(std::move(callback)),
+      per_navigation_mojo_interface_commit_callback_(
+          std::move(per_navigation_mojo_interface_commit_callback)) {}
 }  // namespace content
diff --git a/content/renderer/navigation_state.h b/content/renderer/navigation_state.h
index ea9ce006..418fc316 100644
--- a/content/renderer/navigation_state.h
+++ b/content/renderer/navigation_state.h
@@ -5,16 +5,22 @@
 #ifndef CONTENT_RENDERER_NAVIGATION_STATE_H_
 #define CONTENT_RENDERER_NAVIGATION_STATE_H_
 
-#include <string>
+#include <memory>
 
 #include "base/macros.h"
+#include "base/time/time.h"
 #include "content/common/frame.mojom.h"
 #include "content/common/navigation_params.h"
 #include "content/renderer/navigation_client.h"
-#include "third_party/blink/public/web/commit_result.mojom.h"
+
+struct FrameHostMsg_DidCommitProvisionalLoad_Params;
 
 namespace blink {
 class WebDocumentLoader;
+
+namespace mojom {
+enum class CommitResult;
+}
 }
 
 namespace content {
@@ -28,6 +34,8 @@
       const CommitNavigationParams& commit_params,
       base::TimeTicks time_commit_requested,
       mojom::FrameNavigationControl::CommitNavigationCallback callback,
+      mojom::NavigationClient::CommitNavigationCallback
+          per_navigation_mojo_interface_callback,
       std::unique_ptr<NavigationClient> navigation_client);
 
   static std::unique_ptr<NavigationState> CreateContentInitiated();
@@ -44,6 +52,9 @@
   const CommonNavigationParams& common_params() const { return common_params_; }
   const CommitNavigationParams& commit_params() const { return commit_params_; }
   bool request_committed() const { return request_committed_; }
+  bool uses_per_navigation_mojo_interface() const {
+    return navigation_client_.get();
+  }
   void set_request_committed(bool value) { request_committed_ = value; }
   void set_was_within_same_document(bool value) {
     was_within_same_document_ = value;
@@ -69,6 +80,10 @@
 
   void RunCommitNavigationCallback(blink::mojom::CommitResult result);
 
+  void RunPerNavigationInterfaceCommitNavigationCallback(
+      std::unique_ptr<::FrameHostMsg_DidCommitProvisionalLoad_Params> params,
+      mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params);
+
  private:
   NavigationState(
       const CommonNavigationParams& common_params,
@@ -76,6 +91,8 @@
       base::TimeTicks time_commit_requested,
       bool is_content_initiated,
       content::mojom::FrameNavigationControl::CommitNavigationCallback callback,
+      content::mojom::NavigationClient::CommitNavigationCallback
+          per_navigation_mojo_interface_callback,
       std::unique_ptr<NavigationClient> navigation_client);
 
   bool request_committed_;
@@ -111,6 +128,12 @@
   // successful or not.
   mojom::FrameNavigationControl::CommitNavigationCallback commit_callback_;
 
+  // Temporary member meant to be used in place of |commit_callback_| when
+  // PerNavigationMojoInterface is enabled. Should eventually replace it
+  // completely.
+  mojom::NavigationClient::CommitNavigationCallback
+      per_navigation_mojo_interface_commit_callback_;
+
   DISALLOW_COPY_AND_ASSIGN(NavigationState);
 };
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 0a9b65d..db91a60 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -815,6 +815,8 @@
     const CommitNavigationParams& commit_params,
     base::TimeTicks time_commit_requested,
     mojom::FrameNavigationControl::CommitNavigationCallback commit_callback,
+    mojom::NavigationClient::CommitNavigationCallback
+        per_navigation_mojo_interface_commit_callback,
     const network::ResourceResponseHead* head,
     std::unique_ptr<NavigationClient> navigation_client) {
   std::unique_ptr<DocumentState> document_state(new DocumentState());
@@ -875,7 +877,9 @@
   InternalDocumentStateData::FromDocumentState(document_state.get())
       ->set_navigation_state(NavigationState::CreateBrowserInitiated(
           common_params, commit_params, time_commit_requested,
-          std::move(commit_callback), std::move(navigation_client)));
+          std::move(commit_callback),
+          std::move(per_navigation_mojo_interface_commit_callback),
+          std::move(navigation_client)));
   return document_state;
 }
 
@@ -2833,7 +2837,8 @@
     document_state = BuildDocumentStateFromParams(
         navigation_state->common_params(), navigation_state->commit_params(),
         base::TimeTicks(),  // Not used for failed navigation.
-        CommitNavigationCallback(), nullptr, nullptr);
+        mojom::FrameNavigationControl::CommitNavigationCallback(),
+        mojom::NavigationClient::CommitNavigationCallback(), nullptr, nullptr);
     FillMiscNavigationParams(navigation_state->common_params(),
                              navigation_state->commit_params(),
                              navigation_params.get());
@@ -3203,7 +3208,62 @@
     blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
     network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
     const base::UnguessableToken& devtools_navigation_token,
-    CommitNavigationCallback callback) {
+    CommitNavigationCallback commit_callback) {
+  DCHECK(!navigation_client_impl_);
+  // We can have a FrameNavigationControl::CommitNavigation with
+  // IsPerNavigationMojoInterfaceEnabled() == true, for non-committed
+  // interstitials where no NavigationRequest was created. Therefore, no DCHECK.
+  CommitNavigationInternal(
+      head, common_params, commit_params,
+      std::move(url_loader_client_endpoints),
+      std::move(subresource_loader_factories), std::move(subresource_overrides),
+      std::move(controller_service_worker_info),
+      std::move(prefetch_loader_factory), devtools_navigation_token,
+      std::move(commit_callback),
+      mojom::NavigationClient::CommitNavigationCallback());
+}
+
+void RenderFrameImpl::CommitPerNavigationMojoInterfaceNavigation(
+    const network::ResourceResponseHead& head,
+    const CommonNavigationParams& common_params,
+    const CommitNavigationParams& commit_params,
+    network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+        subresource_loader_factories,
+    base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
+        subresource_overrides,
+    blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
+    network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+    const base::UnguessableToken& devtools_navigation_token,
+    mojom::NavigationClient::CommitNavigationCallback
+        per_navigation_mojo_interface_callback) {
+  DCHECK(navigation_client_impl_);
+  DCHECK(IsPerNavigationMojoInterfaceEnabled());
+  CommitNavigationInternal(
+      head, common_params, commit_params,
+      std::move(url_loader_client_endpoints),
+      std::move(subresource_loader_factories), std::move(subresource_overrides),
+      std::move(controller_service_worker_info),
+      std::move(prefetch_loader_factory), devtools_navigation_token,
+      mojom::FrameNavigationControl::CommitNavigationCallback(),
+      std::move(per_navigation_mojo_interface_callback));
+}
+
+void RenderFrameImpl::CommitNavigationInternal(
+    const network::ResourceResponseHead& head,
+    const CommonNavigationParams& common_params,
+    const CommitNavigationParams& commit_params,
+    network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+        subresource_loader_factories,
+    base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
+        subresource_overrides,
+    blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
+    network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+    const base::UnguessableToken& devtools_navigation_token,
+    mojom::FrameNavigationControl::CommitNavigationCallback callback,
+    mojom::NavigationClient::CommitNavigationCallback
+        per_navigation_mojo_interface_callback) {
   DCHECK(!IsRendererDebugURL(common_params.url));
   DCHECK(
       !FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type));
@@ -3214,7 +3274,11 @@
       browser_side_navigation_pending_url_ == commit_params.original_url &&
       commit_params.nav_entry_id == 0) {
     browser_side_navigation_pending_url_ = GURL();
-    std::move(callback).Run(blink::mojom::CommitResult::Aborted);
+    if (IsPerNavigationMojoInterfaceEnabled()) {
+      navigation_client_impl_.reset();
+    } else {
+      std::move(callback).Run(blink::mojom::CommitResult::Aborted);
+    }
     return;
   }
 
@@ -3244,7 +3308,8 @@
     response_head = &head;
   std::unique_ptr<DocumentState> document_state(BuildDocumentStateFromParams(
       common_params, commit_params, base::TimeTicks::Now(), std::move(callback),
-      response_head, std::move(navigation_client_impl_)));
+      std::move(per_navigation_mojo_interface_callback), response_head,
+      std::move(navigation_client_impl_)));
 
   blink::WebFrameLoadType load_type = NavigationTypeToLoadType(
       common_params.navigation_type, common_params.should_replace_current_entry,
@@ -3462,7 +3527,8 @@
 
   std::unique_ptr<DocumentState> document_state = BuildDocumentStateFromParams(
       common_params, commit_params, base::TimeTicks(), std::move(callback),
-      nullptr, std::move(navigation_client_impl_));
+      mojom::NavigationClient::CommitNavigationCallback(), nullptr,
+      std::move(navigation_client_impl_));
 
   // The load of the error page can result in this frame being removed.
   // Use a WeakPtr as an easy way to detect whether this has occured. If so,
@@ -3524,7 +3590,8 @@
     internal_data->set_navigation_state(NavigationState::CreateBrowserInitiated(
         common_params, commit_params,
         base::TimeTicks(),  // Not used for same-document navigation.
-        CommitNavigationCallback(), nullptr));
+        mojom::FrameNavigationControl::CommitNavigationCallback(),
+        mojom::NavigationClient::CommitNavigationCallback(), nullptr));
 
     // Load the request.
     commit_status = frame_->CommitSameDocumentNavigation(
@@ -3568,12 +3635,13 @@
 }
 
 void RenderFrameImpl::UpdateSubresourceLoaderFactories(
-    std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders) {
+    std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+        subresource_loader_factories) {
   DCHECK(loader_factories_);
   // TODO(crbug/916625): CHECKing for crbug.com/916625.
   CHECK(loader_factories_->IsHostChildURLLoaderFactoryBundle());
   static_cast<HostChildURLLoaderFactoryBundle*>(loader_factories_.get())
-      ->UpdateThisAndAllClones(std::move(subresource_loaders));
+      ->UpdateThisAndAllClones(std::move(subresource_loader_factories));
 }
 
 void RenderFrameImpl::BindDevToolsAgent(
@@ -4371,7 +4439,10 @@
   if (media_permission_dispatcher_)
     media_permission_dispatcher_->OnNavigation();
 
-  navigation_state->RunCommitNavigationCallback(blink::mojom::CommitResult::Ok);
+  if (!navigation_state->uses_per_navigation_mojo_interface()) {
+    navigation_state->RunCommitNavigationCallback(
+        blink::mojom::CommitResult::Ok);
+  }
 
   ui::PageTransition transition = GetTransitionType(frame_->GetDocumentLoader(),
                                                     frame_, true /* loading */);
@@ -5780,9 +5851,16 @@
     GetFrameHost()->DidCommitSameDocumentNavigation(
         MakeDidCommitProvisionalLoadParams(commit_type, transition));
   } else {
-    GetFrameHost()->DidCommitProvisionalLoad(
-        MakeDidCommitProvisionalLoadParams(commit_type, transition),
-        std::move(interface_params));
+    auto params = MakeDidCommitProvisionalLoadParams(commit_type, transition);
+    NavigationState* navigation_state =
+        NavigationState::FromDocumentLoader(frame_->GetDocumentLoader());
+    if (navigation_state->uses_per_navigation_mojo_interface()) {
+      navigation_state->RunPerNavigationInterfaceCommitNavigationCallback(
+          std::move(params), std::move(interface_params));
+    } else {
+      GetFrameHost()->DidCommitProvisionalLoad(std::move(params),
+                                               std::move(interface_params));
+    }
   }
 }
 
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 20bc4c9..381d964 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -562,21 +562,44 @@
       const CommonNavigationParams& common_params,
       const CommitNavigationParams& commit_params,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
-      std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders,
+      std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+          subresource_loader_factories,
       base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
           subresource_overrides,
       blink::mojom::ControllerServiceWorkerInfoPtr
           controller_service_worker_info,
       network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
       const base::UnguessableToken& devtools_navigation_token,
-      CommitNavigationCallback callback) override;
+      mojom::FrameNavigationControl::CommitNavigationCallback commit_callback)
+      override;
+
+  // This is the version to be used with PerNavigationMojoInterface enabled.
+  // It essentially works the same way, except the navigation callback is
+  // the one from NavigationClient mojo interface.
+  void CommitPerNavigationMojoInterfaceNavigation(
+      const network::ResourceResponseHead& head,
+      const CommonNavigationParams& common_params,
+      const CommitNavigationParams& commit_params,
+      network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+          subresource_loader_factories,
+      base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
+          subresource_overrides,
+      blink::mojom::ControllerServiceWorkerInfoPtr
+          controller_service_worker_info,
+      network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+      const base::UnguessableToken& devtools_navigation_token,
+      mojom::NavigationClient::CommitNavigationCallback
+          per_navigation_mojo_interface_callback);
+
   void CommitFailedNavigation(
       const CommonNavigationParams& common_params,
       const CommitNavigationParams& commit_params,
       bool has_stale_copy_in_cache,
       int error_code,
       const base::Optional<std::string>& error_page_content,
-      std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders,
+      std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+          subresource_loader_factories,
       CommitFailedNavigationCallback callback) override;
   void CommitSameDocumentNavigation(
       const CommonNavigationParams& common_params,
@@ -584,8 +607,8 @@
       CommitSameDocumentNavigationCallback callback) override;
   void HandleRendererDebugURL(const GURL& url) override;
   void UpdateSubresourceLoaderFactories(
-      std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders)
-      override;
+      std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+          subresource_loader_factories) override;
   void BindDevToolsAgent(
       blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
       blink::mojom::DevToolsAgentAssociatedRequest request) override;
@@ -1327,6 +1350,25 @@
       blink::mojom::ControllerServiceWorkerInfoPtr
           controller_service_worker_info);
 
+  // This function avoid duplication between CommitNavigation and
+  // CommitPerNavigationMojoInterfaceNavigation.
+  void CommitNavigationInternal(
+      const network::ResourceResponseHead& head,
+      const CommonNavigationParams& common_params,
+      const CommitNavigationParams& commit_params,
+      network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
+          subresource_loader_factories,
+      base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
+          subresource_overrides,
+      blink::mojom::ControllerServiceWorkerInfoPtr
+          controller_service_worker_info,
+      network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+      const base::UnguessableToken& devtools_navigation_token,
+      mojom::FrameNavigationControl::CommitNavigationCallback callback,
+      mojom::NavigationClient::CommitNavigationCallback
+          per_navigation_mojo_interface_callback);
+
   // Stores the WebLocalFrame we are associated with.  This is null from the
   // constructor until BindToFrame() is called, and it is null after
   // FrameDetached() is called until destruction (which is asynchronous in the
diff --git a/content/test/data/media/peerconnection-call-audio.html b/content/test/data/media/peerconnection-call-audio.html
index d6ac04a..b93e4c2 100644
--- a/content/test/data/media/peerconnection-call-audio.html
+++ b/content/test/data/media/peerconnection-call-audio.html
@@ -94,7 +94,8 @@
   }
 
   function callAndEnsureRemoteAudioTrackMutingWorks() {
-    setupCallAndPromiseAudioPlaying({audio: true, video: true}).then(() => {
+    setupCallAndPromiseAudioPlaying(
+        {audio: {echoCancellation: {exact: false}}, video: true}).then(() => {
       // Call is up, now mute the remote track and check we stop playing out
       // audio (after a small delay, we don't expect it to happen instantly).
       enableRemoteAudio(gSecondConnection, false);
@@ -105,7 +106,8 @@
   }
 
   function callAndEnsureLocalAudioTrackMutingWorks() {
-    setupCallAndPromiseAudioPlaying({audio: true, video: true}).then(() => {
+    setupCallAndPromiseAudioPlaying(
+        {audio: {echoCancellation: {exact: false}}, video: true}).then(() => {
       // Call is up, now mute the local track of the sending side and ensure
       // the receiving side stops receiving audio.
       enableLocalAudio(gFirstConnection, false);
@@ -116,7 +118,8 @@
   }
 
   function callAndEnsureAudioTrackUnmutingWorks() {
-    setupCallAndPromiseAudioPlaying({audio: true, video: true}).then(() => {
+    setupCallAndPromiseAudioPlaying(
+        {audio: {echoCancellation: {exact: false}}, video: true}).then(() => {
       // Mute, wait a while, unmute, verify audio gets back up.
       // (Also, ensure video muting doesn't affect audio).
       enableRemoteAudio(gSecondConnection, false);
@@ -135,7 +138,8 @@
   }
 
   function callAndEnsureLocalVideoMutingDoesntMuteAudio() {
-    setupCallAndPromiseAudioPlaying({audio: true, video: true}).then(() => {
+    setupCallAndPromiseAudioPlaying(
+        {audio: {echoCancellation: {exact: false}}, video: true}).then(() => {
       enableLocalVideo(gFirstConnection, false);
       return ensureAudioPlaying(gSecondConnection)
           .then(reportTestSuccess);
@@ -143,7 +147,8 @@
   }
 
   function callAndEnsureRemoteVideoMutingDoesntMuteAudio() {
-    setupCallAndPromiseAudioPlaying({audio: true, video: true}).then(() => {
+    setupCallAndPromiseAudioPlaying(
+        {audio: {echoCancellation: {exact: false}}, video: true}).then(() => {
       enableRemoteVideo(gSecondConnection, false);
       return ensureAudioPlaying(gSecondConnection)
           .then(reportTestSuccess);
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc
index 3a70f62c..7820c64 100644
--- a/content/test/navigation_simulator_impl.cc
+++ b/content/test/navigation_simulator_impl.cc
@@ -575,6 +575,14 @@
     document_interface_broker_blink_request_ = nullptr;
   }
 
+  if (handle_) {
+    scoped_refptr<net::HttpResponseHeaders> response_headers =
+        new net::HttpResponseHeaders(std::string());
+    response_headers->AddHeader(std::string("Content-Type: ") +
+                                contents_mime_type_);
+    handle_->set_response_headers_for_testing(response_headers);
+  }
+
   auto params = BuildDidCommitProvisionalLoadParams(
       false /* same_document */, false /* failed_navigation */);
   render_frame_host_->SimulateCommitProcessed(
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index 600fd6e..e561611 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -16,7 +16,6 @@
 #include "content/browser/frame_host/navigator_impl.h"
 #include "content/browser/frame_host/render_frame_host_delegate.h"
 #include "content/browser/web_contents/web_contents_impl.h"
-#include "content/common/frame_messages.h"
 #include "content/common/frame_owner_properties.h"
 #include "content/public/browser/navigation_throttle.h"
 #include "content/public/common/navigation_policy.h"
@@ -294,7 +293,7 @@
     FrameHostMsg_DidCommitProvisionalLoad_Params* params,
     mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params,
     bool was_within_same_document) {
-  if (GetNavigationHandle()) {
+  if (GetNavigationHandle() && !GetNavigationHandle()->GetResponseHeaders()) {
     scoped_refptr<net::HttpResponseHeaders> response_headers =
         new net::HttpResponseHeaders(std::string());
     response_headers->AddHeader(std::string("Content-Type: ") +
@@ -444,6 +443,7 @@
   CHECK(params);
   blink::mojom::CommitResult result = blink::mojom::CommitResult::Ok;
 
+  bool did_commit = false;
   if (!same_document) {
     // Note: Although the code does not prohibit the running of multiple
     // callbacks, no more than 1 callback will ever run, because navigation_id
@@ -455,8 +455,15 @@
     }
     {
       auto callback_it = navigation_client_commit_callback_.find(navigation_id);
-      if (callback_it != navigation_client_commit_callback_.end())
-        std::move(callback_it->second).Run(result);
+      if (callback_it != navigation_client_commit_callback_.end()) {
+        std::move(callback_it->second)
+            .Run(std::move(params),
+                 mojom::DidCommitProvisionalLoadInterfaceParams::New(
+                     std::move(interface_provider_request),
+                     std::move(document_interface_broker_content_request),
+                     std::move(document_interface_broker_blink_request)));
+        did_commit = true;
+      }
     }
     {
       auto callback_it = commit_failed_callback_.find(navigation_id);
@@ -471,13 +478,15 @@
     }
   }
 
-  SendNavigateWithParamsAndInterfaceParams(
-      params.release(),
-      mojom::DidCommitProvisionalLoadInterfaceParams::New(
-          std::move(interface_provider_request),
-          std::move(document_interface_broker_content_request),
-          std::move(document_interface_broker_blink_request)),
-      same_document);
+  if (!did_commit) {
+    SendNavigateWithParamsAndInterfaceParams(
+        params.release(),
+        mojom::DidCommitProvisionalLoadInterfaceParams::New(
+            std::move(interface_provider_request),
+            std::move(document_interface_broker_content_request),
+            std::move(document_interface_broker_blink_request)),
+        same_document);
+  }
 }
 
 WebBluetoothServiceImpl*
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
index e6d1e6a9..ded86db 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -332,6 +332,10 @@
 }
 
 IN_PROC_BROWSER_TEST_F(MimeHandlerViewTest, Iframe) {
+  // TODO(https://crbug.com/923051): Flaky in single process mash.
+  if (features::IsSingleProcessMash())
+    return;
+
   RunTest("test_iframe.html");
 }
 
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
index e6dea1c3..46f54ef 100644
--- a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
+++ b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
@@ -401,9 +401,19 @@
   if (self.isPaused) {
     return;
   }
-  if (self.inputAccessoryView && !self.inputAccessoryView.superview) {
+  if (self.inputAccessoryView) {
     if (IsIPadIdiom()) {
+      // On iPad the keyboard view can change so this updates it when needed.
       UIView* keyboardView = [self getKeyboardView];
+      if (self.inputAccessoryView.superview) {
+        if (keyboardView == self.inputAccessoryView.superview) {
+          return;
+        }
+        // The keyboard view is a different one.
+        [self.manualFillAccessoryViewController resetAnimated:NO];
+        [self.inputAccessoryView removeFromSuperview];
+        [self.grayBackgroundView removeFromSuperview];
+      }
       self.inputAccessoryView.translatesAutoresizingMaskIntoConstraints = NO;
       [keyboardView addSubview:self.inputAccessoryView];
       [NSLayoutConstraint activateConstraints:@[
@@ -421,7 +431,7 @@
         [keyboardView sendSubviewToBack:self.grayBackgroundView];
         AddSameConstraints(self.grayBackgroundView, keyboardView);
       }
-    } else {
+    } else if (!self.inputAccessoryView.superview) {  // Is not an iPad.
       UIResponder* firstResponder = GetFirstResponder();
       if (firstResponder.inputAccessoryView) {
         [firstResponder.inputAccessoryView addSubview:self.inputAccessoryView];
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn
index 5474ee03..74f9916f 100644
--- a/ios/chrome/browser/signin/BUILD.gn
+++ b/ios/chrome/browser/signin/BUILD.gn
@@ -120,8 +120,6 @@
     "fake_gaia_cookie_manager_service_builder.h",
     "fake_oauth2_token_service_builder.h",
     "fake_oauth2_token_service_builder.mm",
-    "fake_signin_manager_builder.cc",
-    "fake_signin_manager_builder.h",
     "identity_test_environment_chrome_browser_state_adaptor.cc",
     "identity_test_environment_chrome_browser_state_adaptor.h",
   ]
diff --git a/ios/chrome/browser/signin/authentication_service.h b/ios/chrome/browser/signin/authentication_service.h
index dc8217a..7b2a7c649 100644
--- a/ios/chrome/browser/signin/authentication_service.h
+++ b/ios/chrome/browser/signin/authentication_service.h
@@ -25,7 +25,6 @@
 class IdentityManager;
 }
 
-class AccountTrackerService;
 class AuthenticationServiceDelegate;
 @class ChromeIdentity;
 class PrefService;
@@ -41,7 +40,6 @@
   AuthenticationService(PrefService* pref_service,
                         ProfileOAuth2TokenService* token_service,
                         SyncSetupService* sync_setup_service,
-                        AccountTrackerService* account_tracker,
                         identity::IdentityManager* identity_manager,
                         syncer::SyncService* sync_service);
   ~AuthenticationService() override;
@@ -200,7 +198,6 @@
   PrefService* pref_service_ = nullptr;
   ProfileOAuth2TokenService* token_service_ = nullptr;
   SyncSetupService* sync_setup_service_ = nullptr;
-  AccountTrackerService* account_tracker_ = nullptr;
   identity::IdentityManager* identity_manager_ = nullptr;
   syncer::SyncService* sync_service_ = nullptr;
 
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm
index d961febb..9df38f4 100644
--- a/ios/chrome/browser/signin/authentication_service.mm
+++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -16,7 +16,6 @@
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/core/browser/account_info.h"
-#include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h"
 #include "components/sync/driver/sync_service.h"
@@ -59,10 +58,16 @@
 constexpr char kFakeAccountIdForRemovedAccount[] = "0000000000000";
 
 // Returns the account id associated with |identity|.
-std::string ChromeIdentityToAccountID(AccountTrackerService* account_tracker,
-                                      ChromeIdentity* identity) {
+std::string ChromeIdentityToAccountID(
+    identity::IdentityManager* identity_manager,
+    ChromeIdentity* identity) {
   std::string gaia_id = base::SysNSStringToUTF8([identity gaiaID]);
-  return account_tracker->FindAccountInfoByGaiaId(gaia_id).account_id;
+  auto maybe_account =
+      identity_manager->FindAccountInfoForAccountWithRefreshTokenByGaiaId(
+          gaia_id);
+  AccountInfo account_info =
+      maybe_account.has_value() ? maybe_account.value() : AccountInfo();
+  return account_info.account_id;
 }
 
 }  // namespace
@@ -71,20 +76,17 @@
     PrefService* pref_service,
     ProfileOAuth2TokenService* token_service,
     SyncSetupService* sync_setup_service,
-    AccountTrackerService* account_tracker,
     identity::IdentityManager* identity_manager,
     syncer::SyncService* sync_service)
     : pref_service_(pref_service),
       token_service_(token_service),
       sync_setup_service_(sync_setup_service),
-      account_tracker_(account_tracker),
       identity_manager_(identity_manager),
       sync_service_(sync_service),
       identity_service_observer_(this),
       weak_pointer_factory_(this) {
   DCHECK(pref_service_);
   DCHECK(sync_setup_service_);
-  DCHECK(account_tracker_);
   DCHECK(identity_manager_);
   DCHECK(sync_service_);
   token_service_->AddObserver(this);
@@ -246,21 +248,26 @@
 }
 
 void AuthenticationService::MigrateAccountsStoredInPrefsIfNeeded() {
-  if (account_tracker_->GetMigrationState() ==
-      AccountTrackerService::MIGRATION_NOT_STARTED) {
+  if (identity_manager_->GetAccountIdMigrationState() ==
+      identity::IdentityManager::AccountIdMigrationState::
+          MIGRATION_NOT_STARTED) {
     return;
   }
-  DCHECK_EQ(AccountTrackerService::MIGRATION_DONE,
-            account_tracker_->GetMigrationState());
+  DCHECK_EQ(identity::IdentityManager::AccountIdMigrationState::MIGRATION_DONE,
+            identity_manager_->GetAccountIdMigrationState());
   if (pref_service_->GetBoolean(prefs::kSigninLastAccountsMigrated)) {
     // Already migrated.
     return;
   }
 
-  std::vector<std::string> emails = GetAccountsInPrefs();
+  std::vector<std::string> account_ids = GetAccountsInPrefs();
   base::ListValue accounts_pref_value;
-  for (const std::string& email : emails) {
-    AccountInfo account_info = account_tracker_->FindAccountInfoByEmail(email);
+  for (const std::string& account_id : account_ids) {
+    auto maybe_account =
+        identity_manager_->FindAccountInfoForAccountWithRefreshTokenByAccountId(
+            account_id);
+    AccountInfo account_info =
+        maybe_account.has_value() ? maybe_account.value() : AccountInfo();
     if (!account_info.email.empty()) {
       DCHECK(!account_info.gaia.empty());
       accounts_pref_value.AppendString(account_info.account_id);
@@ -306,11 +313,8 @@
   if (!IsAuthenticated())
     return nil;
 
-  std::string authenticated_account_id =
-      identity_manager_->GetPrimaryAccountId();
-
   std::string authenticated_gaia_id =
-      account_tracker_->GetAccountInfo(authenticated_account_id).gaia;
+      identity_manager_->GetPrimaryAccountInfo().gaia;
   if (authenticated_gaia_id.empty())
     return nil;
 
@@ -334,7 +338,7 @@
   info.email = GetCanonicalizedEmailForIdentity(identity);
   info.hosted_domain = hosted_domain;
   std::string new_authenticated_account_id =
-      account_tracker_->SeedAccountInfo(info);
+      identity_manager_->LegacySeedAccountInfo(info);
   std::string old_authenticated_account_id =
       identity_manager_->GetPrimaryAccountId();
   // |SigninManager::SetAuthenticatedAccountId| simply ignores the call if
@@ -403,7 +407,7 @@
 NSDictionary* AuthenticationService::GetCachedMDMInfo(
     ChromeIdentity* identity) {
   auto it = cached_mdm_infos_.find(
-      ChromeIdentityToAccountID(account_tracker_, identity));
+      ChromeIdentityToAccountID(identity_manager_, identity));
 
   if (it == cached_mdm_infos_.end()) {
     return nil;
@@ -492,7 +496,7 @@
     }
   };
   if (identity_service->HandleMDMNotification(identity, user_info, callback)) {
-    cached_mdm_infos_[ChromeIdentityToAccountID(account_tracker_, identity)] =
+    cached_mdm_infos_[ChromeIdentityToAccountID(identity_manager_, identity)] =
         user_info;
     return true;
   }
diff --git a/ios/chrome/browser/signin/authentication_service_factory.mm b/ios/chrome/browser/signin/authentication_service_factory.mm
index add584d1..810d24e5 100644
--- a/ios/chrome/browser/signin/authentication_service_factory.mm
+++ b/ios/chrome/browser/signin/authentication_service_factory.mm
@@ -10,7 +10,6 @@
 #include "base/no_destructor.h"
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/chrome/browser/signin/account_tracker_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_delegate.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
@@ -51,7 +50,6 @@
     : BrowserStateKeyedServiceFactory(
           "AuthenticationService",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(ios::AccountTrackerServiceFactory::GetInstance());
   DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(SyncSetupServiceFactory::GetInstance());
@@ -69,7 +67,6 @@
       browser_state->GetPrefs(),
       ProfileOAuth2TokenServiceFactory::GetForBrowserState(browser_state),
       SyncSetupServiceFactory::GetForBrowserState(browser_state),
-      ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state),
       IdentityManagerFactory::GetForBrowserState(browser_state),
       ProfileSyncServiceFactory::GetForBrowserState(browser_state));
 }
diff --git a/ios/chrome/browser/signin/authentication_service_fake.h b/ios/chrome/browser/signin/authentication_service_fake.h
index 331e400..3ae16b5 100644
--- a/ios/chrome/browser/signin/authentication_service_fake.h
+++ b/ios/chrome/browser/signin/authentication_service_fake.h
@@ -46,7 +46,6 @@
   AuthenticationServiceFake(PrefService* pref_service,
                             ProfileOAuth2TokenService* token_service,
                             SyncSetupService* sync_setup_service,
-                            AccountTrackerService* account_tracker,
                             identity::IdentityManager* identity_manager,
                             syncer::SyncService* sync_service);
 
diff --git a/ios/chrome/browser/signin/authentication_service_fake.mm b/ios/chrome/browser/signin/authentication_service_fake.mm
index f4cf4a9..8dd076395 100644
--- a/ios/chrome/browser/signin/authentication_service_fake.mm
+++ b/ios/chrome/browser/signin/authentication_service_fake.mm
@@ -8,7 +8,6 @@
 
 #include "base/memory/ptr_util.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/chrome/browser/signin/account_tracker_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_delegate_fake.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
@@ -25,13 +24,11 @@
     PrefService* pref_service,
     ProfileOAuth2TokenService* token_service,
     SyncSetupService* sync_setup_service,
-    AccountTrackerService* account_tracker,
     identity::IdentityManager* identity_manager,
     syncer::SyncService* sync_service)
     : AuthenticationService(pref_service,
                             token_service,
                             sync_setup_service,
-                            account_tracker,
                             identity_manager,
                             sync_service),
       have_accounts_changed_(false) {}
@@ -80,7 +77,6 @@
       browser_state->GetPrefs(),
       ProfileOAuth2TokenServiceFactory::GetForBrowserState(browser_state),
       SyncSetupServiceFactory::GetForBrowserState(browser_state),
-      ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state),
       IdentityManagerFactory::GetForBrowserState(browser_state),
       ProfileSyncServiceFactory::GetForBrowserState(browser_state)));
   service->Initialize(std::make_unique<AuthenticationServiceDelegateFake>());
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm
index c328572..69e26d7 100644
--- a/ios/chrome/browser/signin/authentication_service_unittest.mm
+++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -174,8 +174,6 @@
         ProfileOAuth2TokenServiceFactory::GetForBrowserState(
             browser_state_.get()),
         SyncSetupServiceFactory::GetForBrowserState(browser_state_.get()),
-        ios::AccountTrackerServiceFactory::GetForBrowserState(
-            browser_state_.get()),
         IdentityManagerFactory::GetForBrowserState(browser_state_.get()),
         ProfileSyncServiceFactory::GetForBrowserState(browser_state_.get()));
     authentication_service_->Initialize(
@@ -574,6 +572,19 @@
   account_tracker->Initialize(browser_state_->GetPrefs(), base::FilePath());
   account_tracker->SetMigrationDone();
 
+  // Reload all credentials to find account info with the refresh token.
+  // If it tries to find refresh token with gaia ID after
+  // AccountTrackerService::Initialize(), it fails because account ids are
+  // updated with gaia ID from email at MigrateToGaiaId. As IdentityManager
+  // needs refresh token to find account info, it reloads all credentials.
+  ProfileOAuth2TokenService* token_service =
+      ProfileOAuth2TokenServiceFactory::GetForBrowserState(
+          browser_state_.get());
+  ProfileOAuth2TokenServiceIOSDelegate* token_service_delegate =
+      static_cast<ProfileOAuth2TokenServiceIOSDelegate*>(
+          token_service->GetDelegate());
+  token_service_delegate->ReloadCredentials();
+
   // Actually migrate the accounts in prefs.
   MigrateAccountsStoredInPrefsIfNeeded();
   std::vector<std::string> migrated_accounts_in_prefs = GetAccountsInPrefs();
diff --git a/ios/chrome/browser/signin/fake_signin_manager_builder.cc b/ios/chrome/browser/signin/fake_signin_manager_builder.cc
deleted file mode 100644
index 3a30db6e..0000000
--- a/ios/chrome/browser/signin/fake_signin_manager_builder.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 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 "ios/chrome/browser/signin/fake_signin_manager_builder.h"
-
-#include <utility>
-
-#include "components/signin/core/browser/fake_signin_manager.h"
-#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/chrome/browser/signin/account_tracker_service_factory.h"
-#include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h"
-#include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "ios/chrome/browser/signin/signin_client_factory.h"
-#include "ios/chrome/browser/signin/signin_manager_factory.h"
-
-namespace ios {
-
-std::unique_ptr<KeyedService> BuildFakeSigninManager(
-    web::BrowserState* browser_state) {
-  ios::ChromeBrowserState* chrome_browser_state =
-      ios::ChromeBrowserState::FromBrowserState(browser_state);
-  std::unique_ptr<SigninManager> manager(new FakeSigninManager(
-      SigninClientFactory::GetForBrowserState(chrome_browser_state),
-      ProfileOAuth2TokenServiceFactory::GetForBrowserState(
-          chrome_browser_state),
-      ios::AccountTrackerServiceFactory::GetForBrowserState(
-          chrome_browser_state),
-      ios::GaiaCookieManagerServiceFactory::GetForBrowserState(
-          chrome_browser_state)));
-  manager->Initialize(nullptr);
-  ios::SigninManagerFactory::GetInstance()
-      ->NotifyObserversOfSigninManagerCreationForTesting(manager.get());
-  return manager;
-}
-
-}  // namespace ios
diff --git a/ios/chrome/browser/signin/fake_signin_manager_builder.h b/ios/chrome/browser/signin/fake_signin_manager_builder.h
deleted file mode 100644
index f10af9d..0000000
--- a/ios/chrome/browser/signin/fake_signin_manager_builder.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_BUILDER_H_
-#define IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_BUILDER_H_
-
-#include <memory>
-
-namespace web {
-class BrowserState;
-}
-
-class KeyedService;
-
-namespace ios {
-
-// Helper function to be used with KeyedService::SetTestingFactory().
-// The returned instance is initialized.
-std::unique_ptr<KeyedService> BuildFakeSigninManager(
-    web::BrowserState* browser_state);
-
-}  // namespace ios
-
-#endif  // IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_BUILDER_H_
diff --git a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc
index 17a3a59..8d2b2a32 100644
--- a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc
+++ b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc
@@ -8,21 +8,37 @@
 #include "ios/chrome/browser/signin/account_tracker_service_factory.h"
 #include "ios/chrome/browser/signin/fake_gaia_cookie_manager_service_builder.h"
 #include "ios/chrome/browser/signin/fake_oauth2_token_service_builder.h"
-#include "ios/chrome/browser/signin/fake_signin_manager_builder.h"
 #include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "ios/chrome/browser/signin/signin_client_factory.h"
 #include "ios/chrome/browser/signin/signin_manager_factory.h"
 
 namespace {
 
+std::unique_ptr<KeyedService> BuildFakeSigninManager(
+    web::BrowserState* browser_state) {
+  ios::ChromeBrowserState* chrome_browser_state =
+      ios::ChromeBrowserState::FromBrowserState(browser_state);
+  std::unique_ptr<SigninManager> manager(new FakeSigninManager(
+      SigninClientFactory::GetForBrowserState(chrome_browser_state),
+      ProfileOAuth2TokenServiceFactory::GetForBrowserState(
+          chrome_browser_state),
+      ios::AccountTrackerServiceFactory::GetForBrowserState(
+          chrome_browser_state),
+      ios::GaiaCookieManagerServiceFactory::GetForBrowserState(
+          chrome_browser_state)));
+  manager->Initialize(nullptr);
+  ios::SigninManagerFactory::GetInstance()
+      ->NotifyObserversOfSigninManagerCreationForTesting(manager.get());
+  return manager;
+}
+
 TestChromeBrowserState::TestingFactories GetIdentityTestEnvironmentFactories() {
-  return {{ios::GaiaCookieManagerServiceFactory::GetInstance(),
-           base::BindRepeating(&BuildFakeGaiaCookieManagerService)},
-          {ProfileOAuth2TokenServiceFactory::GetInstance(),
+  return {{ProfileOAuth2TokenServiceFactory::GetInstance(),
            base::BindRepeating(&BuildFakeOAuth2TokenService)},
           {ios::SigninManagerFactory::GetInstance(),
-           base::BindRepeating(&ios::BuildFakeSigninManager)}};
+           base::BindRepeating(&BuildFakeSigninManager)}};
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
index dc2e797d..50f50ab 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 #import <EarlGrey/EarlGrey.h>
+#import <EarlGrey/GREYAppleInternals.h>
 #import <EarlGrey/GREYKeyboard.h>
+#include <atomic>
 
 #include "base/ios/ios_util.h"
 #include "base/strings/sys_string_conversions.h"
@@ -38,9 +40,14 @@
 namespace {
 
 constexpr char kFormElementName[] = "name";
+constexpr char kFormElementCity[] = "city";
 
 constexpr char kFormHTMLFile[] = "/profile_form.html";
 
+// EarlGrey fails to detect undocked keyboards on screen, so this help check
+// for them.
+static std::atomic_bool gCHRIsKeyboardShown(false);
+
 // Returns a matcher for the profiles icon in the keyboard accessory bar.
 id<GREYMatcher> ProfilesIconMatcher() {
   return grey_accessibilityID(
@@ -65,6 +72,13 @@
   return grey_allOf(classMatcher, parentMatcher, nil);
 }
 
+// Returns a matcher for a button in the ProfileTableView. Currently it returns
+// the company one.
+id<GREYMatcher> ProfileTableViewButtonMatcher() {
+  // The company name for autofill::test::GetFullProfile() is "Underworld".
+  return grey_buttonTitle(@"Underworld");
+}
+
 // Saves an example profile in the store.
 void AddAutofillProfile(autofill::PersonalDataManager* personalDataManager) {
   autofill::AutofillProfile profile = autofill::test::GetFullProfile();
@@ -95,6 +109,156 @@
   return [condition waitWithTimeout:timeout];
 }
 
+// If the keyboard is not present this will add a text field to the hierarchy,
+// make it first responder and return it. If it is already present, this does
+// nothing and returns nil.
+UITextField* ShowKeyboard() {
+  UITextField* textField = nil;
+  if (!gCHRIsKeyboardShown) {
+    CGRect rect = CGRectMake(0, 0, 300, 100);
+    textField = [[UITextField alloc] initWithFrame:rect];
+    textField.backgroundColor = [UIColor blueColor];
+    [[[UIApplication sharedApplication] keyWindow] addSubview:textField];
+    [textField becomeFirstResponder];
+  }
+  auto verify_block = ^BOOL {
+    return gCHRIsKeyboardShown;
+  };
+  NSTimeInterval timeout = base::test::ios::kWaitForUIElementTimeout;
+  NSString* condition_name =
+      [NSString stringWithFormat:@"Wait for keyboard to appear"];
+  GREYCondition* condition = [GREYCondition conditionWithName:condition_name
+                                                        block:verify_block];
+  [condition waitWithTimeout:timeout];
+  return textField;
+}
+
+// Returns the dismiss key if present in the passed keyboard layout. Returns nil
+// if not found.
+UIAccessibilityElement* KeyboardDismissKeyInLayout(UIView* layout) {
+  UIAccessibilityElement* key = nil;
+  if ([layout accessibilityElementCount] != NSNotFound) {
+    for (NSInteger i = [layout accessibilityElementCount]; i >= 0; --i) {
+      id element = [layout accessibilityElementAtIndex:i];
+      if ([[[element key] valueForKey:@"name"]
+              isEqualToString:@"Dismiss-Key"]) {
+        key = element;
+        break;
+      }
+    }
+  }
+  return key;
+}
+
+// Finds the first view containing the keyboard which origin is not zero.
+UIView* KeyboardContainerForLayout(UIView* layout) {
+  CGRect frame = CGRectZero;
+  UIView* keyboardContainer = layout;
+  while (CGPointEqualToPoint(frame.origin, CGPointZero) && keyboardContainer) {
+    keyboardContainer = [keyboardContainer superview];
+    if (keyboardContainer) {
+      frame = keyboardContainer.frame;
+    }
+  }
+  return keyboardContainer;
+}
+
+// Returns YES if the keyboard is docked at the bottom. NO otherwise.
+BOOL IsKeyboardDockedForLayout(UIView* layout) {
+  UIView* keyboardContainer = KeyboardContainerForLayout(layout);
+  CGRect screenBounds = [[UIScreen mainScreen] bounds];
+  CGFloat maxY = CGRectGetMaxY(keyboardContainer.frame);
+  return [@(maxY) isEqualToNumber:@(screenBounds.size.height)];
+}
+
+// Undocks the keyboard by swiping it up. Does nothing if already undocked.
+void UndockKeyboard() {
+  if (!IsIPadIdiom()) {
+    return;
+  }
+
+  UITextField* textField = ShowKeyboard();
+
+  // Assert the "Dismiss-Key" is present.
+  UIView* layout = [[UIKeyboardImpl sharedInstance] _layout];
+  GREYAssert([[layout valueForKey:@"keyplaneContainsDismissKey"] boolValue],
+             @"No dismiss key is pressent");
+
+  // Return if already undocked.
+  if (!IsKeyboardDockedForLayout(layout)) {
+    // If we created a dummy textfield for this, remove it.
+    [textField removeFromSuperview];
+    return;
+  }
+
+  // Swipe it up.
+  if (!layout.accessibilityIdentifier.length) {
+    layout.accessibilityIdentifier = @"CRKBLayout";
+  }
+
+  id<GREYMatcher> matcher =
+      grey_accessibilityID(layout.accessibilityIdentifier);
+
+  UIAccessibilityElement* key = KeyboardDismissKeyInLayout(layout);
+  CGRect keyFrame = [key accessibilityFrame];
+  CGRect keyboardContainerFrame = KeyboardContainerForLayout(layout).frame;
+  CGPoint pointToKey = {keyFrame.origin.x - keyboardContainerFrame.origin.x,
+                        keyFrame.origin.y - keyboardContainerFrame.origin.y};
+  CGRectIntersection(keyFrame, keyboardContainerFrame);
+  CGPoint startPoint = CGPointMake((pointToKey.x + keyFrame.size.width / 2.0) /
+                                       keyboardContainerFrame.size.width,
+                                   (pointToKey.y + keyFrame.size.height / 2.0) /
+                                       keyboardContainerFrame.size.height);
+
+  id action = grey_swipeFastInDirectionWithStartPoint(
+      kGREYDirectionUp, startPoint.x, startPoint.y);
+  [[EarlGrey selectElementWithMatcher:matcher] performAction:action];
+}
+
+// Docks the keyboard by swiping it down. Does nothing if already docked.
+void DockKeyboard() {
+  if (!IsIPadIdiom()) {
+    return;
+  }
+
+  UITextField* textField = ShowKeyboard();
+
+  // Assert the "Dismiss-Key" is present.
+  UIView* layout = [[UIKeyboardImpl sharedInstance] _layout];
+  GREYAssert([[layout valueForKey:@"keyplaneContainsDismissKey"] boolValue],
+             @"No dismiss key is pressent");
+
+  // Return if already docked.
+  if (IsKeyboardDockedForLayout(layout)) {
+    // If we created a dummy textfield for this, remove it.
+    [textField removeFromSuperview];
+    return;
+  }
+
+  // Swipe it down.
+  id<GREYMatcher> classMatcher = grey_kindOfClass([UIWindow class]);
+  UIAccessibilityElement* key = KeyboardDismissKeyInLayout(layout);
+  id<GREYMatcher> parentMatcher =
+      grey_descendant(grey_accessibilityLabel(key.accessibilityLabel));
+  id matcher = grey_allOf(classMatcher, parentMatcher, nil);
+
+  CGRect keyFrame = [key accessibilityFrame];
+  GREYAssertFalse(CGRectEqualToRect(keyFrame, CGRectZero),
+                  @"The dismiss key accessibility frame musn't be zero");
+  CGPoint startPoint =
+      CGPointMake((keyFrame.origin.x + keyFrame.size.width / 2.0) /
+                      [UIScreen mainScreen].bounds.size.width,
+                  (keyFrame.origin.y + keyFrame.size.height / 2.0) /
+                      [UIScreen mainScreen].bounds.size.height);
+  id<GREYAction> action = grey_swipeFastInDirectionWithStartPoint(
+      kGREYDirectionDown, startPoint.x, startPoint.y);
+
+  [[EarlGrey selectElementWithMatcher:matcher] performAction:action];
+
+  // If we created a dummy textfield for this, remove it.
+  [textField removeFromSuperview];
+}
+
 }  // namespace
 
 // Integration Tests for fallback coordinator.
@@ -107,6 +271,41 @@
 
 @implementation FallbackCoordinatorTestCase
 
++ (void)load {
+  @autoreleasepool {
+    // EarlGrey fails to detect undocked keyboards on screen, so this help check
+    // for them.
+    auto block = ^(NSNotification* note) {
+      CGRect keyboardFrame =
+          [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
+      UIWindow* window = [UIApplication sharedApplication].keyWindow;
+      keyboardFrame = [window convertRect:keyboardFrame fromWindow:nil];
+      CGRect windowFrame = window.frame;
+      CGRect frameIntersection = CGRectIntersection(windowFrame, keyboardFrame);
+      gCHRIsKeyboardShown =
+          frameIntersection.size.width > 1 && frameIntersection.size.height > 1;
+    };
+
+    [[NSNotificationCenter defaultCenter]
+        addObserverForName:UIKeyboardDidChangeFrameNotification
+                    object:nil
+                     queue:nil
+                usingBlock:block];
+
+    [[NSNotificationCenter defaultCenter]
+        addObserverForName:UIKeyboardDidShowNotification
+                    object:nil
+                     queue:nil
+                usingBlock:block];
+
+    [[NSNotificationCenter defaultCenter]
+        addObserverForName:UIKeyboardDidHideNotification
+                    object:nil
+                     queue:nil
+                usingBlock:block];
+  }
+}
+
 - (void)setUp {
   [super setUp];
   GREYAssert(autofill::features::IsAutofillManualFallbackEnabled(),
@@ -129,6 +328,18 @@
   for (const auto* profile : _personalDataManager->GetProfiles()) {
     _personalDataManager->RemoveByGUID(profile->guid());
   }
+  // Leaving a picker on iPads causes problems with the docking logic. This
+  // will dismiss any.
+  if (IsIPadIdiom()) {
+    // Tap in the web view so the popover dismisses.
+    [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+        performAction:grey_tapAtPoint(CGPointMake(0, 0))];
+
+    // Verify the table view is not visible.
+    [[EarlGrey selectElementWithMatcher:grey_kindOfClass([UITableView class])]
+        assertWithMatcher:grey_notVisible()];
+  }
+  DockKeyboard();
   [super tearDown];
 }
 
@@ -136,7 +347,7 @@
 // continue working.
 - (void)testIPadTappingOutsidePopOverResumesSuggestionsCorrectly {
   if (!IsIPadIdiom()) {
-    return;
+    EARL_GREY_TEST_SKIPPED(@"Test not applicable for iPhone.");
   }
 
   GREYAssertEqual(_personalDataManager->GetProfiles().size(), 0,
@@ -184,4 +395,166 @@
   XCTAssertTrue(WaitForJavaScriptCondition(javaScriptCondition));
 }
 
+// Tests that the manual fallback view concedes preference to the system picker
+// for selection elements.
+- (void)testPickerDismissesManualFallback {
+  // Add the profile to be used.
+  AddAutofillProfile(_personalDataManager);
+
+  // Bring up the keyboard.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElement(kFormElementCity)];
+
+  // Tap on the profiles icon.
+  [[EarlGrey selectElementWithMatcher:ProfilesIconMatcher()]
+      performAction:grey_tap()];
+
+  // Verify the profiles controller table view is visible.
+  [[EarlGrey selectElementWithMatcher:ProfilesTableViewMatcher()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Tap any option.
+  [[EarlGrey selectElementWithMatcher:ProfileTableViewButtonMatcher()]
+      performAction:grey_tap()];
+
+  // Verify the profiles controller table view is not visible.
+  [[EarlGrey selectElementWithMatcher:ProfilesTableViewMatcher()]
+      assertWithMatcher:grey_notVisible()];
+}
+
+// Tests that the input accessory view continues working after a picker is
+// present.
+- (void)testInputAccessoryBarIsPresentAfterPickers {
+  // Add the profile to be used.
+  AddAutofillProfile(_personalDataManager);
+
+  // Bring up the keyboard by tapping the city, which is the element before the
+  // picker.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElement(kFormElementCity)];
+
+  // Tap on the profiles icon.
+  [[EarlGrey selectElementWithMatcher:ProfilesIconMatcher()]
+      performAction:grey_tap()];
+
+  // Verify the profiles controller table view is visible.
+  [[EarlGrey selectElementWithMatcher:ProfilesTableViewMatcher()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Tap any option.
+  [[EarlGrey selectElementWithMatcher:ProfileTableViewButtonMatcher()]
+      performAction:grey_tap()];
+
+  // Verify the profiles controller table view is not visible.
+  [[EarlGrey selectElementWithMatcher:ProfilesTableViewMatcher()]
+      assertWithMatcher:grey_notVisible()];
+
+  // On iPad the picker is a table view in a popover, we need to dismiss that
+  // first.
+  if (IsIPadIdiom()) {
+    // Tap in the web view so the popover dismisses.
+    [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+        performAction:grey_tapAtPoint(CGPointMake(0, 0))];
+
+    // Verify the table view is not visible.
+    [[EarlGrey selectElementWithMatcher:grey_kindOfClass([UITableView class])]
+        assertWithMatcher:grey_notVisible()];
+  }
+
+  // Bring up the regular keyboard again.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElement(kFormElementName)];
+
+  // Wait for the accessory icon to appear.
+  [GREYKeyboard waitForKeyboardToAppear];
+
+  // Verify the profiles icon is visible, and therefore also the input accessory
+  // bar.
+  [[EarlGrey selectElementWithMatcher:ProfilesIconMatcher()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Same as before but with the keyboard undocked.
+- (void)testUndockedInputAccessoryBarIsPresentAfterPickers {
+  // No need to run if not iPad.
+  if (!IsIPadIdiom()) {
+    EARL_GREY_TEST_SKIPPED(@"Test not applicable for iPhone.");
+  }
+  // Add the profile to be used.
+  AddAutofillProfile(_personalDataManager);
+
+  // Bring up the keyboard by tapping the city, which is the element before the
+  // picker.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElement(kFormElementCity)];
+
+  UndockKeyboard();
+
+  // Tap on the profiles icon.
+  [[EarlGrey selectElementWithMatcher:ProfilesIconMatcher()]
+      performAction:grey_tap()];
+
+  // Verify the profiles controller table view is visible.
+  [[EarlGrey selectElementWithMatcher:ProfilesTableViewMatcher()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Tap any option.
+  [[EarlGrey selectElementWithMatcher:ProfileTableViewButtonMatcher()]
+      performAction:grey_tap()];
+
+  // Verify the profiles controller table view is not visible.
+  [[EarlGrey selectElementWithMatcher:ProfilesTableViewMatcher()]
+      assertWithMatcher:grey_notVisible()];
+
+  // On iPad the picker is a table view in a popover, we need to dismiss that
+  // first. Tap in the previous field, so the popover dismisses.
+  [[EarlGrey selectElementWithMatcher:grey_keyWindow()]
+      performAction:grey_tapAtPoint(CGPointMake(0, 0))];
+
+  // Verify the table view is not visible.
+  [[EarlGrey selectElementWithMatcher:grey_kindOfClass([UITableView class])]
+      assertWithMatcher:grey_notVisible()];
+
+  // Bring up the regular keyboard again.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElement(kFormElementName)];
+
+  // Wait for the accessory icon to appear.
+  [GREYKeyboard waitForKeyboardToAppear];
+
+  // Verify the profiles icon is visible, and therefore also the input accessory
+  // bar.
+  [[EarlGrey selectElementWithMatcher:ProfilesIconMatcher()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  DockKeyboard();
+}
+
+// Test the input accessory bar is present when undocking the keyboard.
+- (void)testInputAccessoryBarIsPresentAfterUndockingKeyboard {
+  if (!IsIPadIdiom()) {
+    EARL_GREY_TEST_SKIPPED(@"Test not applicable for iPhone.");
+  }
+  // Add the profile to use for verification.
+  AddAutofillProfile(_personalDataManager);
+
+  // Bring up the keyboard by tapping the city, which is the element before the
+  // picker.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
+      performAction:chrome_test_util::TapWebElement(kFormElementCity)];
+
+  UndockKeyboard();
+
+  // Verify the profiles icon.
+  [[EarlGrey selectElementWithMatcher:ProfilesIconMatcher()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  DockKeyboard();
+
+  // Verify the profiles icon is visible, and therefore also the input accessory
+  // bar.
+  [[EarlGrey selectElementWithMatcher:ProfilesIconMatcher()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/history/history_clear_browsing_data_coordinator.mm b/ios/chrome/browser/ui/history/history_clear_browsing_data_coordinator.mm
index 81f2cc7..d7020aa 100644
--- a/ios/chrome/browser/ui/history/history_clear_browsing_data_coordinator.mm
+++ b/ios/chrome/browser/ui/history/history_clear_browsing_data_coordinator.mm
@@ -72,7 +72,24 @@
 
 - (void)stopWithCompletion:(ProceduralBlock)completionHandler {
   if (self.historyClearBrowsingDataNavigationController) {
-    [self dismissClearBrowsingDataWithCompletion:completionHandler];
+    [self.clearBrowsingDataTableViewController prepareForDismissal];
+    [self.historyClearBrowsingDataNavigationController
+        dismissViewControllerAnimated:YES
+                           completion:^() {
+                             // completionHandler might trigger
+                             // dismissHistoryWithCompletion, which will call
+                             // stopWithCompletion:, so
+                             // historyClearBrowsingDataNavigationController
+                             // needs to be nil, otherwise stopWithCompletion:
+                             // will call dismiss with nothing to dismiss and
+                             // therefore not trigger its own completionHandler.
+                             self.clearBrowsingDataTableViewController = nil;
+                             self.historyClearBrowsingDataNavigationController =
+                                 nil;
+                             if (completionHandler) {
+                               completionHandler();
+                             }
+                           }];
   } else if (completionHandler) {
     completionHandler();
   }
@@ -81,13 +98,14 @@
 #pragma mark - ClearBrowsingDataLocalCommands
 
 - (void)openURL:(const GURL&)URL {
+  DCHECK(self.historyClearBrowsingDataNavigationController);
   OpenNewTabCommand* command =
       [[OpenNewTabCommand alloc] initWithURL:URL
                                     referrer:web::Referrer()
                                  inIncognito:NO
                                 inBackground:NO
                                     appendTo:kLastTab];
-  [self dismissClearBrowsingDataWithCompletion:^() {
+  [self stopWithCompletion:^() {
     [self.localDispatcher dismissHistoryWithCompletion:^{
       [self.loader webPageOrderedOpen:command];
       [self.presentationDelegate showActiveRegularTabFromHistory];
@@ -95,27 +113,9 @@
   }];
 }
 
-- (void)dismissClearBrowsingDataWithCompletion:
-    (ProceduralBlock)completionHandler {
+- (void)dismissClearBrowsingData {
   DCHECK(self.historyClearBrowsingDataNavigationController);
-  [self.clearBrowsingDataTableViewController prepareForDismissal];
-  [self.historyClearBrowsingDataNavigationController
-      dismissViewControllerAnimated:YES
-                         completion:^() {
-                           // completionHandler might trigger
-                           // dismissHistoryWithCompletion, which will call
-                           // stopWithCompletion:, so
-                           // historyClearBrowsingDataNavigationController needs
-                           // to be nil, otherwise stopWithCompletion: will call
-                           // dismiss with nothing to dismiss and therefore not
-                           // trigger its own completionHandler.
-                           self.clearBrowsingDataTableViewController = nil;
-                           self.historyClearBrowsingDataNavigationController =
-                               nil;
-                           if (completionHandler) {
-                             completionHandler();
-                           }
-                         }];
+  [self stopWithCompletion:nil];
 }
 
 #pragma mark - UIViewControllerTransitioningDelegate
diff --git a/ios/chrome/browser/ui/main/browser_view_wrangler.mm b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
index b21ac63..db900cc 100644
--- a/ios/chrome/browser/ui/main/browser_view_wrangler.mm
+++ b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
@@ -361,9 +361,8 @@
   [_incognitoBrowserCoordinator stop];
   _incognitoBrowserCoordinator = nil;
 
-  [self.mainBrowser->GetTabModel() closeAllTabs];
-  [self.otrBrowser->GetTabModel() closeAllTabs];
-  // Handles removing observers and stopping breakpad monitoring.
+  // Handles removing observers, stopping breakpad monitoring, and closing all
+  // tabs.
   [self setMainBrowser:nullptr];
   [self setOtrBrowser:nullptr];
 
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_local_commands.h b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_local_commands.h
index fabef39..4625d1a 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_local_commands.h
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_local_commands.h
@@ -15,8 +15,7 @@
 // view.
 - (void)openURL:(const GURL&)URL;
 // Notifies the coordinator that Clear Browsing Data should be dismissed.
-- (void)dismissClearBrowsingDataWithCompletion:
-    (ProceduralBlock)completionHandler;
+- (void)dismissClearBrowsingData;
 
 @end
 
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.h b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.h
index 8ebb234..c71f96b 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.h
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.h
@@ -5,7 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CLEAR_BROWSING_DATA_CLEAR_BROWSING_DATA_TABLE_VIEW_CONTROLLER_H_
 #define IOS_CHROME_BROWSER_UI_SETTINGS_CLEAR_BROWSING_DATA_CLEAR_BROWSING_DATA_TABLE_VIEW_CONTROLLER_H_
 
-#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h"
+#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
 
 namespace ios {
 class ChromeBrowserState;
@@ -16,7 +16,8 @@
 
 // TableView for clearing browsing data (including history,
 // cookies, caches, passwords, and autofill).
-@interface ClearBrowsingDataTableViewController : ChromeTableViewController
+@interface ClearBrowsingDataTableViewController
+    : SettingsRootTableViewController
 
 // Initializers. |browserState| can't be nil.
 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
index 95f397f..b2e60989 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
@@ -98,6 +98,8 @@
 
 - (void)viewDidLoad {
   [super viewDidLoad];
+  self.styler.tableViewBackgroundColor = UIColor.whiteColor;
+  self.tableView.backgroundColor = self.styler.tableViewBackgroundColor;
   // TableView configuration
   self.tableView.estimatedRowHeight = 56;
   self.tableView.rowHeight = UITableViewAutomaticDimension;
@@ -135,7 +137,7 @@
 
 - (void)dismiss {
   [self prepareForDismissal];
-  [self.localDispatcher dismissClearBrowsingDataWithCompletion:nil];
+  [self.localDispatcher dismissClearBrowsingData];
 }
 
 #pragma mark - Public Methods
diff --git a/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm b/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm
index 4aaa800..2350241 100644
--- a/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm
@@ -22,11 +22,14 @@
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/pref_names.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h"
 #import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_local_commands.h"
+#import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/dataplan_usage_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/handoff_table_view_controller.h"
@@ -72,8 +75,9 @@
 
 }  // namespace
 
-@interface PrivacyTableViewController ()<BooleanObserver,
-                                         PrefObserverDelegate> {
+@interface PrivacyTableViewController () <BooleanObserver,
+                                          ClearBrowsingDataLocalCommands,
+                                          PrefObserverDelegate> {
   ios::ChromeBrowserState* _browserState;  // weak
   PrefBackedBoolean* _suggestionsEnabled;
   // The item related to the switch for the show suggestions setting.
@@ -350,8 +354,16 @@
                             IDS_IOS_OPTIONS_SEND_USAGE_DATA)];
       break;
     case ItemTypeClearBrowsingDataClear:
-      controller = [[ClearBrowsingDataCollectionViewController alloc]
-          initWithBrowserState:_browserState];
+      if (base::FeatureList::IsEnabled(kSettingsRefresh)) {
+        ClearBrowsingDataTableViewController* clearBrowsingDataViewController =
+            [[ClearBrowsingDataTableViewController alloc]
+                initWithBrowserState:_browserState];
+        clearBrowsingDataViewController.localDispatcher = self;
+        controller = clearBrowsingDataViewController;
+      } else {
+        controller = [[ClearBrowsingDataCollectionViewController alloc]
+            initWithBrowserState:_browserState];
+      }
       break;
     case ItemTypeCanMakePaymentSwitch:
     case ItemTypeWebServicesShowSuggestions:
@@ -379,6 +391,21 @@
   [self reconfigureCellsForItems:@[ _showSuggestionsItem ]];
 }
 
+#pragma mark - ClearBrowsingDataLocalCommands
+
+- (void)openURL:(const GURL&)URL {
+  DCHECK(self.dispatcher);
+  OpenNewTabCommand* command = [OpenNewTabCommand commandWithURLFromChrome:URL];
+  [self.dispatcher closeSettingsUIAndOpenURL:command];
+}
+
+- (void)dismissClearBrowsingData {
+  SettingsNavigationController* navigationController =
+      base::mac::ObjCCastStrict<SettingsNavigationController>(
+          self.navigationController);
+  [navigationController closeSettings];
+}
+
 #pragma mark - Actions
 
 - (void)showSuggestionsToggled:(UISwitch*)sender {
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
index 040d501..cfd1bb4 100644
--- a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
@@ -87,7 +87,7 @@
     syncer::SyncService* service =
         ProfileSyncServiceFactory::GetForBrowserState(browserState_);
     if (service->IsEngineInitialized() &&
-        service->IsUsingSecondaryPassphrase()) {
+        service->GetUserSettings()->IsUsingSecondaryPassphrase()) {
       base::Time passphrase_time =
           service->GetUserSettings()->GetExplicitPassphraseTime();
       if (!passphrase_time.is_null()) {
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm
index b581e61..02c605a 100644
--- a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm
@@ -13,6 +13,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
@@ -70,8 +71,9 @@
     _browserState = browserState;
     syncer::SyncService* syncService =
         ProfileSyncServiceFactory::GetForBrowserState(_browserState);
-    _isUsingSecondaryPassphrase = syncService->IsEngineInitialized() &&
-                                  syncService->IsUsingSecondaryPassphrase();
+    _isUsingSecondaryPassphrase =
+        syncService->IsEngineInitialized() &&
+        syncService->GetUserSettings()->IsUsingSecondaryPassphrase();
     _syncObserver = std::make_unique<SyncObserverBridge>(self, syncService);
   }
   return self;
@@ -183,7 +185,7 @@
       syncer::SyncService* service =
           ProfileSyncServiceFactory::GetForBrowserState(_browserState);
       if (service->IsEngineInitialized() &&
-          !service->IsUsingSecondaryPassphrase()) {
+          !service->GetUserSettings()->IsUsingSecondaryPassphrase()) {
         SyncCreatePassphraseTableViewController* controller =
             [[SyncCreatePassphraseTableViewController alloc]
                 initWithBrowserState:_browserState];
@@ -210,7 +212,8 @@
   syncer::SyncService* service =
       ProfileSyncServiceFactory::GetForBrowserState(_browserState);
   BOOL isNowUsingSecondaryPassphrase =
-      service->IsEngineInitialized() && service->IsUsingSecondaryPassphrase();
+      service->IsEngineInitialized() &&
+      service->GetUserSettings()->IsUsingSecondaryPassphrase();
   if (_isUsingSecondaryPassphrase != isNowUsingSecondaryPassphrase) {
     _isUsingSecondaryPassphrase = isNowUsingSecondaryPassphrase;
     [self reloadData];
diff --git a/ios/third_party/earl_grey/BUILD.gn b/ios/third_party/earl_grey/BUILD.gn
index 893f13e..5b1c3ec 100644
--- a/ios/third_party/earl_grey/BUILD.gn
+++ b/ios/third_party/earl_grey/BUILD.gn
@@ -253,6 +253,7 @@
     "src/EarlGrey/Assertion/GREYAssertionBlock.h",
     "src/EarlGrey/Assertion/GREYAssertionDefines.h",
     "src/EarlGrey/Assertion/GREYAssertions.h",
+    "src/EarlGrey/Common/GREYAppleInternals.h",
     "src/EarlGrey/Common/GREYConfiguration.h",
     "src/EarlGrey/Common/GREYConstants.h",
     "src/EarlGrey/Common/GREYDefines.h",
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn
index 65df0143..1ed62261 100644
--- a/ios/third_party/material_components_ios/BUILD.gn
+++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -34,7 +34,7 @@
     "src/components/Buttons/src/ShapeThemer",
     "src/components/Buttons/src/Theming",
     "src/components/AppBar/src",
-    "src/components/private/ShapeLibrary/src",
+    "src/components/ShapeLibrary/src",
     "src/components/ButtonBar/src",
     "src/components/Buttons/src",
     "src/components/Cards/src",
@@ -56,7 +56,7 @@
     "src/components/Snackbar/src",
     "src/components/Themes/src",
     "src/components/Typography/src",
-    "src/components/private/Shapes/src/",
+    "src/components/Shapes/src/",
     "src/components/private/UIMetrics/src",
     "src/components/schemes/Color/src",
     "src/components/schemes/Container/src/",
@@ -297,6 +297,27 @@
     "src/components/ShadowLayer/src/MDCShadowLayer.h",
     "src/components/ShadowLayer/src/MDCShadowLayer.m",
     "src/components/ShadowLayer/src/MaterialShadowLayer.h",
+    "src/components/ShapeLibrary/src/MDCCornerTreatment+CornerTypeInitalizer.m",
+    "src/components/ShapeLibrary/src/MDCCornerTreatment+CornerTypeInitalizerNew.h",
+    "src/components/ShapeLibrary/src/MDCCurvedCornerTreatment.m",
+    "src/components/ShapeLibrary/src/MDCCurvedCornerTreatmentNew.h",
+    "src/components/ShapeLibrary/src/MDCCutCornerTreatment.m",
+    "src/components/ShapeLibrary/src/MDCCutCornerTreatmentNew.h",
+    "src/components/ShapeLibrary/src/MDCRoundedCornerTreatment.m",
+    "src/components/ShapeLibrary/src/MDCRoundedCornerTreatmentNew.h",
+    "src/components/Shapes/src/MDCCornerTreatment.m",
+    "src/components/Shapes/src/MDCCornerTreatmentNew.h",
+    "src/components/Shapes/src/MDCEdgeTreatment.m",
+    "src/components/Shapes/src/MDCEdgeTreatmentNew.h",
+    "src/components/Shapes/src/MDCPathGenerator.m",
+    "src/components/Shapes/src/MDCPathGeneratorNew.h",
+    "src/components/Shapes/src/MDCRectangleShapeGenerator.m",
+    "src/components/Shapes/src/MDCRectangleShapeGeneratorNew.h",
+    "src/components/Shapes/src/MDCShapedShadowLayer.m",
+    "src/components/Shapes/src/MDCShapedShadowLayerNew.h",
+    "src/components/Shapes/src/MDCShapedView.m",
+    "src/components/Shapes/src/MDCShapedViewNew.h",
+    "src/components/Shapes/src/MaterialShapesNew.h",
     "src/components/Snackbar/src/MDCSnackbarManager.h",
     "src/components/Snackbar/src/MDCSnackbarManager.m",
     "src/components/Snackbar/src/MDCSnackbarMessage.h",
@@ -357,27 +378,6 @@
     "src/components/private/Overlay/src/private/MDCOverlayObserverTransition.m",
     "src/components/private/Overlay/src/private/MDCOverlayUtilities.h",
     "src/components/private/Overlay/src/private/MDCOverlayUtilities.m",
-    "src/components/private/ShapeLibrary/src/MDCCornerTreatment+CornerTypeInitalizer.h",
-    "src/components/private/ShapeLibrary/src/MDCCornerTreatment+CornerTypeInitalizer.m",
-    "src/components/private/ShapeLibrary/src/MDCCurvedCornerTreatment.h",
-    "src/components/private/ShapeLibrary/src/MDCCurvedCornerTreatment.m",
-    "src/components/private/ShapeLibrary/src/MDCCutCornerTreatment.h",
-    "src/components/private/ShapeLibrary/src/MDCCutCornerTreatment.m",
-    "src/components/private/ShapeLibrary/src/MDCRoundedCornerTreatment.h",
-    "src/components/private/ShapeLibrary/src/MDCRoundedCornerTreatment.m",
-    "src/components/private/Shapes/src/MDCCornerTreatment.h",
-    "src/components/private/Shapes/src/MDCCornerTreatment.m",
-    "src/components/private/Shapes/src/MDCEdgeTreatment.h",
-    "src/components/private/Shapes/src/MDCEdgeTreatment.m",
-    "src/components/private/Shapes/src/MDCPathGenerator.h",
-    "src/components/private/Shapes/src/MDCPathGenerator.m",
-    "src/components/private/Shapes/src/MDCRectangleShapeGenerator.h",
-    "src/components/private/Shapes/src/MDCRectangleShapeGenerator.m",
-    "src/components/private/Shapes/src/MDCShapedShadowLayer.h",
-    "src/components/private/Shapes/src/MDCShapedShadowLayer.m",
-    "src/components/private/Shapes/src/MDCShapedView.h",
-    "src/components/private/Shapes/src/MDCShapedView.m",
-    "src/components/private/Shapes/src/MaterialShapes.h",
     "src/components/private/ThumbTrack/src/MDCNumericValueLabel.h",
     "src/components/private/ThumbTrack/src/MDCNumericValueLabel.m",
     "src/components/private/ThumbTrack/src/MDCThumbTrack.h",
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index ef86db7f..9781037 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -434,6 +434,7 @@
     "//components/url_formatter",
     "//ios/net",
     "//ios/testing:ocmock_support",
+    "//ios/web/find_in_page",
     "//ios/web/public",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
@@ -441,7 +442,6 @@
     "//ios/web/test:test_constants",
     "//ios/web/test:test_support",
     "//ios/web/web_state:context_menu",
-    "//ios/web/web_state:find_in_page",
     "//ios/web/web_state:navigation_context",
     "//ios/web/web_state/js",
     "//ios/web/web_state/js:script_util",
diff --git a/ios/web/find_in_page/BUILD.gn b/ios/web/find_in_page/BUILD.gn
new file mode 100644
index 0000000..0150e60
--- /dev/null
+++ b/ios/web/find_in_page/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("find_in_page") {
+  deps = [
+    "//base",
+    "//ios/web/public/",
+    "//ios/web/web_state:web_frame",
+    "//ios/web/web_state:web_state_impl_header",
+  ]
+
+  sources = [
+    "find_in_page_constants.h",
+    "find_in_page_constants.mm",
+    "find_in_page_manager_impl.h",
+    "find_in_page_manager_impl.mm",
+  ]
+
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
diff --git a/ios/web/web_state/find_in_page/find_in_page_constants.h b/ios/web/find_in_page/find_in_page_constants.h
similarity index 68%
rename from ios/web/web_state/find_in_page/find_in_page_constants.h
rename to ios/web/find_in_page/find_in_page_constants.h
index d13abac..4ae2c52 100644
--- a/ios/web/web_state/find_in_page/find_in_page_constants.h
+++ b/ios/web/find_in_page/find_in_page_constants.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_CONSTANTS_H_
-#define IOS_WEB_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_CONSTANTS_H_
+#ifndef IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_CONSTANTS_H_
+#define IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_CONSTANTS_H_
 
 namespace web {
 
@@ -14,4 +14,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_CONSTANTS_H_
+#endif  // IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_CONSTANTS_H_
diff --git a/ios/web/web_state/find_in_page/find_in_page_constants.mm b/ios/web/find_in_page/find_in_page_constants.mm
similarity index 86%
rename from ios/web/web_state/find_in_page/find_in_page_constants.mm
rename to ios/web/find_in_page/find_in_page_constants.mm
index 44e369f..af4792f 100644
--- a/ios/web/web_state/find_in_page/find_in_page_constants.mm
+++ b/ios/web/find_in_page/find_in_page_constants.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/web_state/find_in_page/find_in_page_constants.h"
+#import "ios/web/find_in_page/find_in_page_constants.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/web/web_state/find_in_page/find_in_page_manager_impl.h b/ios/web/find_in_page/find_in_page_manager_impl.h
similarity index 89%
rename from ios/web/web_state/find_in_page/find_in_page_manager_impl.h
rename to ios/web/find_in_page/find_in_page_manager_impl.h
index 61f25ee..4ee00f4 100644
--- a/ios/web/web_state/find_in_page/find_in_page_manager_impl.h
+++ b/ios/web/find_in_page/find_in_page_manager_impl.h
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_
-#define IOS_WEB_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_
+#ifndef IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_
+#define IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_
 
 #include <list>
 #include <map>
 #include <string>
 
 #include "base/memory/weak_ptr.h"
-#import "ios/web/public/web_state/find_in_page/find_in_page_manager.h"
+#import "ios/web/public/find_in_page/find_in_page_manager.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 
 namespace web {
@@ -70,4 +70,4 @@
 };
 }  // namespace web
 
-#endif  // IOS_WEB_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_
+#endif  // IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_
diff --git a/ios/web/web_state/find_in_page/find_in_page_manager_impl.mm b/ios/web/find_in_page/find_in_page_manager_impl.mm
similarity index 97%
rename from ios/web/web_state/find_in_page/find_in_page_manager_impl.mm
rename to ios/web/find_in_page/find_in_page_manager_impl.mm
index 199a35967..8a11623 100644
--- a/ios/web/web_state/find_in_page/find_in_page_manager_impl.mm
+++ b/ios/web/find_in_page/find_in_page_manager_impl.mm
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/web_state/find_in_page/find_in_page_manager_impl.h"
+#import "ios/web/find_in_page/find_in_page_manager_impl.h"
 
 #import "base/strings/sys_string_conversions.h"
 #include "base/values.h"
+#import "ios/web/find_in_page/find_in_page_constants.h"
 #import "ios/web/public/web_state/web_frame.h"
 #include "ios/web/public/web_state/web_frame_util.h"
 #import "ios/web/public/web_state/web_frames_manager.h"
-#import "ios/web/web_state/find_in_page/find_in_page_constants.h"
 #import "ios/web/web_state/web_state_impl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/public/BUILD.gn b/ios/web/public/BUILD.gn
index a9df31c..68e6e3e 100644
--- a/ios/web/public/BUILD.gn
+++ b/ios/web/public/BUILD.gn
@@ -62,7 +62,6 @@
     "web_client.h",
     "web_kit_constants.h",
     "web_state/context_menu_params.h",
-    "web_state/find_in_page/find_in_page_manager.h",
     "web_state/global_web_state_observer.h",
     "web_state/js/crw_js_injection_evaluator.h",
     "web_state/js/crw_js_injection_manager.h",
diff --git a/ios/web/public/find_in_page/BUILD.gn b/ios/web/public/find_in_page/BUILD.gn
new file mode 100644
index 0000000..c27758a
--- /dev/null
+++ b/ios/web/public/find_in_page/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("find_in_page") {
+  deps = [
+    "//base",
+    "//ios/web/public/",
+  ]
+
+  sources = [
+    "find_in_page_manager.h",
+  ]
+
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
diff --git a/ios/web/public/web_state/find_in_page/find_in_page_manager.h b/ios/web/public/find_in_page/find_in_page_manager.h
similarity index 89%
rename from ios/web/public/web_state/find_in_page/find_in_page_manager.h
rename to ios/web/public/find_in_page/find_in_page_manager.h
index 64d16ba..e5c77984 100644
--- a/ios/web/public/web_state/find_in_page/find_in_page_manager.h
+++ b/ios/web/public/find_in_page/find_in_page_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_PUBLIC_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_H_
+#ifndef IOS_WEB_PUBLIC_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_H_
+#define IOS_WEB_PUBLIC_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_H_
 
 #include "base/macros.h"
 #import "ios/web/public/web_state/web_state_user_data.h"
@@ -51,4 +51,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_H_
+#endif  // IOS_WEB_PUBLIC_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_H_
diff --git a/ios/web/web_state/BUILD.gn b/ios/web/web_state/BUILD.gn
index 8ca83350..3074ddb0 100644
--- a/ios/web/web_state/BUILD.gn
+++ b/ios/web/web_state/BUILD.gn
@@ -165,24 +165,6 @@
   configs += [ "//build/config/compiler:enable_arc" ]
 }
 
-source_set("find_in_page") {
-  deps = [
-    ":web_frame",
-    ":web_state_impl_header",
-    "//base",
-    "//ios/web/public",
-  ]
-
-  sources = [
-    "find_in_page/find_in_page_constants.h",
-    "find_in_page/find_in_page_constants.mm",
-    "find_in_page/find_in_page_manager_impl.h",
-    "find_in_page/find_in_page_manager_impl.mm",
-  ]
-
-  configs += [ "//build/config/compiler:enable_arc" ]
-}
-
 source_set("web_frame") {
   deps = [
     ":web_state_impl_header",
diff --git a/ios/web/web_state/js/find_in_page_unittest.mm b/ios/web/web_state/js/find_in_page_unittest.mm
index d075c80..b5932d7 100644
--- a/ios/web/web_state/js/find_in_page_unittest.mm
+++ b/ios/web/web_state/js/find_in_page_unittest.mm
@@ -5,11 +5,11 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #import "base/test/ios/wait_util.h"
+#import "ios/web/find_in_page/find_in_page_constants.h"
 #import "ios/web/public/test/web_test_with_web_state.h"
 #import "ios/web/public/web_state/web_frame.h"
 #import "ios/web/public/web_state/web_frame_util.h"
 #import "ios/web/public/web_state/web_frames_manager.h"
-#import "ios/web/web_state/find_in_page/find_in_page_constants.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/web_view/internal/sync/cwv_sync_controller.mm b/ios/web_view/internal/sync/cwv_sync_controller.mm
index 88bb0f4..5b8ab92b 100644
--- a/ios/web_view/internal/sync/cwv_sync_controller.mm
+++ b/ios/web_view/internal/sync/cwv_sync_controller.mm
@@ -166,7 +166,7 @@
 }
 
 - (BOOL)isPassphraseNeeded {
-  return _syncService->IsPassphraseRequiredForDecryption();
+  return _syncService->GetUserSettings()->IsPassphraseRequiredForDecryption();
 }
 
 - (void)startSyncWithIdentity:(CWVIdentity*)identity
diff --git a/ios/web_view/internal/sync/web_view_profile_invalidation_provider_factory.mm b/ios/web_view/internal/sync/web_view_profile_invalidation_provider_factory.mm
index 1adeba7..3a5d740 100644
--- a/ios/web_view/internal/sync/web_view_profile_invalidation_provider_factory.mm
+++ b/ios/web_view/internal/sync/web_view_profile_invalidation_provider_factory.mm
@@ -24,8 +24,6 @@
 #include "ios/web/public/web_task_traits.h"
 #include "ios/web_view/internal/app/application_context.h"
 #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
-#include "ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h"
-#include "ios/web_view/internal/signin/web_view_signin_manager_factory.h"
 #include "ios/web_view/internal/sync/web_view_gcm_profile_service_factory.h"
 #include "ios/web_view/internal/web_view_browser_state.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -84,9 +82,7 @@
           "InvalidationService",
           BrowserStateDependencyManager::GetInstance()) {
   DependsOn(WebViewIdentityManagerFactory::GetInstance());
-  DependsOn(WebViewSigninManagerFactory::GetInstance());
   DependsOn(WebViewGCMProfileServiceFactory::GetInstance());
-  DependsOn(WebViewOAuth2TokenServiceFactory::GetInstance());
 }
 
 WebViewProfileInvalidationProviderFactory::
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 1ad3330..4336fd5 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -294,6 +294,7 @@
   VLOGF(2);
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
   DCHECK_EQ(decoder_state_, kInitialized);
+  TRACE_EVENT0("media,gpu", "V4L2VDA::InitializeTask");
 
   if (IsDestroyPending())
     return;
@@ -356,6 +357,8 @@
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
   DCHECK_EQ(decoder_state_, kAwaitingPictureBuffers);
   DCHECK(output_queue_);
+  TRACE_EVENT1("media,gpu", "V4L2VDA::AssignPictureBuffersTask", "buffers_size",
+               buffers.size());
 
   if (IsDestroyPending())
     return;
@@ -619,6 +622,9 @@
             << ", dmabuf_fds.size()=" << dmabuf_fds.size()
             << ", stride=" << stride;
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
+  TRACE_EVENT2("media,gpu", "V4L2VDA::ImportBufferForPictureTask",
+               "picture_buffer_id", picture_buffer_id, "dmabuf_fds_size",
+               dmabuf_fds.size());
 
   if (IsDestroyPending())
     return;
@@ -821,7 +827,6 @@
   DVLOGF(4) << "input_id=" << bitstream_id;
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
   DCHECK_NE(decoder_state_, kUninitialized);
-  TRACE_EVENT1("media,gpu", "V4L2VDA::DecodeTask", "input_id", bitstream_id);
 
   if (IsDestroyPending())
     return;
@@ -1213,6 +1218,9 @@
   // Enqueue once since there's new available input for it.
   Enqueue();
 
+  TRACE_COUNTER_ID1("media,gpu", "V4L2VDA input ready buffers", this,
+                    input_ready_queue_.size());
+
   return (decoder_state_ != kError);
 }
 
@@ -1310,7 +1318,6 @@
   DCHECK_NE(decoder_state_, kUninitialized);
   DCHECK(input_queue_);
   DCHECK(output_queue_);
-  TRACE_EVENT0("media,gpu", "V4L2VDA::Enqueue");
 
   // Drain the pipe of completed decode buffers.
   const int old_inputs_queued = input_queue_->QueuedBuffersCount();
@@ -1425,7 +1432,6 @@
   DCHECK_NE(decoder_state_, kUninitialized);
   DCHECK(input_queue_);
   DCHECK(output_queue_);
-  TRACE_EVENT0("media,gpu", "V4L2VDA::Dequeue");
 
   while (input_queue_->QueuedBuffersCount() > 0) {
     if (!DequeueInputBuffer())
@@ -1601,7 +1607,6 @@
     std::unique_ptr<gl::GLFenceEGL> egl_fence) {
   DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id;
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
-  TRACE_EVENT0("media,gpu", "V4L2VDA::ReusePictureBufferTask");
 
   if (IsDestroyPending())
     return;
@@ -1646,12 +1651,20 @@
 
   // We got a buffer back, so enqueue it back.
   Enqueue();
+
+  TRACE_COUNTER_ID2(
+      "media,gpu", "V4L2 output buffers", this, "in client",
+      GetNumOfRecordsInState(kAtClient), "in vda",
+      output_buffer_map_.size() - GetNumOfRecordsInState(kAtClient));
+  TRACE_COUNTER_ID2(
+      "media,gpu", "V4L2 output buffers in vda", this, "free",
+      GetNumOfRecordsInState(kFree), "in device or IP",
+      GetNumOfRecordsInState(kAtDevice) + GetNumOfRecordsInState(kAtProcessor));
 }
 
 void V4L2VideoDecodeAccelerator::FlushTask() {
   VLOGF(2);
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
-  TRACE_EVENT0("media,gpu", "V4L2VDA::FlushTask");
 
   if (IsDestroyPending())
     return;
@@ -1661,6 +1674,8 @@
     return;
   }
 
+  TRACE_EVENT_ASYNC_BEGIN0("media,gpu", "V4L2VDA::FlushTask", this);
+
   // We don't support stacked flushing.
   DCHECK(!decoder_flushing_);
 
@@ -1730,6 +1745,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::NofityFlushDone() {
+  TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2VDA::FlushTask", this);
   decoder_delay_bitstream_buffer_id_ = -1;
   decoder_flushing_ = false;
   VLOGF(2) << "returning flush";
@@ -1769,7 +1785,6 @@
 void V4L2VideoDecodeAccelerator::ResetTask() {
   VLOGF(2);
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
-  TRACE_EVENT0("media,gpu", "V4L2VDA::ResetTask");
 
   if (IsDestroyPending())
     return;
@@ -1778,6 +1793,9 @@
     VLOGF(2) << "early out: kError state";
     return;
   }
+
+  TRACE_EVENT_ASYNC_BEGIN0("media,gpu", "V4L2VDA::ResetTask", this);
+
   decoder_current_bitstream_buffer_.reset();
   while (!decoder_input_queue_.empty())
     decoder_input_queue_.pop_front();
@@ -1843,7 +1861,6 @@
 void V4L2VideoDecodeAccelerator::ResetDoneTask() {
   VLOGF(2);
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
-  TRACE_EVENT0("media,gpu", "V4L2VDA::ResetDoneTask");
 
   if (IsDestroyPending())
     return;
@@ -1853,6 +1870,8 @@
     return;
   }
 
+  TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2VDA::ResetTask", this);
+
   // Start poll thread if NotifyFlushDoneIfNeeded has not already.
   if (!device_poll_thread_.IsRunning()) {
     if (!StartDevicePoll())
@@ -2765,6 +2784,14 @@
   NOTIFY_ERROR(PLATFORM_FAILURE);
 }
 
+size_t V4L2VideoDecodeAccelerator::GetNumOfRecordsInState(
+    OutputRecordState state) const {
+  DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
+  return std::count_if(
+      output_buffer_map_.begin(), output_buffer_map_.end(),
+      [state = state](const auto& r) { return r.state == state; });
+}
+
 bool V4L2VideoDecodeAccelerator::OnMemoryDump(
     const base::trace_event::MemoryDumpArgs& args,
     base::trace_event::ProcessMemoryDump* pmd) {
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
index 032a84d..0e2fe2d 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -400,6 +400,10 @@
 
   void SendBufferToClient(size_t buffer_index, int32_t bitstream_buffer_id);
 
+  // Returns the number of OutputRecords whose state is |state|. This is used to
+  // compute values reported for chrome://tracing.
+  size_t GetNumOfRecordsInState(OutputRecordState state) const;
+
   //
   // Methods run on child thread.
   //
diff --git a/mojo/public/cpp/system/BUILD.gn b/mojo/public/cpp/system/BUILD.gn
index 07fc688..01b62788f 100644
--- a/mojo/public/cpp/system/BUILD.gn
+++ b/mojo/public/cpp/system/BUILD.gn
@@ -26,6 +26,7 @@
     "buffer.cc",
     "buffer.h",
     "core.h",
+    "data_pipe.cc",
     "data_pipe.h",
     "data_pipe_drainer.cc",
     "data_pipe_drainer.h",
diff --git a/mojo/public/cpp/system/data_pipe.cc b/mojo/public/cpp/system/data_pipe.cc
new file mode 100644
index 0000000..8fe5ed7c8
--- /dev/null
+++ b/mojo/public/cpp/system/data_pipe.cc
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/public/cpp/system/data_pipe.h"
+
+namespace mojo {
+
+namespace {
+
+NOINLINE void CrashMojoResourceExhausted() {
+  LOG(FATAL)
+      << "Failed to create data pipe due to MOJO_RESULT_RESOURCE_EXHAUSTED.";
+}
+
+void CrashIfResultNotOk(MojoResult result) {
+  if (LIKELY(result == MOJO_RESULT_OK))
+    return;
+
+  // Include some extra information for resource exhausted failures.
+  if (result == MOJO_RESULT_RESOURCE_EXHAUSTED)
+    CrashMojoResourceExhausted();
+
+  LOG(FATAL) << "Failed to create data pipe; result=" << result;
+}
+
+}  // namespace
+
+DataPipe::DataPipe() {
+  MojoResult result =
+      CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
+  CrashIfResultNotOk(result);
+}
+
+DataPipe::DataPipe(uint32_t capacity_num_bytes) {
+  MojoCreateDataPipeOptions options;
+  options.struct_size = sizeof(MojoCreateDataPipeOptions);
+  options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+  options.element_num_bytes = 1;
+  options.capacity_num_bytes = capacity_num_bytes;
+  MojoResult result =
+      CreateDataPipe(&options, &producer_handle, &consumer_handle);
+  CrashIfResultNotOk(result);
+}
+
+DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) {
+  MojoResult result =
+      CreateDataPipe(&options, &producer_handle, &consumer_handle);
+  CrashIfResultNotOk(result);
+}
+
+DataPipe::~DataPipe() {}
+
+}  // namespace mojo
diff --git a/mojo/public/cpp/system/data_pipe.h b/mojo/public/cpp/system/data_pipe.h
index c810ed4..205af85 100644
--- a/mojo/public/cpp/system/data_pipe.h
+++ b/mojo/public/cpp/system/data_pipe.h
@@ -141,7 +141,7 @@
 // TODO(vtl): Make an even more friendly version? (Maybe templatized for a
 // particular type instead of some "element"? Maybe functions that take
 // vectors?)
-class DataPipe {
+class MOJO_CPP_SYSTEM_EXPORT DataPipe {
  public:
   DataPipe();
   explicit DataPipe(uint32_t capacity_num_bytes);
@@ -152,32 +152,6 @@
   ScopedDataPipeConsumerHandle consumer_handle;
 };
 
-inline DataPipe::DataPipe() {
-  MojoResult result =
-      CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
-  CHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-inline DataPipe::DataPipe(uint32_t capacity_num_bytes) {
-  MojoCreateDataPipeOptions options;
-  options.struct_size = sizeof(MojoCreateDataPipeOptions);
-  options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
-  options.element_num_bytes = 1;
-  options.capacity_num_bytes = capacity_num_bytes;
-  MojoResult result =
-      CreateDataPipe(&options, &producer_handle, &consumer_handle);
-  CHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-inline DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) {
-  MojoResult result =
-      CreateDataPipe(&options, &producer_handle, &consumer_handle);
-  CHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-inline DataPipe::~DataPipe() {
-}
-
 }  // namespace mojo
 
 #endif  // MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl
index a29a1b7f..d825b489 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl
@@ -35,7 +35,7 @@
       return mojo::Equals(data_.{{field.name}}, other.data_.{{field.name}});
 {%-   endif %}
 {%- endfor %}
-  };
+  }
 
   return false;
 }
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index c161b7e3..211a41b 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -131,6 +131,7 @@
     session_context.ct_policy_enforcer = ct_policy_enforcer();
     session_context.transport_security_state = transport_security_state();
     session_context.proxy_resolution_service = proxy_resolution_service();
+    session_context.proxy_delegate = proxy_delegate();
     session_context.ssl_config_service = ssl_config_service();
     session_context.http_auth_handler_factory = http_auth_handler_factory();
     session_context.http_server_properties = http_server_properties();
diff --git a/printing/nup_parameters.h b/printing/nup_parameters.h
index 0171f9f4..d4d656d 100644
--- a/printing/nup_parameters.h
+++ b/printing/nup_parameters.h
@@ -18,9 +18,9 @@
   static bool IsSupported(int pages_per_sheet);
 
   // Orientation of the to-be-generated N-up PDF document.
-  bool landscape() const { return landscape_; };
-  int num_pages_on_x_axis() const { return num_pages_on_x_axis_; };
-  int num_pages_on_y_axis() const { return num_pages_on_y_axis_; };
+  bool landscape() const { return landscape_; }
+  int num_pages_on_x_axis() const { return num_pages_on_x_axis_; }
+  int num_pages_on_y_axis() const { return num_pages_on_y_axis_; }
 
   // Calculates the |num_pages_on_x_axis_|, |num_pages_on_y_axis_| and
   // |landscape_| based on the input.  |is_source_landscape| is true if the
diff --git a/services/identity/OWNERS b/services/identity/OWNERS
index 6adc5e2..d913972 100644
--- a/services/identity/OWNERS
+++ b/services/identity/OWNERS
@@ -1,6 +1,7 @@
 # COMPONENT: Services>SignIn
 
 blundell@chromium.org
+droger@chromium.org
 msarda@chromium.org
 sdefresne@chromium.org
 
diff --git a/services/identity/identity_manager_impl_unittest.cc b/services/identity/identity_manager_impl_unittest.cc
index 28ae35c..d0bb2b52 100644
--- a/services/identity/identity_manager_impl_unittest.cc
+++ b/services/identity/identity_manager_impl_unittest.cc
@@ -435,7 +435,7 @@
   // to call SignIn() here to ensure that GoogleSigninSucceeded() is fired by
   // the fake signin manager.
   static_cast<FakeSigninManager*>(signin_manager())
-      ->SignIn(kTestGaiaId, kTestEmail, "password");
+      ->SignIn(kTestGaiaId, kTestEmail);
 
   run_loop.Run();
 
diff --git a/services/identity/public/cpp/DEPS b/services/identity/public/cpp/DEPS
index 6d262c1..1b82c02 100644
--- a/services/identity/public/cpp/DEPS
+++ b/services/identity/public/cpp/DEPS
@@ -5,6 +5,7 @@
   "+components/signin/core/browser/fake_account_fetcher_service.h",
   "+components/signin/core/browser/fake_gaia_cookie_manager_service.h",
   "+components/signin/core/browser/gaia_cookie_manager_service.h",
+  "+components/signin/core/browser/list_accounts_test_utils.h",
   "+components/signin/core/browser/account_consistency_method.h",
   "+components/signin/core/browser/signin_buildflags.h",
   "+components/signin/core/browser/signin_internals_util.h",
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc
index 6379729a..8b2c7ac16 100644
--- a/services/identity/public/cpp/identity_manager.cc
+++ b/services/identity/public/cpp/identity_manager.cc
@@ -360,14 +360,6 @@
   }
 }
 
-void IdentityManager::GoogleSigninSucceededWithPassword(
-    const AccountInfo& account_info,
-    const std::string& password) {
-  for (auto& observer : observer_list_) {
-    observer.OnPrimaryAccountSetWithPassword(account_info, password);
-  }
-}
-
 void IdentityManager::GoogleSignedOut(const AccountInfo& account_info) {
   DCHECK(!HasPrimaryAccount());
   for (auto& observer : observer_list_) {
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h
index 9cb04a9d..bf5dca6 100644
--- a/services/identity/public/cpp/identity_manager.h
+++ b/services/identity/public/cpp/identity_manager.h
@@ -69,14 +69,6 @@
     // This method is not called during a reauth.
     virtual void OnPrimaryAccountSet(const AccountInfo& primary_account_info) {}
 
-    // Called when an account becomes the user's primary account using the
-    // legacy workflow (non-DICE). If access to the password is not required,
-    // it is preferred to instead override OnPrimaryAccountSet() which will
-    // also be called at the same time.
-    virtual void OnPrimaryAccountSetWithPassword(
-        const AccountInfo& primary_account_info,
-        const std::string& password) {}
-
     // Called when when the user moves from having a primary account to no
     // longer having a primary account.
     virtual void OnPrimaryAccountCleared(
@@ -451,8 +443,6 @@
 
   // SigninManagerBase::Observer:
   void GoogleSigninSucceeded(const AccountInfo& account_info) override;
-  void GoogleSigninSucceededWithPassword(const AccountInfo& account_info,
-                                         const std::string& password) override;
   void GoogleSignedOut(const AccountInfo& account_info) override;
   void GoogleSigninFailed(const GoogleServiceAuthError& error) override;
 
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc
index dfc5f2a..f04335b 100644
--- a/services/identity/public/cpp/identity_manager_unittest.cc
+++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -12,9 +12,9 @@
 #include "build/build_config.h"
 #include "components/signin/core/browser/account_consistency_method.h"
 #include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h"
 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
 #include "components/signin/core/browser/fake_signin_manager.h"
+#include "components/signin/core/browser/list_accounts_test_utils.h"
 #include "components/signin/core/browser/signin_switches.h"
 #include "components/signin/core/browser/test_signin_client.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
@@ -450,13 +450,19 @@
 }  // namespace
 
 class IdentityManagerTest : public testing::Test {
- public:
+ protected:
   IdentityManagerTest()
       : signin_client_(&pref_service_),
         token_service_(&pref_service_),
-        gaia_cookie_manager_service_(&token_service_,
-                                     &signin_client_,
-                                     &test_url_loader_factory_) {
+        gaia_cookie_manager_service_(
+            &token_service_,
+            &signin_client_,
+            base::BindRepeating(
+                [](network::TestURLLoaderFactory* test_url_loader_factory)
+                    -> scoped_refptr<network::SharedURLLoaderFactory> {
+                  return test_url_loader_factory->GetSafeWeakWrapper();
+                },
+                test_url_loader_factory())) {
     AccountTrackerService::RegisterPrefs(pref_service_.registry());
     ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry());
     SigninManagerBase::RegisterProfilePrefs(pref_service_.registry());
@@ -482,7 +488,7 @@
   CustomFakeProfileOAuth2TokenService* token_service() {
     return &token_service_;
   }
-  FakeGaiaCookieManagerService* gaia_cookie_manager_service() {
+  GaiaCookieManagerService* gaia_cookie_manager_service() {
     return &gaia_cookie_manager_service_;
   }
 
@@ -570,6 +576,10 @@
     consumer->OnMergeSessionFailure(error);
   }
 
+  network::TestURLLoaderFactory* test_url_loader_factory() {
+    return &test_url_loader_factory_;
+  }
+
  private:
   base::MessageLoop message_loop_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
@@ -577,7 +587,7 @@
   TestSigninClient signin_client_;
   CustomFakeProfileOAuth2TokenService token_service_;
   network::TestURLLoaderFactory test_url_loader_factory_;
-  FakeGaiaCookieManagerService gaia_cookie_manager_service_;
+  GaiaCookieManagerService gaia_cookie_manager_service_;
   std::unique_ptr<SigninManagerForTest> signin_manager_;
   std::unique_ptr<IdentityManager> identity_manager_;
   std::unique_ptr<TestIdentityManagerObserver> identity_manager_observer_;
@@ -605,7 +615,7 @@
   identity_manager_observer()->set_on_primary_account_set_callback(
       run_loop.QuitClosure());
 
-  signin_manager()->SignIn(kTestGaiaId, kTestEmail, "password");
+  signin_manager()->SignIn(kTestGaiaId, kTestEmail);
   run_loop.Run();
 
   AccountInfo primary_account_from_set_callback =
@@ -631,7 +641,7 @@
   base::RunLoop run_loop;
   identity_manager_observer()->set_on_primary_account_set_callback(
       run_loop.QuitClosure());
-  signin_manager()->SignIn(kTestGaiaId, kTestEmail, "password");
+  signin_manager()->SignIn(kTestGaiaId, kTestEmail);
   run_loop.Run();
 
   // Sign the user out and check that the IdentityManager responds
@@ -666,7 +676,7 @@
   base::RunLoop run_loop;
   identity_manager_observer()->set_on_primary_account_set_callback(
       run_loop.QuitClosure());
-  signin_manager()->SignIn(kTestGaiaId, kTestEmail, "password");
+  signin_manager()->SignIn(kTestGaiaId, kTestEmail);
   run_loop.Run();
 
   // Remove the account from the AccountTrackerService and check that
@@ -1456,7 +1466,7 @@
   RecreateIdentityManager();
   signin_manager_observer.set_identity_manager(identity_manager());
 
-  signin_manager()->SignIn(kTestGaiaId, kTestEmail, "password");
+  signin_manager()->SignIn(kTestGaiaId, kTestEmail);
   run_loop.Run();
 
   AccountInfo primary_account_from_signin_callback =
@@ -1769,7 +1779,7 @@
   identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
       run_loop.QuitClosure());
 
-  gaia_cookie_manager_service()->SetListAccountsResponseNoAccounts();
+  signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());
   gaia_cookie_manager_service()->TriggerListAccounts();
   run_loop.Run();
 
@@ -1785,8 +1795,8 @@
   identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
       run_loop.QuitClosure());
 
-  gaia_cookie_manager_service()->SetListAccountsResponseOneAccount(kTestEmail,
-                                                                   kTestGaiaId);
+  signin::SetListAccountsResponseOneAccount(kTestEmail, kTestGaiaId,
+                                            test_url_loader_factory());
   gaia_cookie_manager_service()->TriggerListAccounts();
   run_loop.Run();
 
@@ -1811,8 +1821,9 @@
   identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
       run_loop.QuitClosure());
 
-  gaia_cookie_manager_service()->SetListAccountsResponseTwoAccounts(
-      kTestEmail, kTestGaiaId, kTestEmail2, kTestGaiaId2);
+  signin::SetListAccountsResponseTwoAccounts(kTestEmail, kTestGaiaId,
+                                             kTestEmail2, kTestGaiaId2,
+                                             test_url_loader_factory());
   gaia_cookie_manager_service()->TriggerListAccounts();
   run_loop.Run();
 
@@ -1852,11 +1863,12 @@
     identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
         run_loop.QuitClosure());
 
-    gaia_cookie_manager_service()->SetListAccountsResponseWithParams(
+    signin::SetListAccountsResponseWithParams(
         {{kTestEmail, kTestGaiaId, true /* valid */,
           signed_out_status.account_1 /* signed_out */, true /* verified */},
          {kTestEmail2, kTestGaiaId2, true /* valid */,
-          signed_out_status.account_2 /* signed_out */, true /* verified */}});
+          signed_out_status.account_2 /* signed_out */, true /* verified */}},
+        test_url_loader_factory());
 
     gaia_cookie_manager_service()->TriggerListAccounts();
     run_loop.Run();
@@ -1909,7 +1921,7 @@
       run_loop.QuitClosure());
 
   // Configure list accounts to return a permanent Gaia auth error.
-  gaia_cookie_manager_service()->SetListAccountsResponseWebLoginRequired();
+  signin::SetListAccountsResponseWebLoginRequired(test_url_loader_factory());
   gaia_cookie_manager_service()->TriggerListAccounts();
   run_loop.Run();
 
@@ -1925,7 +1937,7 @@
   identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
       run_loop.QuitClosure());
 
-  gaia_cookie_manager_service()->SetListAccountsResponseNoAccounts();
+  signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());
 
   // Do an initial call to GetAccountsInCookieJar(). This call should return no
   // accounts but should also trigger an internal update and eventual
@@ -1953,8 +1965,8 @@
   identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
       run_loop.QuitClosure());
 
-  gaia_cookie_manager_service()->SetListAccountsResponseOneAccount(kTestEmail,
-                                                                   kTestGaiaId);
+  signin::SetListAccountsResponseOneAccount(kTestEmail, kTestGaiaId,
+                                            test_url_loader_factory());
 
   // Do an initial call to GetAccountsInCookieJar(). This call should return no
   // accounts but should also trigger an internal update and eventual
@@ -1990,8 +2002,9 @@
   identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
       run_loop.QuitClosure());
 
-  gaia_cookie_manager_service()->SetListAccountsResponseTwoAccounts(
-      kTestEmail, kTestGaiaId, kTestEmail2, kTestGaiaId2);
+  signin::SetListAccountsResponseTwoAccounts(kTestEmail, kTestGaiaId,
+                                             kTestEmail2, kTestGaiaId2,
+                                             test_url_loader_factory());
 
   // Do an initial call to GetAccountsInCookieJar(). This call should return no
   // accounts but should also trigger an internal update and eventual
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc
index e3b60af..c5e0ecb 100644
--- a/services/identity/public/cpp/identity_test_utils.cc
+++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -167,7 +167,7 @@
   // Note: pass an empty string as the refresh token so that no refresh token is
   // set.
   real_signin_manager->StartSignInWithRefreshToken(
-      /*refresh_token=*/"", gaia_id, email, /*password=*/"",
+      /*refresh_token=*/"", gaia_id, email,
       /*oauth_fetched_callback=*/base::DoNothing());
   real_signin_manager->CompletePendingSignin();
 
diff --git a/services/identity/public/cpp/primary_account_mutator.h b/services/identity/public/cpp/primary_account_mutator.h
index c4a5f12..c2ef177 100644
--- a/services/identity/public/cpp/primary_account_mutator.h
+++ b/services/identity/public/cpp/primary_account_mutator.h
@@ -80,7 +80,6 @@
       const std::string& refresh_token,
       const std::string& gaia_id,
       const std::string& username,
-      const std::string& password,
       base::OnceCallback<void(const std::string&)> callback) = 0;
 
   // Complete the in-process sign-in (legacy, pre-DICE workflow).
diff --git a/services/identity/public/cpp/primary_account_mutator_impl.cc b/services/identity/public/cpp/primary_account_mutator_impl.cc
index 947f6ffe..db9edf3 100644
--- a/services/identity/public/cpp/primary_account_mutator_impl.cc
+++ b/services/identity/public/cpp/primary_account_mutator_impl.cc
@@ -4,6 +4,8 @@
 
 #include "services/identity/public/cpp/primary_account_mutator_impl.h"
 
+#include <utility>
+
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 
@@ -81,10 +83,9 @@
         const std::string& refresh_token,
         const std::string& gaia_id,
         const std::string& username,
-        const std::string& password,
         base::OnceCallback<void(const std::string&)> callback) {
   signin_manager_->StartSignInWithRefreshToken(refresh_token, gaia_id, username,
-                                               password, std::move(callback));
+                                               std::move(callback));
 }
 
 void PrimaryAccountMutatorImpl::LegacyCompletePendingPrimaryAccountSignin() {
diff --git a/services/identity/public/cpp/primary_account_mutator_impl.h b/services/identity/public/cpp/primary_account_mutator_impl.h
index 8df5aea..54de8cc7 100644
--- a/services/identity/public/cpp/primary_account_mutator_impl.h
+++ b/services/identity/public/cpp/primary_account_mutator_impl.h
@@ -33,7 +33,6 @@
       const std::string& refresh_token,
       const std::string& gaia_id,
       const std::string& username,
-      const std::string& password,
       base::OnceCallback<void(const std::string&)> callback) override;
   void LegacyCompletePendingPrimaryAccountSignin() override;
   void LegacyMergeSigninCredentialIntoCookieJar() override;
diff --git a/services/identity/public/cpp/primary_account_mutator_unittest.cc b/services/identity/public/cpp/primary_account_mutator_unittest.cc
index a98334d6..9ca642e 100644
--- a/services/identity/public/cpp/primary_account_mutator_unittest.cc
+++ b/services/identity/public/cpp/primary_account_mutator_unittest.cc
@@ -21,7 +21,6 @@
 const char kPrimaryAccountEmail[] = "primary.account@example.com";
 const char kAnotherAccountEmail[] = "another.account@example.com";
 const char kRefreshToken[] = "refresh_token";
-const char kPassword[] = "password";
 
 // All account consistency methods that are tested by those unit tests when
 // testing ClearPrimaryAccount method.
@@ -559,7 +558,7 @@
   base::RunLoop run_loop;
   std::string signed_account_refresh_token;
   primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      kRefreshToken, account_info.gaia, account_info.email,
       base::BindOnce(
           [](std::string* out_refresh_token, const std::string& refresh_token) {
             *out_refresh_token = refresh_token;
@@ -671,7 +670,7 @@
   // whether we end up with a similar result than with SetPrimaryAccount().
   std::string signed_account_refresh_token;
   primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      kRefreshToken, account_info.gaia, account_info.email,
       base::BindOnce(
           [](std::string* out_refresh_token, const std::string& refresh_token) {
             *out_refresh_token = refresh_token;
@@ -735,7 +734,7 @@
   base::RunLoop run_loop;
   std::string signed_account_refresh_token;
   primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      kRefreshToken, account_info.gaia, account_info.email,
       base::BindOnce(
           [](std::string* out_refresh_token, const std::string& refresh_token) {
             *out_refresh_token = refresh_token;
@@ -803,7 +802,7 @@
   base::RunLoop run_loop;
   std::string signed_account_refresh_token;
   primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      kRefreshToken, account_info.gaia, account_info.email,
       base::BindOnce(
           [](std::string* out_refresh_token, const std::string& refresh_token) {
             *out_refresh_token = refresh_token;
@@ -877,7 +876,7 @@
   base::RunLoop run_loop;
   std::string signed_account_refresh_token;
   primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
-      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      kRefreshToken, account_info.gaia, account_info.email,
       base::BindOnce(
           [](std::string* out_refresh_token, const std::string& refresh_token) {
             *out_refresh_token = refresh_token;
diff --git a/services/identity/public/objc/identity_manager_observer_bridge.h b/services/identity/public/objc/identity_manager_observer_bridge.h
index c8c6fb8..2586c19 100644
--- a/services/identity/public/objc/identity_manager_observer_bridge.h
+++ b/services/identity/public/objc/identity_manager_observer_bridge.h
@@ -23,8 +23,6 @@
 // these semantics.
 
 - (void)onPrimaryAccountSet:(const AccountInfo&)primaryAccountInfo;
-- (void)onPrimaryAccountSet:(const AccountInfo&)primaryAccountInfo
-               withPassword:(const std::string&)password;
 - (void)onPrimaryAccountCleared:(const AccountInfo&)previousPrimaryAccountInfo;
 - (void)onPrimaryAccountSigninFailed:(const GoogleServiceAuthError&)error;
 - (void)onRefreshTokenUpdatedForAccount:(const AccountInfo&)accountInfo;
@@ -51,8 +49,6 @@
 
   // IdentityManager::Observer.
   void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override;
-  void OnPrimaryAccountSetWithPassword(const AccountInfo& primary_account_info,
-                                       const std::string& password) override;
   void OnPrimaryAccountCleared(
       const AccountInfo& previous_primary_account_info) override;
   void OnPrimaryAccountSigninFailed(
diff --git a/services/identity/public/objc/identity_manager_observer_bridge.mm b/services/identity/public/objc/identity_manager_observer_bridge.mm
index 3aab9a0..b29391b5 100644
--- a/services/identity/public/objc/identity_manager_observer_bridge.mm
+++ b/services/identity/public/objc/identity_manager_observer_bridge.mm
@@ -28,15 +28,6 @@
   }
 }
 
-void IdentityManagerObserverBridge::OnPrimaryAccountSetWithPassword(
-    const AccountInfo& primary_account_info,
-    const std::string& password) {
-  if ([delegate_ respondsToSelector:@selector(onPrimaryAccountSet:
-                                                     withPassword:)]) {
-    [delegate_ onPrimaryAccountSet:primary_account_info withPassword:password];
-  }
-}
-
 void IdentityManagerObserverBridge::OnPrimaryAccountCleared(
     const AccountInfo& previous_primary_account_info) {
   if ([delegate_ respondsToSelector:@selector(onPrimaryAccountCleared:)]) {
diff --git a/testing/test.gni b/testing/test.gni
index d04dad1..a7dd581 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -135,7 +135,7 @@
         }
       }
       unittest_apk(_apk_target) {
-        forward_variables_from(invoker, _apk_specific_vars + [ "deps" ])
+        forward_variables_from(invoker, _apk_specific_vars)
         shared_library = ":$_library_target"
         apk_name = invoker.target_name
         if (defined(invoker.output_name)) {
@@ -143,6 +143,12 @@
           install_script_name = "install_${invoker.output_name}"
         }
 
+        if (defined(invoker.deps)) {
+          deps = invoker.deps
+        } else {
+          deps = []
+        }
+
         # Add the Java classes so that each target does not have to do it.
         deps += [ "//base/test:test_support_java" ]
 
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 3f4cc34f..0801e31 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -64,6 +64,7 @@
 /directxsdk
 /dom_distiller_js/dist
 /elfutils/src
+/emoji-segmenter/src
 /errorprone/lib
 /espresso/lib/
 /eyesfree/src
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
index a53d2161..33a03750 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
@@ -335,46 +335,6 @@
   Visitor* const visitor_;
 };
 
-// Visitor purging all DOM wrapper handles.
-class DOMWrapperPurgingVisitor final
-    : public v8::PersistentHandleVisitor,
-      public v8::EmbedderHeapTracer::TracedGlobalHandleVisitor {
- public:
-  explicit DOMWrapperPurgingVisitor(v8::Isolate* isolate)
-      : isolate_(isolate), scope_(isolate) {}
-
-  void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
-                             uint16_t class_id) final {
-    // TODO(mlippautz): There should be no more v8::Persistent that have a class
-    // id set.
-    VisitHandle(value, class_id);
-  }
-
-  void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>& value) final {
-    VisitHandle(&value, value.WrapperClassId());
-  }
-
- private:
-  template <typename T>
-  void VisitHandle(T* value, uint16_t class_id) {
-    if (!IsDOMWrapperClassId(class_id))
-      return;
-
-    // Clear out wrapper type information, essentially disconnecting the Blink
-    // wrappable from the V8 wrapper. This way, V8 cannot find the C++ object
-    // anymore.
-    int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
-    void* values[] = {nullptr, nullptr};
-    v8::Local<v8::Object> wrapper =
-        v8::Local<v8::Object>::New(isolate_, value->template As<v8::Object>());
-    wrapper->SetAlignedPointerInInternalFields(base::size(indices), indices,
-                                               values);
-  }
-
-  v8::Isolate* const isolate_;
-  v8::HandleScope scope_;
-};
-
 }  // namespace
 
 void V8GCController::TraceDOMWrappers(v8::Isolate* isolate,
@@ -389,15 +349,4 @@
     tracer->IterateTracedGlobalHandles(&visitor);
 }
 
-void V8GCController::ClearDOMWrappers(v8::Isolate* isolate) {
-  DOMWrapperPurgingVisitor visitor(isolate);
-  isolate->VisitHandlesWithClassIds(&visitor);
-  v8::EmbedderHeapTracer* tracer =
-      V8PerIsolateData::From(isolate)->GetEmbedderHeapTracer();
-  // There may be no tracer during tear down garbage collections.
-  // Not all threads have a tracer attached.
-  if (tracer)
-    tracer->IterateTracedGlobalHandles(&visitor);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index abf6a94..784d08e3 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -2190,6 +2190,7 @@
     "streams/queue_with_sizes_test.cc",
     "streams/readable_stream_operations_test.cc",
     "streams/readable_stream_test.cc",
+    "streams/stream_promise_resolver_test.cc",
     "streams/test_underlying_source.h",
     "streams/transform_stream_test.cc",
     "streams/writable_stream_test.cc",
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 96253bd..592726f 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1502,8 +1502,14 @@
 void LayoutBox::SetOverrideBlockPercentageResolutionSize(
     LayoutUnit logical_height) {
   DCHECK_GE(logical_height, LayoutUnit(-1));
-  EnsureRareData().override_block_percentage_resolution_size_ = logical_height;
-  EnsureRareData().has_override_block_percentage_resolution_size_ = true;
+  auto& rare_data = EnsureRareData();
+
+  // The actual data field is shared with override available inline size. They
+  // cannot be in use at the same time.
+  DCHECK(!rare_data.has_override_available_inline_size_);
+
+  rare_data.override_block_percentage_resolution_size_ = logical_height;
+  rare_data.has_override_block_percentage_resolution_size_ = true;
 }
 
 void LayoutBox::ClearOverrideBlockPercentageResolutionSize() {
@@ -1512,6 +1518,33 @@
   EnsureRareData().has_override_block_percentage_resolution_size_ = false;
 }
 
+LayoutUnit LayoutBox::OverrideAvailableInlineSize() const {
+  DCHECK(HasOverrideAvailableInlineSize());
+  return rare_data_->override_block_percentage_resolution_size_;
+}
+
+bool LayoutBox::HasOverrideAvailableInlineSize() const {
+  return rare_data_ && rare_data_->has_override_available_inline_size_;
+}
+
+void LayoutBox::SetOverrideAvailableInlineSize(LayoutUnit inline_size) {
+  DCHECK_GE(inline_size, LayoutUnit());
+  auto& rare_data = EnsureRareData();
+
+  // The actual data field is shared with override block percentage resolution
+  // size. They cannot be in use at the same time.
+  DCHECK(!rare_data.has_override_block_percentage_resolution_size_);
+
+  rare_data.override_available_inline_size_ = inline_size;
+  rare_data.has_override_available_inline_size_ = true;
+}
+
+void LayoutBox::ClearOverrideAvailableInlineSize() {
+  if (!rare_data_)
+    return;
+  EnsureRareData().has_override_available_inline_size_ = false;
+}
+
 LayoutUnit LayoutBox::AdjustBorderBoxLogicalWidthForBoxSizing(
     float width) const {
   LayoutUnit borders_plus_padding = CollapsedBorderAndCSSPaddingLogicalWidth();
@@ -2841,6 +2874,10 @@
                                        available_size_for_resolving_margin);
   margin_end = MinimumValueForLength(StyleRef().MarginEnd(),
                                      available_size_for_resolving_margin);
+
+  if (HasOverrideAvailableInlineSize())
+    available_logical_width = OverrideAvailableInlineSize();
+
   LayoutUnit available = available_logical_width - margin_start - margin_end;
   available = std::max(available, LayoutUnit());
   return available;
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 9847527..d4252aa2 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -72,6 +72,7 @@
         has_override_containing_block_content_logical_width_(false),
         has_override_containing_block_content_logical_height_(false),
         has_override_block_percentage_resolution_size_(false),
+        has_override_available_inline_size_(false),
         has_previous_content_box_rect_and_layout_overflow_rect_(false),
         percent_height_container_(nullptr),
         snap_container_(nullptr),
@@ -87,11 +88,22 @@
   bool has_override_containing_block_content_logical_width_ : 1;
   bool has_override_containing_block_content_logical_height_ : 1;
   bool has_override_block_percentage_resolution_size_ : 1;
+  bool has_override_available_inline_size_ : 1;
   bool has_previous_content_box_rect_and_layout_overflow_rect_ : 1;
 
   LayoutUnit override_containing_block_content_logical_width_;
   LayoutUnit override_containing_block_content_logical_height_;
-  LayoutUnit override_block_percentage_resolution_size_;
+
+  // Put two members that aren't used at the same time inside a union, to save
+  // space. There are DCHECKs to make sure that they aren't actually used at the
+  // same time. Currently, the percentage resolution block size is only used by
+  // custom layout children, while the available inline size is only used by
+  // LayoutNG. So, since custom layout containers are laid out by legacy, this
+  // should be safe.
+  union {
+    LayoutUnit override_block_percentage_resolution_size_;
+    LayoutUnit override_available_inline_size_;
+  };
 
   LayoutUnit offset_to_next_page_;
 
@@ -786,6 +798,14 @@
   void SetOverrideBlockPercentageResolutionSize(LayoutUnit);
   void ClearOverrideBlockPercentageResolutionSize();
 
+  // When an available inline size override has been set, we'll use that to fill
+  // available inline size, rather than deducing it from the containing block
+  // (and then subtract space taken up by adjacent floats).
+  LayoutUnit OverrideAvailableInlineSize() const;
+  bool HasOverrideAvailableInlineSize() const;
+  void SetOverrideAvailableInlineSize(LayoutUnit);
+  void ClearOverrideAvailableInlineSize();
+
   LayoutUnit AdjustBorderBoxLogicalWidthForBoxSizing(float width) const;
   LayoutUnit AdjustBorderBoxLogicalHeightForBoxSizing(float height) const;
   LayoutUnit AdjustContentBoxLogicalWidthForBoxSizing(float width) const;
diff --git a/third_party/blink/renderer/core/layout/layout_table.cc b/third_party/blink/renderer/core/layout/layout_table.cc
index 7a51f61..76c9fd2 100644
--- a/third_party/blink/renderer/core/layout/layout_table.cc
+++ b/third_party/blink/renderer/core/layout/layout_table.cc
@@ -326,15 +326,22 @@
         MinimumValueForLength(StyleRef().MarginEnd(), available_logical_width);
     LayoutUnit margin_total = margin_start + margin_end;
 
-    // Subtract out our margins to get the available content width.
-    LayoutUnit available_content_logical_width =
-        (container_width_in_inline_direction - margin_total)
-            .ClampNegativeToZero();
-    if (ShrinkToAvoidFloats() && cb->IsLayoutBlockFlow() &&
-        ToLayoutBlockFlow(cb)->ContainsFloats() &&
-        !has_perpendicular_containing_block)
-      available_content_logical_width = ShrinkLogicalWidthToAvoidFloats(
-          margin_start, margin_end, ToLayoutBlockFlow(cb));
+    LayoutUnit available_content_logical_width;
+    if (HasOverrideAvailableInlineSize()) {
+      available_content_logical_width =
+          (OverrideAvailableInlineSize() - margin_total).ClampNegativeToZero();
+    } else {
+      // Subtract out our margins to get the available content width.
+      available_content_logical_width =
+          (container_width_in_inline_direction - margin_total)
+              .ClampNegativeToZero();
+      if (ShrinkToAvoidFloats() && cb->IsLayoutBlockFlow() &&
+          ToLayoutBlockFlow(cb)->ContainsFloats() &&
+          !has_perpendicular_containing_block) {
+        available_content_logical_width = ShrinkLogicalWidthToAvoidFloats(
+            margin_start, margin_end, ToLayoutBlockFlow(cb));
+      }
+    }
 
     // Ensure we aren't bigger than our available width.
     LayoutUnit max_width = MaxPreferredLogicalWidth();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 4772228..18ffec3 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -179,14 +179,10 @@
 LayoutUnit CalculateAvailableInlineSizeForLegacy(
     const LayoutBox& box,
     const NGConstraintSpace& space) {
-  if (box.StyleRef().LogicalWidth().IsPercent()) {
-    if (box.ShouldComputeSizeAsReplaced())
-      return space.ReplacedPercentageResolutionInlineSize();
+  if (box.ShouldComputeSizeAsReplaced())
+    return space.ReplacedPercentageResolutionInlineSize();
 
-    return space.PercentageResolutionInlineSize();
-  }
-
-  return space.AvailableSize().inline_size;
+  return space.PercentageResolutionInlineSize();
 }
 
 LayoutUnit CalculateAvailableBlockSizeForLegacy(
@@ -893,6 +889,8 @@
     } else {
       box_->ClearOverrideLogicalHeight();
     }
+    box_->SetOverrideAvailableInlineSize(
+        constraint_space.AvailableSize().inline_size);
     box_->ComputeAndSetBlockDirectionMargins(box_->ContainingBlock());
 
     // Using |LayoutObject::LayoutIfNeeded| save us a little bit of overhead,
diff --git a/third_party/blink/renderer/core/streams/BUILD.gn b/third_party/blink/renderer/core/streams/BUILD.gn
index 967339af..4040416 100644
--- a/third_party/blink/renderer/core/streams/BUILD.gn
+++ b/third_party/blink/renderer/core/streams/BUILD.gn
@@ -18,6 +18,10 @@
     "retain_wrapper_during_construction.cc",
     "retain_wrapper_during_construction.h",
     "stream_algorithms.h",
+    "stream_promise_resolver.cc",
+    "stream_promise_resolver.h",
+    "stream_script_function.cc",
+    "stream_script_function.h",
     "transform_stream.cc",
     "transform_stream.h",
     "transform_stream_default_controller.cc",
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.cc b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
new file mode 100644
index 0000000..587676a1
--- /dev/null
+++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
@@ -0,0 +1,94 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/streams/stream_promise_resolver.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+
+namespace blink {
+
+StreamPromiseResolver* StreamPromiseResolver::CreateResolved(
+    ScriptState* script_state,
+    v8::Local<v8::Value> value) {
+  auto* promise = MakeGarbageCollected<StreamPromiseResolver>(script_state);
+  promise->Resolve(script_state, value);
+  return promise;
+}
+
+StreamPromiseResolver* StreamPromiseResolver::CreateResolvedWithUndefined(
+    ScriptState* script_state) {
+  return CreateResolved(script_state,
+                        v8::Undefined(script_state->GetIsolate()));
+}
+
+StreamPromiseResolver* StreamPromiseResolver::CreateRejected(
+    ScriptState* script_state,
+    v8::Local<v8::Value> reason) {
+  auto* promise = MakeGarbageCollected<StreamPromiseResolver>(script_state);
+  promise->Reject(script_state, reason);
+  return promise;
+}
+
+// The constructor crashes if a v8::Promise::Resolver object cannot be created.
+// TODO(ricea): If necessary change this to make all the methods no-op instead.
+StreamPromiseResolver::StreamPromiseResolver(ScriptState* script_state)
+    : resolver_(script_state->GetIsolate(),
+                v8::Promise::Resolver::New(script_state->GetContext())
+                    .ToLocalChecked()) {}
+
+StreamPromiseResolver::~StreamPromiseResolver() = default;
+
+void StreamPromiseResolver::Resolve(ScriptState* script_state,
+                                    v8::Local<v8::Value> value) {
+  DCHECK(!resolver_.IsEmpty());
+  auto result = resolver_.NewLocal(script_state->GetIsolate())
+                    ->Resolve(script_state->GetContext(), value);
+  if (result.IsNothing()) {
+    DVLOG(3) << "Assuming JS shutdown and ignoring failed Resolve";
+  }
+}
+
+void StreamPromiseResolver::ResolveWithUndefined(ScriptState* script_state) {
+  Resolve(script_state, v8::Undefined(script_state->GetIsolate()));
+}
+
+void StreamPromiseResolver::Reject(ScriptState* script_state,
+                                   v8::Local<v8::Value> reason) {
+  DCHECK(!resolver_.IsEmpty());
+  auto result = resolver_.NewLocal(script_state->GetIsolate())
+                    ->Reject(script_state->GetContext(), reason);
+  if (result.IsNothing()) {
+    DVLOG(3) << "Assuming JS shutdown and ignoring failed Reject";
+  }
+}
+
+ScriptPromise StreamPromiseResolver::GetScriptPromise(
+    ScriptState* script_state) const {
+  return ScriptPromise(script_state, V8Promise(script_state->GetIsolate()));
+}
+
+v8::Local<v8::Promise> StreamPromiseResolver::V8Promise(
+    v8::Isolate* isolate) const {
+  DCHECK(!resolver_.IsEmpty());
+  return resolver_.NewLocal(isolate)->GetPromise();
+}
+
+void StreamPromiseResolver::MarkAsHandled(v8::Isolate* isolate) {
+  V8Promise(isolate)->MarkAsHandled();
+}
+
+v8::Promise::PromiseState StreamPromiseResolver::State(
+    v8::Isolate* isolate) const {
+  return V8Promise(isolate)->State();
+}
+
+void StreamPromiseResolver::Trace(Visitor* visitor) {
+  visitor->Trace(resolver_);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.h b/third_party/blink/renderer/core/streams/stream_promise_resolver.h
new file mode 100644
index 0000000..fef07e6
--- /dev/null
+++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.h
@@ -0,0 +1,84 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_STREAM_PROMISE_RESOLVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_STREAM_PROMISE_RESOLVER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class ScriptPromise;
+class ScriptState;
+class Visitor;
+
+// A thin wrapper around v8::Promise::Resolver that matches the semantics used
+// for promises in the standard. StreamPromiseResolver is used for promises that
+// need to be stored somewhere: promises on the stack should generally use
+// v8::Local<v8::Promise>, or ScriptPromise if they are to be returned to the
+// bindings code.
+class CORE_EXPORT StreamPromiseResolver
+    : public GarbageCollectedFinalized<StreamPromiseResolver> {
+ public:
+  // Implements "a promise rejected with" from the INFRA standard.
+  // https://www.w3.org/2001/tag/doc/promises-guide/#a-promise-rejected-with
+  // Prefer PromiseResolve() in miscellaneous_operations.h if the value is to be
+  // returned to JavaScript without storing it. This function should not be used
+  // when |value| might be a Promise already, as it will not pass it through
+  // unchanged at the standard requires.
+  static StreamPromiseResolver* CreateResolved(ScriptState*,
+                                               v8::Local<v8::Value> value);
+
+  // Implements "a promise resolved with *undefined*". Prefer
+  // PromiseResolveWithUndefined() from miscellaneous_operations.h if the value
+  // is to be returned to JavaScript without storing it.
+  static StreamPromiseResolver* CreateResolvedWithUndefined(ScriptState*);
+
+  // Implements "a promise rejected with" from the INFRA standard.
+  // https://www.w3.org/2001/tag/doc/promises-guide/#a-promise-rejected-with
+  // Prefer PromiseResolveWithUndefined() from miscellaneous_operations.h if the
+  // value is to be returned directly to JavaScript.
+  static StreamPromiseResolver* CreateRejected(ScriptState*,
+                                               v8::Local<v8::Value> reason);
+
+  // Creates an initialised promise.
+  explicit StreamPromiseResolver(ScriptState*);
+  ~StreamPromiseResolver();
+
+  // Resolves the promise with |value|. Does nothing if the promise is already
+  // settled.
+  void Resolve(ScriptState*, v8::Local<v8::Value> value);
+
+  // Resolves the promise with undefined.
+  void ResolveWithUndefined(ScriptState*);
+
+  // Rejects the promise with |reason|. Does nothing if the promise is already
+  // resolved.
+  void Reject(ScriptState*, v8::Local<v8::Value> reason);
+
+  // Returns the promise wrapped in a ScriptPromise.
+  ScriptPromise GetScriptPromise(ScriptState* script_state) const;
+
+  // Returns the promise as a v8::Promise.
+  v8::Local<v8::Promise> V8Promise(v8::Isolate* isolate) const;
+
+  // Marks the promise is handled, so if it is rejected it won't be considered
+  // an unhandled rejection.
+  void MarkAsHandled(v8::Isolate*);
+
+  // Returns the state of the promise, one of pending, fulfilled or rejected.
+  v8::Promise::PromiseState State(v8::Isolate*) const;
+
+  void Trace(Visitor*);
+
+ private:
+  TraceWrapperV8Reference<v8::Promise::Resolver> resolver_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_STREAM_PROMISE_RESOLVER_H_
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc b/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc
new file mode 100644
index 0000000..462ee8e
--- /dev/null
+++ b/third_party/blink/renderer/core/streams/stream_promise_resolver_test.cc
@@ -0,0 +1,125 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/streams/stream_promise_resolver.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/core/streams/stream_script_function.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+
+namespace blink {
+
+namespace {
+
+TEST(StreamPromiseResolverTest, Construct) {
+  V8TestingScope scope;
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  EXPECT_TRUE(promise->V8Promise(scope.GetIsolate())->IsPromise());
+}
+
+TEST(StreamPromiseResolverTest, Resolve) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  promise->Resolve(scope.GetScriptState(), v8::Null(isolate));
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kFulfilled);
+  EXPECT_TRUE(promise->V8Promise(isolate)->Result()->IsNull());
+}
+
+TEST(StreamPromiseResolverTest, ResolveWithUndefined) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  promise->ResolveWithUndefined(scope.GetScriptState());
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kFulfilled);
+  EXPECT_TRUE(promise->V8Promise(isolate)->Result()->IsUndefined());
+}
+
+TEST(StreamPromiseResolverTest, Reject) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  promise->Reject(scope.GetScriptState(), v8::Number::New(isolate, 2));
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kRejected);
+  auto result = promise->V8Promise(isolate)->Result();
+  ASSERT_TRUE(result->IsNumber());
+  EXPECT_EQ(result.As<v8::Number>()->Value(), 2.0);
+}
+
+TEST(StreamPromiseResolverTest, RejectDoesNothingAfterResolve) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  promise->Resolve(scope.GetScriptState(), v8::Undefined(isolate));
+  promise->Reject(scope.GetScriptState(), v8::Null(isolate));
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kFulfilled);
+  EXPECT_TRUE(promise->V8Promise(isolate)->Result()->IsUndefined());
+}
+
+TEST(StreamPromiseResolverTest, ResolveDoesNothingAfterReject) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  promise->Reject(scope.GetScriptState(), v8::Null(isolate));
+  promise->Resolve(scope.GetScriptState(), v8::Undefined(isolate));
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kRejected);
+  EXPECT_TRUE(promise->V8Promise(isolate)->Result()->IsNull());
+}
+
+TEST(StreamPromiseResolverTest, GetScriptPromise) {
+  V8TestingScope scope;
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  ScriptPromise script_promise =
+      promise->GetScriptPromise(scope.GetScriptState());
+  EXPECT_FALSE(script_promise.IsEmpty());
+}
+
+TEST(StreamPromiseResolverTest, MarkAsHandled) {
+  V8TestingScope scope;
+  auto* promise =
+      MakeGarbageCollected<StreamPromiseResolver>(scope.GetScriptState());
+  auto* isolate = scope.GetIsolate();
+  promise->MarkAsHandled(isolate);
+  EXPECT_TRUE(promise->V8Promise(isolate)->HasHandler());
+}
+
+TEST(StreamPromiseResolverTest, CreateResolved) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise = StreamPromiseResolver::CreateResolved(scope.GetScriptState(),
+                                                        v8::Null(isolate));
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kFulfilled);
+  EXPECT_TRUE(promise->V8Promise(isolate)->Result()->IsNull());
+}
+
+TEST(StreamPromiseResolverTest, CreateResolvedWithUndefined) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise = StreamPromiseResolver::CreateResolvedWithUndefined(
+      scope.GetScriptState());
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kFulfilled);
+  EXPECT_TRUE(promise->V8Promise(isolate)->Result()->IsUndefined());
+}
+
+TEST(StreamPromiseResolverTest, CreateRejected) {
+  V8TestingScope scope;
+  auto* isolate = scope.GetIsolate();
+  auto* promise = StreamPromiseResolver::CreateRejected(scope.GetScriptState(),
+                                                        v8::Null(isolate));
+  ASSERT_EQ(promise->State(isolate), v8::Promise::kRejected);
+  EXPECT_TRUE(promise->V8Promise(isolate)->Result()->IsNull());
+}
+
+}  // namespace
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/streams/stream_script_function.cc b/third_party/blink/renderer/core/streams/stream_script_function.cc
new file mode 100644
index 0000000..2bd72878
--- /dev/null
+++ b/third_party/blink/renderer/core/streams/stream_script_function.cc
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/streams/stream_script_function.h"
+
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+
+namespace blink {
+
+StreamScriptFunction::StreamScriptFunction(ScriptState* script_state)
+    : ScriptFunction(script_state) {}
+
+void StreamScriptFunction::CallRaw(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  DCHECK_GE(args.Length(), 1);
+  CallWithLocal(args[0]);
+}
+
+void StreamThenPromise(v8::Local<v8::Context> context,
+                       v8::Local<v8::Promise> promise,
+                       StreamScriptFunction* on_fulfilled,
+                       StreamScriptFunction* on_rejected) {
+  DCHECK(on_fulfilled);
+  DCHECK(on_rejected);
+  auto result = promise->Then(context, on_fulfilled->BindToV8Function(),
+                              on_rejected->BindToV8Function());
+  if (result.IsEmpty()) {
+    DVLOG(3)
+        << "assuming that failure of promise->Then() is caused by shutdown and"
+           "ignoring it";
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/streams/stream_script_function.h b/third_party/blink/renderer/core/streams/stream_script_function.h
new file mode 100644
index 0000000..9ed75c0
--- /dev/null
+++ b/third_party/blink/renderer/core/streams/stream_script_function.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_STREAM_SCRIPT_FUNCTION_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_STREAM_SCRIPT_FUNCTION_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+// A variant of ScriptFunction that avoids the conversion to and from a
+// ScriptValue.
+class CORE_EXPORT StreamScriptFunction : public ScriptFunction {
+ public:
+  explicit StreamScriptFunction(ScriptState* script_state);
+
+  virtual void CallWithLocal(v8::Local<v8::Value>) = 0;
+
+  // Exposed as public so that we don't need a boilerplate Create() function for
+  // every subclass.
+  using ScriptFunction::BindToV8Function;
+
+ private:
+  void CallRaw(const v8::FunctionCallbackInfo<v8::Value>&) final;
+};
+
+// A convenient wrapper for promise->Then() for when both paths are
+// StreamScriptFunctions. It avoids having to call BindToV8Function()
+// explicitly. Both |on_fulfilled| and |on_rejected| must be non-null.
+void StreamThenPromise(v8::Local<v8::Context>,
+                       v8::Local<v8::Promise>,
+                       StreamScriptFunction* on_fulfilled,
+                       StreamScriptFunction* on_rejected);
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_STREAM_SCRIPT_FUNCTION_H_
diff --git a/third_party/blink/renderer/core/workers/worker_backing_thread.cc b/third_party/blink/renderer/core/workers/worker_backing_thread.cc
index 5a3c9935..18d07fe 100644
--- a/third_party/blink/renderer/core/workers/worker_backing_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_backing_thread.cc
@@ -108,7 +108,6 @@
   Platform::Current()->WillStopWorkerThread();
 
   V8PerIsolateData::WillBeDestroyed(isolate_);
-  V8GCController::ClearDOMWrappers(isolate_);
   backing_thread_->ShutdownOnThread();
 
   RemoveWorkerIsolate(isolate_);
diff --git a/third_party/blink/renderer/modules/OWNERS b/third_party/blink/renderer/modules/OWNERS
index 731bf092..d438273 100644
--- a/third_party/blink/renderer/modules/OWNERS
+++ b/third_party/blink/renderer/modules/OWNERS
@@ -1,6 +1,7 @@
 dcheng@chromium.org
 haraken@chromium.org
 jbroman@chromium.org
+kinuko@chromium.org
 mkwst@chromium.org
 mlamouri@chromium.org
 
diff --git a/third_party/blink/renderer/modules/badging/OWNERS b/third_party/blink/renderer/modules/badging/OWNERS
index c8216ae..d9d061f 100644
--- a/third_party/blink/renderer/modules/badging/OWNERS
+++ b/third_party/blink/renderer/modules/badging/OWNERS
@@ -1,5 +1,6 @@
 estevenson@chromium.org
 mgiuca@chromium.org
+harrisjay@chromium.org
 
 # TEAM: apps-dev@chromium.org
 # COMPONENT: Platform>Apps
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl
index eae7611..6e460c4 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl
@@ -20,5 +20,5 @@
     //TODO(orphis): Missing ptime. https://crbug.com/857046
     unsigned long   maxBitrate;
     //TODO(orphis): Missing maxFramerate. https://crbug.com/857047
-    //TODO(orphis): Missing scaleResolutionDownBy. https://crbug.com/857048
+    double          scaleResolutionDownBy;
 };
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index 5df696b..9d91211 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -250,8 +250,13 @@
   webrtc_encoding.bitrate_priority = PriorityToDouble(encoding->priority());
   webrtc_encoding.network_priority =
       PriorityToDouble(encoding->networkPriority());
-  if (encoding->hasMaxBitrate())
+  if (encoding->hasMaxBitrate()) {
     webrtc_encoding.max_bitrate_bps = clampTo<int>(encoding->maxBitrate());
+  }
+  if (encoding->hasScaleResolutionDownBy()) {
+    webrtc_encoding.scale_resolution_down_by =
+        encoding->scaleResolutionDownBy();
+  }
   return webrtc_encoding;
 }
 
@@ -358,8 +363,13 @@
     // codecPayloadType, dtx, ptime, maxFramerate, scaleResolutionDownBy, rid
     RTCRtpEncodingParameters* encoding = RTCRtpEncodingParameters::Create();
     encoding->setActive(webrtc_encoding.active);
-    if (webrtc_encoding.max_bitrate_bps)
+    if (webrtc_encoding.max_bitrate_bps) {
       encoding->setMaxBitrate(webrtc_encoding.max_bitrate_bps.value());
+    }
+    if (webrtc_encoding.scale_resolution_down_by) {
+      encoding->setScaleResolutionDownBy(
+          webrtc_encoding.scale_resolution_down_by.value());
+    }
     encoding->setPriority(
         PriorityFromDouble(webrtc_encoding.bitrate_priority).c_str());
     encoding->setNetworkPriority(
diff --git a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
index 5766cb4..ea8cbfa4 100644
--- a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
+++ b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
@@ -179,6 +179,7 @@
   if (data->script_wrappable_visitor_->WrapperTracingInProgress())
     data->script_wrappable_visitor_->AbortTracingForTermination();
   data->script_wrappable_visitor_.reset();
+  data->unified_heap_controller_.reset();
 }
 
 // destroy() clear things that should be cleared after ThreadState::detach()
diff --git a/third_party/blink/renderer/platform/heap/heap_allocator.h b/third_party/blink/renderer/platform/heap/heap_allocator.h
index 64c50638..01d96002 100644
--- a/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -9,7 +9,6 @@
 #include "third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap_compact.h"
 #include "third_party/blink/renderer/platform/heap/marking_visitor.h"
 #include "third_party/blink/renderer/platform/heap/trace_traits.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
@@ -407,11 +406,6 @@
       !std::is_trivially_destructible<T>::value,
       "Finalization of trivially destructible classes should not happen.");
   HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
-
-  // TODO(keishi): Speculative check for crbug.com/918064
-  CHECK(!ThreadState::Current()->Heap().Compaction()->RangeHasInteriors(
-      header->Payload(), header->PayloadSize()));
-
   // Use the payload size as recorded by the heap to determine how many
   // elements to finalize.
   size_t length = header->PayloadSize() / sizeof(T);
@@ -441,9 +435,6 @@
       !std::is_trivially_destructible<Value>::value,
       "Finalization of trivially destructible classes should not happen.");
   HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
-  // TODO(keishi): Speculative check for crbug.com/918064
-  CHECK(!ThreadState::Current()->Heap().Compaction()->RangeHasInteriors(
-      header->Payload(), header->PayloadSize()));
   // Use the payload size as recorded by the heap to determine how many
   // elements to finalize.
   size_t length = header->PayloadSize() / sizeof(Value);
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.cc b/third_party/blink/renderer/platform/heap/heap_compact.cc
index 311daac..055f2dc 100644
--- a/third_party/blink/renderer/platform/heap/heap_compact.cc
+++ b/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -130,25 +130,6 @@
       fixup_callbacks_.erase(it);
   }
 
-  bool RangeHasInteriors(Address address, size_t size) {
-    if (!interiors_)
-      return false;
-
-    SparseHeapBitmap* range = interiors_->HasRange(address, size);
-    if (LIKELY(!range))
-      return false;
-
-    for (size_t offset = 0; offset < size; offset += sizeof(void*)) {
-      MovableReference* slot =
-          reinterpret_cast<MovableReference*>(address + offset);
-      if (range->IsSet(reinterpret_cast<Address>(slot)))
-        return true;
-    }
-
-    NOTREACHED();
-    return false;
-  }
-
   void RelocateInteriorFixups(Address from, Address to, size_t size) {
     SparseHeapBitmap* range = interiors_->HasRange(from, size);
     if (LIKELY(!range))
@@ -513,10 +494,6 @@
   Fixups().Relocate(from, to);
 }
 
-bool HeapCompact::RangeHasInteriors(Address address, size_t size) {
-  return fixups_ && fixups_->RangeHasInteriors(address, size);
-}
-
 void HeapCompact::StartThreadCompaction() {
   if (!do_compact_)
     return;
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.h b/third_party/blink/renderer/platform/heap/heap_compact.h
index a504be64..ec0ef44 100644
--- a/third_party/blink/renderer/platform/heap/heap_compact.h
+++ b/third_party/blink/renderer/platform/heap/heap_compact.h
@@ -123,9 +123,6 @@
   // (Called by the sweep compaction pass.)
   void Relocate(Address from, Address to);
 
-  // Returns true if range has registered interiors.
-  bool RangeHasInteriors(Address, size_t);
-
   // For unit testing only: arrange for a compaction GC to be triggered
   // next time a non-conservative GC is run. Sets the compact-next flag
   // to the new value, returning old.
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc
index a35433a..1c1c5ba 100644
--- a/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -1740,10 +1740,13 @@
 
   VisitPersistents(visitor);
 
-  // Unified garbage collections do not consider DOM wrapper references as
-  // roots. The cross-component references between V8<->Blink are found using
-  // collaborative tracing where both GCs report live references to each other.
-  if (!IsUnifiedGCMarkingInProgress()) {
+  // DOM wrapper references from V8 are considered as roots. Exceptions are:
+  // - Unified garbage collections: The cross-component references between
+  //   V8<->Blink are found using collaborative tracing where both GCs report
+  //   live references to each other.
+  // - Termination GCs that do not care about V8 any longer.
+  if (!IsUnifiedGCMarkingInProgress() &&
+      current_gc_data_.reason != BlinkGC::GCReason::kThreadTerminationGC) {
     VisitDOMWrappers(visitor);
   }
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index a5c7f574d..766dc5a1 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5892,19 +5892,25 @@
 crbug.com/922951 animations/direction-and-fill/fill-mode-transform.html [ Skip ]
 crbug.com/922951 animations/direction-and-fill/fill-mode.html [ Skip ]
 crbug.com/922951 compositing/overflow/overflow-scroll-with-local-background.html [ Skip ]
+crbug.com/922951 external/wpt/pointerevents/pointerevent_capture_mouse.html [ Skip ]
+crbug.com/922951 external/wpt/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html [ Skip ]
+crbug.com/922951 external/wpt/pointerevents/pointerevent_setpointercapture_disconnected.html [ Skip ]
+crbug.com/922951 external/wpt/pointerevents/pointerevent_setpointercapture_invalid_pointerid.html [ Skip ]
 crbug.com/922951 fast/dom/shadow/move-marquee-crossing-treescope-crash.html [ Skip ]
+crbug.com/922951 fast/forms/number/number-input-event-composed.html [ Skip ]
 crbug.com/922951 fast/loader/detach-while-printing.html [ Skip ]
 crbug.com/922951 fast/loader/document-open-iframe-then-detach.html [ Skip ]
 crbug.com/922951 fast/scroll-snap/snaps-after-keyboard-scrolling.html [ Skip ]
 crbug.com/922951 fast/scroll-snap/snaps-for-different-key-granularity.html [ Skip ]
 crbug.com/922951 fast/text/international/inline-plaintext-relayout-with-leading-neutrals.html [ Skip ]
 crbug.com/922951 http/tests/devtools/audits2/audits2-successful-run.js [ Skip ]
+crbug.com/922951 http/tests/devtools/tracing-session-id.js [ Skip ]
 crbug.com/922951 http/tests/devtools/tracing/console-timeline.js [ Skip ]
 crbug.com/922951 http/tests/devtools/tracing/timeline-network-received-data.js [ Skip ]
-crbug.com/922951 http/tests/devtools/tracing-session-id.js [ Skip ]
 crbug.com/922951 http/tests/images/feature-policy-unoptimized-images-cached-image.html [ Skip ]
 crbug.com/922951 http/tests/security/offscreencanvas-placeholder-read-blocked-no-crossorigin.html [ Skip ]
 crbug.com/922951 http/tests/webaudio/autoplay-crossorigin.html [ Skip ]
+crbug.com/922951 images/feature-policy-oversized-images-resize.html [ Skip ]
 crbug.com/922951 media/controls/overflow-menu-hide-on-click-outside-stoppropagation.html [ Skip ]
 crbug.com/922951 media/controls/overflow-menu-hide-on-click-outside.html [ Skip ]
 crbug.com/922951 media/controls/overflow-menu-toggle-class-for-animation.html [ Skip ]
@@ -5913,8 +5919,8 @@
 crbug.com/922951 svg/as-object/embedded-svg-immediate-offsetWidth-query.html [ Skip ]
 crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-fixed-percentage-intrinsic-ratio.html [ Skip ]
 crbug.com/922951 svg/custom/object-sizing-zero-intrinsic-width-height.html [ Skip ]
-crbug.com/922951 virtual/gpu/fast/canvas/color-space/canvas-drawImage-offscreenCanvas.html [ Skip ]
 crbug.com/922951 virtual/gpu/fast/canvas/OffscreenCanvas-placeholder-createImageBitmap.html [ Skip ]
+crbug.com/922951 virtual/gpu/fast/canvas/color-space/canvas-drawImage-offscreenCanvas.html [ Skip ]
 crbug.com/922951 virtual/mouseevent_fractional/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ]
 crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/modern/scrubbing-stops-when-controls-hidden.html [ Skip ]
 crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/overflow-menu-hide-on-click-outside-stoppropagation.html [ Skip ]
@@ -5930,8 +5936,8 @@
 crbug.com/922951 virtual/threaded/animations/direction-and-fill/fill-mode.html [ Skip ]
 crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/console-timeline.js [ Skip ]
 crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/frame-model-instrumentation.js [ Skip ]
-crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-layout/timeline-layout-with-invalidations.js [ Skip ]
 crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-layout/timeline-layout-reason.js [ Skip ]
+crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-layout/timeline-layout-with-invalidations.js [ Skip ]
 crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-record-reload.js [ Skip ]
 crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-paint/timeline-paint-image.js [ Skip ]
 crbug.com/922951 virtual/user-activation-v2/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ]
@@ -5977,3 +5983,5 @@
 
 crbug.com/v8/8319 external/wpt/wasm/jsapi/module/customSections.any.html [ Pass Failure ]
 crbug.com/v8/8319 external/wpt/wasm/jsapi/module/customSections.any.worker.html [ Pass Failure ]
+
+crbug.com/927296 virtual/wasm-site-isolated-code-cache/http/tests/devtools/wasm-isolated-code-cache/wasm-cache-test.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index b6ff4735..936e25b5 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -162244,11 +162244,6 @@
      {}
     ]
    ],
-   "html/browsers/offline/application-cache-api/api_update.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/browsers/offline/changestonetworkingmodel/original-id.json": [
     [
      {}
@@ -162759,6 +162754,11 @@
      {}
     ]
    ],
+   "html/browsers/windows/embedded-opener-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "html/browsers/windows/nested-browsing-contexts/contains.json": [
     [
      {}
@@ -186349,26 +186349,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/global/constructor.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/global/constructor.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/global/value-get-set.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/global/value-get-set.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/global/value-set.any-expected.txt": [
     [
      {}
@@ -186379,16 +186359,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/idlharness.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/idlharness.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/instance/constructor.any-expected.txt": [
     [
      {}
@@ -186404,16 +186374,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/interface.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/interface.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/memory/constructor.any-expected.txt": [
     [
      {}
@@ -186424,16 +186384,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/memory/grow.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/memory/grow.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/module/customSections.any-expected.txt": [
     [
      {}
@@ -186459,16 +186409,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/table/constructor.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/table/constructor.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/table/get-set.any-expected.txt": [
     [
      {}
@@ -186479,16 +186419,6 @@
      {}
     ]
    ],
-   "wasm/jsapi/table/grow.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/jsapi/table/grow.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/jsapi/wasm-constants.js": [
     [
      {}
@@ -186659,16 +186589,6 @@
      {}
     ]
    ],
-   "wasm/webapi/idlharness.any-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "wasm/webapi/idlharness.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "wasm/webapi/instantiateStreaming.any-expected.txt": [
     [
      {}
@@ -213084,6 +213004,24 @@
      {}
     ]
    ],
+   "css/css-sizing/table-percentage-max-width-beside-float.html": [
+    [
+     "/css/css-sizing/table-percentage-max-width-beside-float.html",
+     {}
+    ]
+   ],
+   "css/css-sizing/table-percentage-min-width-below-float.html": [
+    [
+     "/css/css-sizing/table-percentage-min-width-below-float.html",
+     {}
+    ]
+   ],
+   "css/css-sizing/table-percentage-min-width-beside-float.html": [
+    [
+     "/css/css-sizing/table-percentage-min-width-beside-float.html",
+     {}
+    ]
+   ],
    "css/css-syntax/anb-parsing.html": [
     [
      "/css/css-syntax/anb-parsing.html",
@@ -237250,6 +237188,18 @@
      {}
     ]
    ],
+   "html/browsers/windows/embedded-opener-a-form.html": [
+    [
+     "/html/browsers/windows/embedded-opener-a-form.html",
+     {}
+    ]
+   ],
+   "html/browsers/windows/embedded-opener.html": [
+    [
+     "/html/browsers/windows/embedded-opener.html",
+     {}
+    ]
+   ],
    "html/browsers/windows/nested-browsing-contexts/frameElement.sub.html": [
     [
      "/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html",
@@ -288332,13 +288282,13 @@
      {}
     ]
    ],
-   "workers/Worker-location.any.js": [
+   "workers/Worker-location.sub.any.js": [
     [
-     "/workers/Worker-location.any.sharedworker.html",
+     "/workers/Worker-location.sub.any.sharedworker.html",
      {}
     ],
     [
-     "/workers/Worker-location.any.worker.html",
+     "/workers/Worker-location.sub.any.worker.html",
      {}
     ]
    ],
@@ -355655,6 +355605,18 @@
    "e11e2955891f251409e8519abd48f10fb2dd89e9",
    "reftest"
   ],
+  "css/css-sizing/table-percentage-max-width-beside-float.html": [
+   "be82ac0da66fcfb4e327580b11b491e2621b0629",
+   "testharness"
+  ],
+  "css/css-sizing/table-percentage-min-width-below-float.html": [
+   "400a87dd175c88af215f191ac48453ff101e7794",
+   "testharness"
+  ],
+  "css/css-sizing/table-percentage-min-width-beside-float.html": [
+   "d763c927016bef8ffaffa7126b944ec60563d3f7",
+   "testharness"
+  ],
   "css/css-sizing/whitespace-and-break.html": [
    "f3ea3764478488b949433daccddf710cd0a91006",
    "reftest"
@@ -400139,10 +400101,6 @@
    "02e7b3cd8c00b70dfc14cde57a2e045e58153f77",
    "testharness"
   ],
-  "html/browsers/offline/application-cache-api/api_update.https-expected.txt": [
-   "4466e82c34eb9f5d4f252ac1af4e863ae2c8d1dd",
-   "support"
-  ],
   "html/browsers/offline/application-cache-api/api_update.https.html": [
    "0cb281fba5682e57de968ec77fba84e0212f7de1",
    "testharness"
@@ -400991,6 +400949,18 @@
    "5e99bb522f194e67b78bda958359f8ace011a59c",
    "testharness"
   ],
+  "html/browsers/windows/embedded-opener-a-form.html": [
+   "e1ec760b926670e610a96f02c935cf169563714a",
+   "testharness"
+  ],
+  "html/browsers/windows/embedded-opener-expected.txt": [
+   "16481744cb91f79d4589e364e539ef8d4128bc90",
+   "support"
+  ],
+  "html/browsers/windows/embedded-opener.html": [
+   "8e02664342f5493faa1f68e67804f2dd7f4d6491",
+   "testharness"
+  ],
   "html/browsers/windows/nested-browsing-contexts/contains.json": [
    "121284dca146c10e4d3b2c0a4f06c0fdf8b6d147",
    "support"
@@ -415896,7 +415866,7 @@
    "testharness"
   ],
   "html/syntax/serializing-html-fragments/serializing.html": [
-   "6645b5aabadec103694e5b79a47022229719f030",
+   "1bccbf560880d98287c57046e84a449b20c39d90",
    "testharness"
   ],
   "html/syntax/serializing-xml-fragments/OWNERS": [
@@ -418408,7 +418378,7 @@
    "support"
   ],
   "interfaces/html.idl": [
-   "46d0b852f095a65c0019a9f6dd518963b26a9ac6",
+   "0d6445e7f016b736966e621a414cbe9bc9219e99",
    "support"
   ],
   "interfaces/image-capture.idl": [
@@ -419032,7 +419002,7 @@
    "support"
   ],
   "lint.whitelist": [
-   "8c5a329357ded76e66c627859a178aab657602dd",
+   "765256d05cafd33777d181e42ddadb8aad424784",
    "support"
   ],
   "loading/preloader-css-import-no-quote.tentative.html": [
@@ -450739,34 +450709,18 @@
    "c8613cbd9b3a467a919d87d3244c4f508dce6317",
    "testharness"
   ],
-  "wasm/jsapi/global/constructor.any-expected.txt": [
-   "6408c87fe70195eb7c2906097d434ae38f3316d7",
-   "support"
-  ],
   "wasm/jsapi/global/constructor.any.js": [
    "237f99c8b298183a557c10778c70e1d359b9d6b6",
    "testharness"
   ],
-  "wasm/jsapi/global/constructor.any.worker-expected.txt": [
-   "6408c87fe70195eb7c2906097d434ae38f3316d7",
-   "support"
-  ],
   "wasm/jsapi/global/toString.any.js": [
    "ca025576c2b49604f053c83002f3a9cc8ef41a7b",
    "testharness"
   ],
-  "wasm/jsapi/global/value-get-set.any-expected.txt": [
-   "e1ffba45a5d1aabe557c5b799fe73bad6b0bdb7d",
-   "support"
-  ],
   "wasm/jsapi/global/value-get-set.any.js": [
    "6de62d5f58362bab593ae7eb453fa14c1424cf2c",
    "testharness"
   ],
-  "wasm/jsapi/global/value-get-set.any.worker-expected.txt": [
-   "e1ffba45a5d1aabe557c5b799fe73bad6b0bdb7d",
-   "support"
-  ],
   "wasm/jsapi/global/value-set.any-expected.txt": [
    "6410e1c2cd09f457636df2234940bf84bc245564",
    "support"
@@ -450779,18 +450733,10 @@
    "d4a84b254f76ea50284619967ab6dc98c99bfea2",
    "testharness"
   ],
-  "wasm/jsapi/idlharness.any-expected.txt": [
-   "d120c0a8f6dac128cc75921b4f4220210b4ccf74",
-   "support"
-  ],
   "wasm/jsapi/idlharness.any.js": [
    "25298d3dabfbbce7490fa040258f3e06cd94b582",
    "testharness"
   ],
-  "wasm/jsapi/idlharness.any.worker-expected.txt": [
-   "d120c0a8f6dac128cc75921b4f4220210b4ccf74",
-   "support"
-  ],
   "wasm/jsapi/instance/constructor-bad-imports.any.js": [
    "24c51c10dc5df9d52c06bfb0715e435b17f24f7a",
    "testharness"
@@ -450819,18 +450765,10 @@
    "cb720ceb7095b2fbdd40c6f7385770fee9195ab3",
    "support"
   ],
-  "wasm/jsapi/interface.any-expected.txt": [
-   "b1d0c2bb437b1819dbd9aa82f6f449d863d56472",
-   "support"
-  ],
   "wasm/jsapi/interface.any.js": [
    "98c4a1d781b7d77709a7f1df5adb3c756648fbd3",
    "testharness"
   ],
-  "wasm/jsapi/interface.any.worker-expected.txt": [
-   "b1d0c2bb437b1819dbd9aa82f6f449d863d56472",
-   "support"
-  ],
   "wasm/jsapi/memory/buffer.any.js": [
    "4788ffcf84ff8d88adbafbe416dd7d5b80ec89d1",
    "testharness"
@@ -450847,18 +450785,10 @@
    "f0e59835e2d54da3c4593b914189ce599c94f8c9",
    "support"
   ],
-  "wasm/jsapi/memory/grow.any-expected.txt": [
-   "1f0c1b046ff1f3c890a34f2039d7d27b8e4f1436",
-   "support"
-  ],
   "wasm/jsapi/memory/grow.any.js": [
    "1ccfb946756fef71b89672dfc86830c620a9e981",
    "testharness"
   ],
-  "wasm/jsapi/memory/grow.any.worker-expected.txt": [
-   "1f0c1b046ff1f3c890a34f2039d7d27b8e4f1436",
-   "support"
-  ],
   "wasm/jsapi/memory/toString.any.js": [
    "4e15d75ea20f1ebfeba5dc7c8a9a52c253dd01bf",
    "testharness"
@@ -450903,18 +450833,10 @@
    "c88972b4ebdcd760b2a441835c2c9eb31dabfea8",
    "support"
   ],
-  "wasm/jsapi/table/constructor.any-expected.txt": [
-   "db2b7482d2abc99a265efb9503e9ead667feeb1f",
-   "support"
-  ],
   "wasm/jsapi/table/constructor.any.js": [
    "99eee19fecd49e432c7f6774c0968218e6d931a3",
    "testharness"
   ],
-  "wasm/jsapi/table/constructor.any.worker-expected.txt": [
-   "db2b7482d2abc99a265efb9503e9ead667feeb1f",
-   "support"
-  ],
   "wasm/jsapi/table/get-set.any-expected.txt": [
    "c742d96f21593e43dce7ec35b02435728254ccbc",
    "support"
@@ -450927,18 +450849,10 @@
    "c742d96f21593e43dce7ec35b02435728254ccbc",
    "support"
   ],
-  "wasm/jsapi/table/grow.any-expected.txt": [
-   "522e84a58d4f2881cad28936f469c542ab967383",
-   "support"
-  ],
   "wasm/jsapi/table/grow.any.js": [
    "4978e3ca23d0261aaccf4aad97dd348da22a54d0",
    "testharness"
   ],
-  "wasm/jsapi/table/grow.any.worker-expected.txt": [
-   "522e84a58d4f2881cad28936f469c542ab967383",
-   "support"
-  ],
   "wasm/jsapi/table/length.any.js": [
    "b1bfa6cfd1f44fbdbf18769b3f3e8129310c7e0e",
    "testharness"
@@ -451155,18 +451069,10 @@
    "bd17ce2a68ff8a0b3c917d05d48de95e52cfc860",
    "support"
   ],
-  "wasm/webapi/idlharness.any-expected.txt": [
-   "c0d8c7a28dc8ecf87d414f379cb472a2e2e59161",
-   "support"
-  ],
   "wasm/webapi/idlharness.any.js": [
    "0c4669e6caa7b2b7a9c0a89f13cc11605a9067c4",
    "testharness"
   ],
-  "wasm/webapi/idlharness.any.worker-expected.txt": [
-   "c0d8c7a28dc8ecf87d414f379cb472a2e2e59161",
-   "support"
-  ],
   "wasm/webapi/instantiateStreaming-bad-imports.any.js": [
    "b1efba31e9192654f2790edf3c5c391bb812a9eb",
    "testharness"
@@ -459139,8 +459045,8 @@
    "73eabd55226d67b05fc3a86a9e57880b9a725e5b",
    "testharness"
   ],
-  "workers/Worker-location.any.js": [
-   "c2a4590b75a4a156cbb05eca7f69bf43a837c095",
+  "workers/Worker-location.sub.any.js": [
+   "2ef944553105767535f6e3119048091f959bfac8",
    "testharness"
   ],
   "workers/Worker-replace-global-constructor.any.js": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-max-width-beside-float.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-max-width-beside-float.html
new file mode 100644
index 0000000..be82ac0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-max-width-beside-float.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/#available">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/#percentage-sizing">
+<p>There should be a green square below, and no red.</p>
+<div id="container" style="width:100px; background:red;">
+  <div style="float:right; width:50px; height:100px; background:green;"></div>
+  <div style="display:table; max-width:50%; height:100px; background:green;" data-expected-width="50">
+    <div style="float:left; width:20px; height:10px;"></div>
+    <div style="float:left; width:20px; height:10px;"></div>
+    <div style="float:left; width:20px; height:10px;"></div>
+  </div>
+</div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+  checkLayout("#container");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-min-width-below-float.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-min-width-below-float.html
new file mode 100644
index 0000000..400a87dd1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-min-width-below-float.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/#available">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/#percentage-sizing">
+<p>There should be a blue square below.</p>
+<div id="container" style="width:100px;">
+  <div style="float:right; width:50px; height:10px;"></div>
+  <div style="display:table; width:10px; min-width:100%; height:100px; background:blue;" data-expected-width="100"></div>
+</div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+  checkLayout("#container");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-min-width-beside-float.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-min-width-beside-float.html
new file mode 100644
index 0000000..d763c92
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/table-percentage-min-width-beside-float.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/#available">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/#percentage-sizing">
+<p>There should be a green square below, and no red.</p>
+<div id="container" style="width:100px; background:red;">
+  <div style="float:right; width:50px; height:100px; background:green;"></div>
+  <div style="display:table; width:10px; min-width:50%; height:100px; background:green;" data-expected-width="50"></div>
+</div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+  checkLayout("#container");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html
index b9f81ee..4044e106 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html
@@ -48,17 +48,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may appear at line start if zh and loose');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may appear at line start if zh and loose');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html
index 7d2af70..01096b2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html
@@ -48,17 +48,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and normal');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and normal');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html
index 069212e..8460aaa 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html
@@ -48,17 +48,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and strict');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and strict');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html
index 70ebdc08..724f776 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html
@@ -42,17 +42,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may appear at line start if zh and loose');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may appear at line start if zh and loose');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html
index 8fd631e..e89c9b8b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html
@@ -42,17 +42,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may appear at line start if zh and normal');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may appear at line start if zh and normal');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html
index 91f2610..b9585d7 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html
@@ -42,17 +42,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and strict');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and strict');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html
index 4f16371..e768661 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html
@@ -43,17 +43,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may appear at line start if zh and loose');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may appear at line start if zh and loose');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html
index bb0df2e8f..a9409cf 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html
@@ -43,17 +43,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and normal');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and normal');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html
index 965d513..defdf22 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html
@@ -43,17 +43,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and strict');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and strict');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html
index 72c476cd..64f8219 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html
@@ -44,17 +44,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may appear at line start if zh and loose');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may appear at line start if zh and loose');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html
index 92ac2e02..a7f66ea2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html
@@ -44,17 +44,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and normal');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and normal');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html
index 22ac4ba..0b1ca2a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html
@@ -44,17 +44,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and strict');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and strict');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html
index 0e02805..04a0f4d6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html
@@ -48,17 +48,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may appear at line start if zh and loose');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may appear at line start if zh and loose');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html
index 490e4067..5a52cf8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html
@@ -48,17 +48,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and normal');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and normal');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html
index ec44c09..d85b74a54 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html
@@ -48,17 +48,26 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
+function spansNearEnough(counter) {
+  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
+           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
+}
+
 document.querySelector('body').innerHTML = out
-// hide successful tests
-for (i=0;i<lines.length;i++) {
-    if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none'
-    }
-// run the test framework
- for (i=0;i<lines.length;i++) {
-   test(function() {
-        assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft);
-        }, lines[i]+' may NOT appear at line start if zh and strict');
-   }
+setup({explicit_done: true});
+
+document.fonts.ready.then(validate);
+
+function validate() {
+  for (i=0;i<lines.length;i++) {
+    test(function() {
+      assert_true(spansNearEnough(i));
+    }, lines[i]+' may NOT appear at line start if zh and strict');
+    // Hide successful tests.
+    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+  }
+  done();
+}
 </script>
 <!--Notes:
 The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-a-form.html b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-a-form.html
new file mode 100644
index 0000000..e1ec760
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-a-form.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>opener and embedded documents; using a and form</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<iframe name=matchesastring></iframe>
+<a href=/common/blank.html target=matchesastring>&lt;a></a>
+<form action=/common/blank.html target=matchesastring><input type=submit value="<form>"></form>
+<script>
+async_test(t => {
+  const frame = document.querySelector("iframe");
+  let counter = 0;
+  frame.onload = t.step_func(() => {
+    // Firefox and Chrome/Safari load differently
+    if (frame.contentWindow.location.href === "about:blank") {
+      return;
+    }
+
+    // Test bits
+    assert_equals(frame.contentWindow.opener, null);
+    if (counter === 0) {
+      document.querySelector("input").click();
+    } else {
+      t.done();
+    }
+    counter++;
+  });
+  document.querySelector("a").click();
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-expected.txt b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-expected.txt
new file mode 100644
index 0000000..16481744
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL opener and embedded documents; using window.open() openerGet is not a function
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener.html b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener.html
new file mode 100644
index 0000000..8e02664
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>opener and embedded documents; using window.open()</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<iframe name=matchesastring></iframe>
+<script>
+async_test(t => {
+  const frame = document.querySelector("iframe");
+  frame.onload = t.step_func(() => {
+    // Firefox and Chrome/Safari load differently
+    if (frame.contentWindow.location.href === "about:blank") {
+      return;
+    }
+
+    // Test bits
+    assert_equals(frame.contentWindow.opener, window, "opener before setting it to null");
+
+    const openerDesc = Object.getOwnPropertyDescriptor(frame.contentWindow, "opener"),
+          openerGet = openerDesc.get;
+
+    assert_equals(openerGet(), window, "opener before setting it to null via directly invoking the getter");
+    frame.contentWindow.opener = null;
+    frame.contentWindow.opener = "immaterial";
+    assert_equals(openerGet(), null, "opener after setting it to null via directly invoking the getter");
+    assert_equals(frame.contentWindow.opener, "immaterial");
+
+    t.done();
+  });
+  window.open("/common/blank.html", "matchesastring");
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/html.idl b/third_party/blink/web_tests/external/wpt/interfaces/html.idl
index 46d0b85..0d6445e 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/html.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/html.idl
@@ -1096,8 +1096,8 @@
 
   RenderingContext? getContext(DOMString contextId, optional any options = null);
 
-  USVString toDataURL(optional DOMString type, optional any quality);
-  void toBlob(BlobCallback _callback, optional DOMString type, optional any quality);
+  USVString toDataURL(optional DOMString type = "image/png", optional any quality);
+  void toBlob(BlobCallback _callback, optional DOMString type = "image/png", optional any quality);
   OffscreenCanvas transferControlToOffscreen();
 };
 
@@ -1357,7 +1357,7 @@
 
 dictionary ImageEncodeOptions {
   DOMString type = "image/png";
-  unrestricted double quality = 1.0;
+  unrestricted double quality;
 };
 
 enum OffscreenRenderingContextId { "2d", "webgl", "webgl2" };
diff --git a/third_party/blink/web_tests/external/wpt/portals/portals-activate-no-browsing-context.html b/third_party/blink/web_tests/external/wpt/portals/portals-activate-no-browsing-context.html
new file mode 100644
index 0000000..9a822e92
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/portals/portals-activate-no-browsing-context.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async () => {
+  let activatePromise = document.createElement('portal').activate();
+  await activatePromise.then(() => assert_unreached(), e => {
+    assert_true(e instanceof DOMException);
+    assert_equals(e.name, 'InvalidStateError');
+  });
+}, "A portal with nothing in it cannot be activated");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings-expected.txt
index 3ce1fdd6..ce30e45 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings-expected.txt
@@ -5,8 +5,8 @@
 PASS sender.setParameters() with mismatch number of encodings should reject with InvalidModificationError
 PASS sender.setParameters() with encodings unset should reject with TypeError
 FAIL setParameters() with modified encoding.rid field should reject with InvalidModificationError assert_equals: expected (string) "foo" but got (undefined) undefined
-FAIL setParameters() with encoding.scaleResolutionDownBy field set to less than 1.0 should reject with RangeError assert_unreached: Should have rejected: undefined Reached unreachable code
-FAIL setParameters() with encoding.scaleResolutionDownBy field set to greater than 1.0 should succeed assert_approx_equals: expected a number but got a "undefined"
+PASS setParameters() with encoding.scaleResolutionDownBy field set to less than 1.0 should reject with RangeError
+PASS setParameters() with encoding.scaleResolutionDownBy field set to greater than 1.0 should succeed
 FAIL setParameters() with modified encoding.dtx should succeed with RTCRtpTransceiverInit assert_equals: expected (string) "enabled" but got (undefined) undefined
 FAIL setParameters() with modified encoding.dtx should succeed without RTCRtpTransceiverInit assert_equals: expected (string) "enabled" but got (undefined) undefined
 FAIL setParameters() with unset encoding.dtx should succeed with RTCRtpTransceiverInit assert_equals: expected (string) "enabled" but got (undefined) undefined
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings.html
index b8ae4e4c..23cb769 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpParameters-encodings.html
@@ -253,7 +253,7 @@
     const encoding = getFirstEncoding(param);
 
     encoding.scaleResolutionDownBy = 0.5;
-    return promise_rejects(t, 'RangeError',
+    return promise_rejects(t, new RangeError(),
       sender.setParameters(param));
   }, `setParameters() with encoding.scaleResolutionDownBy field set to less than 1.0 should reject with RangeError`);
 
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose-expected.txt
deleted file mode 100644
index f9139277..0000000
--- a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS 30FB  KATAKANA MIDDLE DOT may appear at line start if zh and loose
-PASS FF1A  FULLWIDTH COLON may appear at line start if zh and loose
-PASS FF1B  FULLWIDTH SEMICOLON may appear at line start if zh and loose
-PASS FF65  HALFWIDTH KATAKANA MIDDLE DOT may appear at line start if zh and loose
-PASS 203C  DOUBLE EXCLAMATION MARK may appear at line start if zh and loose
-FAIL 2047  DOUBLE QUESTION MARK may appear at line start if zh and loose assert_true: expected true got false
-FAIL 2048  QUESTION EXCLAMATION MARK may appear at line start if zh and loose assert_true: expected true got false
-PASS 2049  EXCLAMATION QUESTION MARK may appear at line start if zh and loose
-PASS FF01  FULLWIDTH EXCLAMATION MARK may appear at line start if zh and loose
-PASS FF1F  FULLWIDTH QUESTION MARK may appear at line start if zh and loose
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose-expected.txt
deleted file mode 100644
index 83049b0..0000000
--- a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS 00B0  DEGREE SIGN may appear at line start if zh and loose
-PASS 2030  PER MILLE SIGN may appear at line start if zh and loose
-PASS 2032  PRIME may appear at line start if zh and loose
-PASS 2033  DOUBLE PRIME may appear at line start if zh and loose
-PASS 2035  REVERSED PRIME may appear at line start if zh and loose
-FAIL 2103  DEGREE CELSIUS may appear at line start if zh and loose assert_true: expected true got false
-FAIL 2109  DEGREE FAHRENHEIT may appear at line start if zh and loose assert_true: expected true got false
-PASS FE6A  SMALL PERCENT SIGN may appear at line start if zh and loose
-PASS FF05  FULLWIDTH PERCENT SIGN may appear at line start if zh and loose
-PASS FFE0  FULLWIDTH CENT SIGN may appear at line start if zh and loose
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose-expected.txt
deleted file mode 100644
index 83049b0..0000000
--- a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS 00B0  DEGREE SIGN may appear at line start if zh and loose
-PASS 2030  PER MILLE SIGN may appear at line start if zh and loose
-PASS 2032  PRIME may appear at line start if zh and loose
-PASS 2033  DOUBLE PRIME may appear at line start if zh and loose
-PASS 2035  REVERSED PRIME may appear at line start if zh and loose
-FAIL 2103  DEGREE CELSIUS may appear at line start if zh and loose assert_true: expected true got false
-FAIL 2109  DEGREE FAHRENHEIT may appear at line start if zh and loose assert_true: expected true got false
-PASS FE6A  SMALL PERCENT SIGN may appear at line start if zh and loose
-PASS FF05  FULLWIDTH PERCENT SIGN may appear at line start if zh and loose
-PASS FFE0  FULLWIDTH CENT SIGN may appear at line start if zh and loose
-Harness: the test ran to completion.
-
diff --git a/tools/clang/scripts/download_strip.py b/tools/clang/scripts/download_strip.py
deleted file mode 100755
index 9daab0a..0000000
--- a/tools/clang/scripts/download_strip.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-"""Script to download llvm-strip from google storage."""
-
-import os
-import sys
-
-import update
-
-LLVM_BUILD_DIR = update.LLVM_BUILD_DIR
-STRIP_PATH = os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-strip')
-STAMP_FILE = os.path.normpath(
-    os.path.join(LLVM_BUILD_DIR, 'llvmstrip_build_revision'))
-
-
-def AlreadyUpToDate():
-  if not os.path.exists(STRIP_PATH):
-    return False
-  stamp = update.ReadStampFile(STAMP_FILE)
-  return stamp.rstrip() == update.PACKAGE_VERSION
-
-
-def main():
-  if not AlreadyUpToDate():
-    cds_file = 'llvmstrip-%s.tgz' % update.PACKAGE_VERSION
-    cds_full_url = update.GetPlatformUrlPrefix(sys.platform) + cds_file
-    update.DownloadAndUnpack(cds_full_url, update.LLVM_BUILD_DIR)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py
index 3671709..4ceb56e 100755
--- a/tools/clang/scripts/package.py
+++ b/tools/clang/scripts/package.py
@@ -494,26 +494,6 @@
               filter=PrintTarProgress)
     MaybeUpload(args, llddir, platform)
 
-  # On Linux and Mac, package and upload llvm-strip in a separate zip.
-  # This is used for the Fuchsia build.
-  if sys.platform == 'darwin' or sys.platform.startswith('linux'):
-    stripdir = 'llvmstrip-' + stamp
-    shutil.rmtree(stripdir, ignore_errors=True)
-    os.makedirs(os.path.join(stripdir, 'bin'))
-    shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'llvm-strip'),
-                os.path.join(stripdir, 'bin'))
-    llvmstrip_stamp_file_base = 'llvmstrip_build_revision'
-    llvmstrip_stamp_file = os.path.join(stripdir, llvmstrip_stamp_file_base)
-    with open(llvmstrip_stamp_file, 'w') as f:
-      f.write(expected_stamp)
-      f.write('\n')
-    with tarfile.open(stripdir + '.tgz', 'w:gz') as tar:
-      tar.add(os.path.join(stripdir, 'bin'), arcname='bin',
-              filter=PrintTarProgress)
-      tar.add(llvmstrip_stamp_file, arcname=llvmstrip_stamp_file_base,
-              filter=PrintTarProgress)
-    MaybeUpload(args, stripdir, platform)
-
   # Zip up the translation_unit tool.
   translation_unit_dir = 'translation_unit-' + stamp
   shutil.rmtree(translation_unit_dir, ignore_errors=True)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 609aed3..32390d5e 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -41320,6 +41320,12 @@
   <int value="6" label="%-) Neither filling nor user input">
     For example, it might be because of 3rd party password managers.
   </int>
+  <int value="7"
+      label=":-X Unknown password typed, no saved credentials existed and
+             site was explicitly blacklisted"/>
+  <int value="8"
+      label=":-X Unknown password typed, no saved credentials existed and
+             site is blacklisted by the smart bubble"/>
 </enum>
 
 <enum name="PasswordManagerFirstRendererFillingResult">
diff --git a/ui/display/mojo/display_constants_struct_traits.h b/ui/display/mojo/display_constants_struct_traits.h
index ca7d9c2..9ecf7cc 100644
--- a/ui/display/mojo/display_constants_struct_traits.h
+++ b/ui/display/mojo/display_constants_struct_traits.h
@@ -26,6 +26,6 @@
                         display::HDCPState* out);
 };
 
-};  // namespace mojo
+}  // namespace mojo
 
-#endif  // UI_DISPLAY_MOJO_DISPLAY_CONSTANTS_STRUCT_TRAITS_H_
\ No newline at end of file
+#endif  // UI_DISPLAY_MOJO_DISPLAY_CONSTANTS_STRUCT_TRAITS_H_
diff --git a/ui/display/screen_base.h b/ui/display/screen_base.h
index 04f548be..4cdec4e 100644
--- a/ui/display/screen_base.h
+++ b/ui/display/screen_base.h
@@ -20,8 +20,8 @@
   ScreenBase();
   ~ScreenBase() override;
 
-  DisplayList& display_list() { return display_list_; };
-  const DisplayList& display_list() const { return display_list_; };
+  DisplayList& display_list() { return display_list_; }
+  const DisplayList& display_list() const { return display_list_; }
 
   // Screen:
   gfx::Point GetCursorScreenPoint() override;
diff --git a/ui/events/gesture_detection/gesture_event_data_packet.cc b/ui/events/gesture_detection/gesture_event_data_packet.cc
index d5b1722..a72c089 100644
--- a/ui/events/gesture_detection/gesture_event_data_packet.cc
+++ b/ui/events/gesture_detection/gesture_event_data_packet.cc
@@ -33,7 +33,7 @@
     case ui::MotionEvent::Action::BUTTON_RELEASE:
       NOTREACHED();
       return GestureEventDataPacket::INVALID;
-  };
+  }
   NOTREACHED();
   return GestureEventDataPacket::INVALID;
 }
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc
index e09989e..b5c1b74f 100644
--- a/ui/gfx/color_transform.cc
+++ b/ui/gfx/color_transform.cc
@@ -271,8 +271,8 @@
                          Intent intent);
   ~ColorTransformInternal() override;
 
-  gfx::ColorSpace GetSrcColorSpace() const override { return src_; };
-  gfx::ColorSpace GetDstColorSpace() const override { return dst_; };
+  gfx::ColorSpace GetSrcColorSpace() const override { return src_; }
+  gfx::ColorSpace GetDstColorSpace() const override { return dst_; }
 
   void Transform(TriStim* colors, size_t num) const override {
     for (const auto& step : steps_) {
diff --git a/ui/gfx/decorated_text.h b/ui/gfx/decorated_text.h
index 4904871..d161152 100644
--- a/ui/gfx/decorated_text.h
+++ b/ui/gfx/decorated_text.h
@@ -40,6 +40,6 @@
   std::vector<RangedAttribute> attributes;
 };
 
-};  // namespace gfx
+}  // namespace gfx
 
 #endif  // UI_GFX_DECORATED_TEXT_H_
diff --git a/ui/gfx/half_float.cc b/ui/gfx/half_float.cc
index 930d0cac..a7c6696 100644
--- a/ui/gfx/half_float.cc
+++ b/ui/gfx/half_float.cc
@@ -13,4 +13,5 @@
     output[i] = (tmp2 & 0x80000000UL) >> 16 | (tmp2 >> 13);
   }
 }
-};
+
+}  // namespace gfx
diff --git a/ui/gfx/half_float.h b/ui/gfx/half_float.h
index 788607f..f0492d6 100644
--- a/ui/gfx/half_float.h
+++ b/ui/gfx/half_float.h
@@ -18,5 +18,6 @@
 GFX_EXPORT void FloatToHalfFloat(const float* input,
                                  HalfFloat* output,
                                  size_t num);
-};
+}  // namespace gfx
+
 #endif
diff --git a/ui/gfx/image/canvas_image_source.h b/ui/gfx/image/canvas_image_source.h
index 20e13ac..bde35a0 100644
--- a/ui/gfx/image/canvas_image_source.h
+++ b/ui/gfx/image/canvas_image_source.h
@@ -45,7 +45,7 @@
   virtual void Draw(Canvas* canvas) = 0;
 
   // Returns the size of images in DIP that this source will generate.
-  const Size& size() const { return size_; };
+  const Size& size() const { return size_; }
 
   // Overridden from ImageSkiaSource.
   ImageSkiaRep GetImageForScale(float scale) override;
diff --git a/ui/gfx/image/image_skia_rep_default.h b/ui/gfx/image/image_skia_rep_default.h
index 79705fb..28064f4 100644
--- a/ui/gfx/image/image_skia_rep_default.h
+++ b/ui/gfx/image/image_skia_rep_default.h
@@ -73,7 +73,7 @@
   // ImageRep is |kImageTypeDrawable|.
   sk_sp<cc::PaintRecord> GetPaintRecord() const;
 
-  const cc::PaintImage& paint_image() const { return paint_image_; };
+  const cc::PaintImage& paint_image() const { return paint_image_; }
   bool has_paint_image() const { return !!paint_image_; }
 
  private:
diff --git a/ui/gfx/rrect_f.cc b/ui/gfx/rrect_f.cc
index 8e7e825..d8bb08e 100644
--- a/ui/gfx/rrect_f.cc
+++ b/ui/gfx/rrect_f.cc
@@ -62,7 +62,7 @@
     case SkRRect::kComplex_Type:
     default:
       return Type::kComplex;
-  };
+  }
 }
 
 gfx::Vector2dF RRectF::GetCornerRadii(Corner corner) const {