diff --git a/DEPS b/DEPS
index 4b0380f..03b99b0 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # 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': 'dcf65ba2f663c9efb8e1ce25e2a28129c8508f1b',
+  'v8_revision': 'a8a39548a410205fe49dbd5daca8cc601ade2d16',
   # 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.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '4db9046e56c884a350fa2c5087f8d5b8110463c4',
+  'pdfium_revision': '3962d80bde19074227c34f4615b0446f4975a098',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -235,7 +235,7 @@
     Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'f91805c46d7a5067e3b4ce2bd066ca504dc167f3', # commit position 18617
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'e6fddec2d5f2b9883f3d678c9e5623a8e1c6e28b', # commit position 18665
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -860,18 +860,6 @@
     ],
   },
   {
-    "name": "wasm_asmjs_fuzzer",
-    "pattern": ".",
-    'action': [ 'python',
-                'src/third_party/depot_tools/download_from_google_storage.py',
-                "--no_resume",
-                "--no_auth",
-                "-u",
-                "--bucket", "v8-wasm-asmjs-fuzzer",
-                "-s", "src/v8/test/fuzzer/wasm_asmjs_corpus.tar.gz.sha1",
-    ],
-  },
-  {
     'name': 'devtools_install_node',
     'action': [ 'python',
                 'src/third_party/WebKit/Source/devtools/scripts/local_node/node.py',
diff --git a/ash/ime/ime_controller.cc b/ash/ime/ime_controller.cc
index 03c820f..35d2e91 100644
--- a/ash/ime/ime_controller.cc
+++ b/ash/ime/ime_controller.cc
@@ -13,13 +13,54 @@
 
 ImeController::~ImeController() = default;
 
-void ImeController::RefreshIme(
-    const mojom::ImeInfo& current_ime,
-    const std::vector<mojom::ImeInfo>& available_imes,
-    const std::vector<mojom::ImeMenuItem>& menu_items) {
-  current_ime_ = current_ime;
-  available_imes_ = available_imes;
-  current_ime_menu_items_ = menu_items;
+void ImeController::BindRequest(mojom::ImeControllerRequest request) {
+  bindings_.AddBinding(this, std::move(request));
+}
+
+void ImeController::SetClient(mojom::ImeControllerClientPtr client) {
+  client_ = std::move(client);
+}
+
+bool ImeController::CanSwitchIme() const {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+void ImeController::SwitchToNextIme() {
+  NOTIMPLEMENTED();
+}
+
+void ImeController::SwitchToPreviousIme() {
+  NOTIMPLEMENTED();
+}
+
+bool ImeController::CanSwitchImeWithAccelerator(
+    const ui::Accelerator& accelerator) const {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+void ImeController::SwitchImeWithAccelerator(
+    const ui::Accelerator& accelerator) {
+  NOTIMPLEMENTED();
+}
+
+// mojom::ImeController:
+void ImeController::RefreshIme(mojom::ImeInfoPtr current_ime,
+                               std::vector<mojom::ImeInfoPtr> available_imes,
+                               std::vector<mojom::ImeMenuItemPtr> menu_items) {
+  current_ime_ = *current_ime;
+
+  available_imes_.clear();
+  available_imes_.reserve(available_imes.size());
+  for (const auto& ime : available_imes)
+    available_imes_.push_back(*ime);
+
+  current_ime_menu_items_.clear();
+  current_ime_menu_items_.reserve(menu_items.size());
+  for (const auto& item : menu_items)
+    current_ime_menu_items_.push_back(*item);
+
   Shell::Get()->system_tray_notifier()->NotifyRefreshIME();
 }
 
diff --git a/ash/ime/ime_controller.h b/ash/ime/ime_controller.h
index 96183636..744a543e 100644
--- a/ash/ime/ime_controller.h
+++ b/ash/ime/ime_controller.h
@@ -8,18 +8,24 @@
 #include <vector>
 
 #include "ash/ash_export.h"
+#include "ash/public/interfaces/ime_controller.mojom.h"
 #include "ash/public/interfaces/ime_info.mojom.h"
 #include "base/macros.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+
+namespace ui {
+class Accelerator;
+}
 
 namespace ash {
 
 // Connects ash IME users (e.g. the system tray) to the IME implementation,
 // which might live in Chrome browser or in a separate mojo service.
-// TODO(jamescook): Convert to use mojo IME interface to Chrome browser.
-class ASH_EXPORT ImeController {
+class ASH_EXPORT ImeController
+    : public NON_EXPORTED_BASE(mojom::ImeController) {
  public:
   ImeController();
-  ~ImeController();
+  ~ImeController() override;
 
   const mojom::ImeInfo& current_ime() const { return current_ime_; }
 
@@ -33,18 +39,31 @@
     return current_ime_menu_items_;
   }
 
-  // Updates the cached IME information and refreshes the UI.
-  // TODO(jamescook): This should take an ID for current_ime.
-  void RefreshIme(const mojom::ImeInfo& current_ime,
-                  const std::vector<mojom::ImeInfo>& available_imes,
-                  const std::vector<mojom::ImeMenuItem>& menu_items);
+  // Binds the mojo interface to this object.
+  void BindRequest(mojom::ImeControllerRequest request);
 
-  void SetImesManagedByPolicy(bool managed);
+  // TODO(jamescook): Implement these. http://crbug.com/724305
+  bool CanSwitchIme() const;
+  void SwitchToNextIme();
+  void SwitchToPreviousIme();
+  bool CanSwitchImeWithAccelerator(const ui::Accelerator& accelerator) const;
+  void SwitchImeWithAccelerator(const ui::Accelerator& accelerator);
 
-  // Shows the IME menu on the shelf instead of inside the system tray menu.
-  void ShowImeMenuOnShelf(bool show);
+  // mojom::ImeController:
+  void SetClient(mojom::ImeControllerClientPtr client) override;
+  void RefreshIme(mojom::ImeInfoPtr current_ime,
+                  std::vector<mojom::ImeInfoPtr> available_imes,
+                  std::vector<mojom::ImeMenuItemPtr> menu_items) override;
+  void SetImesManagedByPolicy(bool managed) override;
+  void ShowImeMenuOnShelf(bool show) override;
 
  private:
+  // Bindings for users of the mojo interface.
+  mojo::BindingSet<mojom::ImeController> bindings_;
+
+  // Client interface back to IME code in chrome.
+  mojom::ImeControllerClientPtr client_;
+
   mojom::ImeInfo current_ime_;
 
   // "Available" IMEs are both installed and enabled by the user in settings.
diff --git a/ash/ime/ime_controller_unittest.cc b/ash/ime/ime_controller_unittest.cc
index e235e6a4..19ef8af0 100644
--- a/ash/ime/ime_controller_unittest.cc
+++ b/ash/ime/ime_controller_unittest.cc
@@ -21,7 +21,7 @@
   ~TestImeObserver() override = default;
 
   // IMEObserver:
-  void OnIMERefresh() override { refresh_count_++; }
+  void OnIMERefresh() override { ++refresh_count_; }
   void OnIMEMenuActivationChanged(bool is_active) override {
     ime_menu_active_ = is_active;
   }
@@ -37,15 +37,23 @@
   TestImeObserver observer;
   Shell::Get()->system_tray_notifier()->AddIMEObserver(&observer);
 
-  mojom::ImeInfo ime1;
-  ime1.id = "ime1";
-  mojom::ImeInfo ime2;
-  ime2.id = "ime2";
+  mojom::ImeInfoPtr ime1 = mojom::ImeInfo::New();
+  ime1->id = "ime1";
+  mojom::ImeInfoPtr ime2 = mojom::ImeInfo::New();
+  ime2->id = "ime2";
 
-  mojom::ImeMenuItem item1;
-  item1.key = "key1";
+  std::vector<mojom::ImeInfoPtr> available_imes;
+  available_imes.push_back(ime1.Clone());
+  available_imes.push_back(ime2.Clone());
 
-  controller->RefreshIme(ime1, {ime1, ime2}, {item1});
+  mojom::ImeMenuItemPtr item1 = mojom::ImeMenuItem::New();
+  item1->key = "key1";
+
+  std::vector<mojom::ImeMenuItemPtr> menu_items;
+  menu_items.push_back(item1.Clone());
+
+  controller->RefreshIme(std::move(ime1), std::move(available_imes),
+                         std::move(menu_items));
 
   // Cached data was updated.
   EXPECT_EQ("ime1", controller->current_ime().id);
diff --git a/ash/mojo_interface_factory.cc b/ash/mojo_interface_factory.cc
index b11a3f8..d7bd8295 100644
--- a/ash/mojo_interface_factory.cc
+++ b/ash/mojo_interface_factory.cc
@@ -9,6 +9,7 @@
 #include "ash/accelerators/accelerator_controller.h"
 #include "ash/cast_config_controller.h"
 #include "ash/display/ash_display_controller.h"
+#include "ash/ime/ime_controller.h"
 #include "ash/login/lock_screen_controller.h"
 #include "ash/media_controller.h"
 #include "ash/new_window_controller.h"
@@ -57,6 +58,12 @@
   Shell::Get()->cast_config()->BindRequest(std::move(request));
 }
 
+void BindImeControllerRequestOnMainThread(
+    const service_manager::BindSourceInfo& source_info,
+    mojom::ImeControllerRequest request) {
+  Shell::Get()->ime_controller()->BindRequest(std::move(request));
+}
+
 void BindLocaleNotificationControllerOnMainThread(
     const service_manager::BindSourceInfo& source_info,
     mojom::LocaleNotificationControllerRequest request) {
@@ -148,6 +155,8 @@
       main_thread_task_runner);
   registry->AddInterface(base::Bind(&BindAppListRequestOnMainThread),
                          main_thread_task_runner);
+  registry->AddInterface(base::Bind(&BindImeControllerRequestOnMainThread),
+                         main_thread_task_runner);
   registry->AddInterface(
       base::Bind(&BindAshDisplayControllerRequestOnMainThread),
       main_thread_task_runner);
diff --git a/ash/mus/manifest.json b/ash/mus/manifest.json
index 32e927d5..d05c528 100644
--- a/ash/mus/manifest.json
+++ b/ash/mus/manifest.json
@@ -10,6 +10,7 @@
           "app_list::mojom::AppList",
           "ash::mojom::AcceleratorController",
           "ash::mojom::CastConfig",
+          "ash::mojom::ImeController",
           "ash::mojom::LocaleNotificationController",
           "ash::mojom::LockScreen",
           "ash::mojom::MediaController",
diff --git a/ash/mus/standalone/manifest.json b/ash/mus/standalone/manifest.json
index 04ba7fe..89d5106 100644
--- a/ash/mus/standalone/manifest.json
+++ b/ash/mus/standalone/manifest.json
@@ -8,6 +8,7 @@
           "app_list::mojom::AppList",
           "ash::mojom::AcceleratorController",
           "ash::mojom::CastConfig",
+          "ash::mojom::ImeController",
           "ash::mojom::LocaleNotificationController",
           "ash::mojom::MediaController",
           "ash::mojom::NewWindowController",
diff --git a/ash/public/interfaces/BUILD.gn b/ash/public/interfaces/BUILD.gn
index 623b242..1d8da270 100644
--- a/ash/public/interfaces/BUILD.gn
+++ b/ash/public/interfaces/BUILD.gn
@@ -17,6 +17,7 @@
     "cast_config.mojom",
     "constants.mojom",
     "event_properties.mojom",
+    "ime_controller.mojom",
     "ime_info.mojom",
     "locale.mojom",
     "lock_screen.mojom",
diff --git a/ash/public/interfaces/ime_controller.mojom b/ash/public/interfaces/ime_controller.mojom
new file mode 100644
index 0000000..65dd3b9
--- /dev/null
+++ b/ash/public/interfaces/ime_controller.mojom
@@ -0,0 +1,50 @@
+// 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.
+
+module ash.mojom;
+
+import "ash/public/interfaces/ime_info.mojom";
+
+// Interface for ash client (e.g. Chrome) to send input method info to ash.
+interface ImeController {
+  // Sets the client interface.
+  SetClient(ImeControllerClient client);
+
+  // Updates the cached IME information and refreshes the IME menus.
+  // |current_ime| has an empty ID when there is no active IME yet.
+  // TODO(jamescook): Convert |current_ime| to an ID instead of an IMEInfo.
+  RefreshIme(ImeInfo current_ime,
+             array<ImeInfo> available_imes,
+             array<ImeMenuItem> menu_items);
+
+  // Shows an icon in the IME menu indicating that IMEs are controlled by device
+  // policy.
+  SetImesManagedByPolicy(bool managed);
+
+  // Shows the IME menu on the shelf instead of inside the system tray menu.
+  // Users with multiple IMEs that have multiple configurable properties (e.g.
+  // some Chinese IMEs) prefer this to keeping the IME menu under the primary
+  // system tray menu.
+  ShowImeMenuOnShelf(bool show);
+};
+
+// Interface for ash to send input method requests to its client (e.g. Chrome).
+interface ImeControllerClient {
+  // Switches to the next input method. Does nothing if only one input method
+  // is installed.
+  SwitchToNextIme();
+
+  // Switches to the previous input method. Does nothing if only one input
+  // method is installed.
+  SwitchToPreviousIme();
+
+  // Switches to an input method by |id| (for example, "xkb:jp::jpn"). Does
+  // nothing if the input method is not installed.
+  SwitchImeById(string id);
+
+  // Activates an input method property. These are settings that are provided by
+  // IME extensions that appear in the IME menu. Does nothing if the |key| does
+  // not exist.
+  ActivateImeProperty(string key);
+};
diff --git a/ash/public/interfaces/ime_info.mojom b/ash/public/interfaces/ime_info.mojom
index b471e4e..3d8ca018 100644
--- a/ash/public/interfaces/ime_info.mojom
+++ b/ash/public/interfaces/ime_info.mojom
@@ -9,6 +9,7 @@
 // Metadata about an installed input method.
 struct ImeInfo {
   // True if the IME is the current IME.
+  // TODO(jamescook): Remove this and use ImeController::current_ime().
   bool selected;
 
   // True if the IME is a third-party extension.
diff --git a/ash/system/ime/tray_ime_chromeos_unittest.cc b/ash/system/ime/tray_ime_chromeos_unittest.cc
index 4496c08..ffc570c 100644
--- a/ash/system/ime/tray_ime_chromeos_unittest.cc
+++ b/ash/system/ime/tray_ime_chromeos_unittest.cc
@@ -55,6 +55,9 @@
   void TearDown() override;
 
  private:
+  // Updates the ImeController with the latest IME test data.
+  void RefreshImeController();
+
   std::unique_ptr<TrayIME> tray_;
   std::unique_ptr<views::View> default_view_;
   std::unique_ptr<views::View> detailed_view_;
@@ -81,8 +84,7 @@
 
 void TrayIMETest::SetActiveImeCount(int count) {
   available_imes_.resize(count);
-  Shell::Get()->ime_controller()->RefreshIme(current_ime_, available_imes_,
-                                             menu_items_);
+  RefreshImeController();
 }
 
 views::View* TrayIMETest::GetToggleView() const {
@@ -101,8 +103,7 @@
 void TrayIMETest::SetCurrentImeMenuItems(
     const std::vector<mojom::ImeMenuItem>& items) {
   menu_items_ = items;
-  Shell::Get()->ime_controller()->RefreshIme(current_ime_, available_imes_,
-                                             menu_items_);
+  RefreshImeController();
 }
 
 void TrayIMETest::SuppressKeyboard() {
@@ -142,6 +143,22 @@
   detailed_view_.reset(tray_->CreateDetailedView(LoginStatus::USER));
 }
 
+void TrayIMETest::RefreshImeController() {
+  mojom::ImeInfoPtr current_ime_ptr = current_ime_.Clone();
+
+  std::vector<mojom::ImeInfoPtr> available_ime_ptrs;
+  for (const auto& ime : available_imes_)
+    available_ime_ptrs.push_back(ime.Clone());
+
+  std::vector<mojom::ImeMenuItemPtr> menu_item_ptrs;
+  for (const auto& item : menu_items_)
+    menu_item_ptrs.push_back(item.Clone());
+
+  Shell::Get()->ime_controller()->RefreshIme(std::move(current_ime_ptr),
+                                             std::move(available_ime_ptrs),
+                                             std::move(menu_item_ptrs));
+}
+
 void TrayIMETest::TearDown() {
   if (keyboard_suppressed_)
     RestoreKeyboard();
diff --git a/ash/system/ime_menu/ime_menu_tray_unittest.cc b/ash/system/ime_menu/ime_menu_tray_unittest.cc
index 7602ac3..818e629 100644
--- a/ash/system/ime_menu/ime_menu_tray_unittest.cc
+++ b/ash/system/ime_menu/ime_menu_tray_unittest.cc
@@ -34,8 +34,13 @@
 
 void SetCurrentIme(mojom::ImeInfo current_ime,
                    const std::vector<mojom::ImeInfo>& available_imes) {
-  Shell::Get()->ime_controller()->RefreshIme(current_ime, available_imes,
-                                             std::vector<mojom::ImeMenuItem>());
+  mojom::ImeInfoPtr current_ime_ptr = current_ime.Clone();
+  std::vector<mojom::ImeInfoPtr> available_ime_ptrs;
+  for (const auto& ime : available_imes)
+    available_ime_ptrs.push_back(ime.Clone());
+  Shell::Get()->ime_controller()->RefreshIme(
+      std::move(current_ime_ptr), std::move(available_ime_ptrs),
+      std::vector<mojom::ImeMenuItemPtr>());
 }
 
 }  // namespace
diff --git a/base/task_scheduler/lazy_task_runner.h b/base/task_scheduler/lazy_task_runner.h
index f5e74639..eecdb126 100644
--- a/base/task_scheduler/lazy_task_runner.h
+++ b/base/task_scheduler/lazy_task_runner.h
@@ -105,7 +105,7 @@
   ALLOW_UNUSED_TYPE constexpr base::TaskTraits                            \
       LAZY_TASK_RUNNER_CONCATENATE_INTERNAL(kVerifyTraitsAreConstexpr,    \
                                             __LINE__) = traits;           \
-  ALLOW_UNUSED_TYPE constexpr SingleThreadTaskRunnerThreadMode            \
+  ALLOW_UNUSED_TYPE constexpr base::SingleThreadTaskRunnerThreadMode      \
       LAZY_TASK_RUNNER_CONCATENATE_INTERNAL(kVerifyThreadModeIsConstexpr, \
                                             __LINE__) = thread_mode
 
@@ -118,7 +118,7 @@
   ALLOW_UNUSED_TYPE constexpr base::TaskTraits                            \
       LAZY_TASK_RUNNER_CONCATENATE_INTERNAL(kVerifyTraitsAreConstexpr,    \
                                             __LINE__) = traits;           \
-  ALLOW_UNUSED_TYPE constexpr SingleThreadTaskRunnerThreadMode            \
+  ALLOW_UNUSED_TYPE constexpr base::SingleThreadTaskRunnerThreadMode      \
       LAZY_TASK_RUNNER_CONCATENATE_INTERNAL(kVerifyThreadModeIsConstexpr, \
                                             __LINE__) = thread_mode
 
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc
index 128cc4b4..d2c51d18 100644
--- a/cc/blink/web_layer_impl.cc
+++ b/cc/blink/web_layer_impl.cc
@@ -132,6 +132,14 @@
   return layer_->is_root_for_isolated_group();
 }
 
+void WebLayerImpl::SetShouldHitTest(bool should_hit_test) {
+  layer_->SetShouldHitTest(should_hit_test);
+}
+
+bool WebLayerImpl::ShouldHitTest() {
+  return layer_->should_hit_test();
+}
+
 void WebLayerImpl::SetOpaque(bool opaque) {
   if (contents_opaque_is_fixed_)
     return;
diff --git a/cc/blink/web_layer_impl.h b/cc/blink/web_layer_impl.h
index 2cb948e..f85b1d9 100644
--- a/cc/blink/web_layer_impl.h
+++ b/cc/blink/web_layer_impl.h
@@ -69,6 +69,8 @@
   blink::WebBlendMode BlendMode() const override;
   void SetIsRootForIsolatedGroup(bool root) override;
   bool IsRootForIsolatedGroup() override;
+  void SetShouldHitTest(bool should_hit_test) override;
+  bool ShouldHitTest() override;
   void SetOpaque(bool opaque) override;
   bool Opaque() const override;
   void SetPosition(const blink::WebFloatPoint& position) override;
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index c17e76d..4740816bb 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -46,6 +46,7 @@
       opacity(1.f),
       blend_mode(SkBlendMode::kSrcOver),
       is_root_for_isolated_group(false),
+      should_hit_test(false),
       contents_opaque(false),
       is_drawable(false),
       double_sided(true),
@@ -572,6 +573,15 @@
   SetNeedsCommit();
 }
 
+void Layer::SetShouldHitTest(bool should_hit_test) {
+  DCHECK(IsPropertyChangeAllowed());
+  if (inputs_.should_hit_test == should_hit_test)
+    return;
+  inputs_.should_hit_test = should_hit_test;
+  SetPropertyTreesNeedRebuild();
+  SetNeedsCommit();
+}
+
 void Layer::SetContentsOpaque(bool opaque) {
   DCHECK(IsPropertyChangeAllowed());
   if (inputs_.contents_opaque == opaque)
@@ -1154,6 +1164,7 @@
   layer->SetScrollTreeIndex(scroll_tree_index());
   layer->set_offset_to_transform_parent(offset_to_transform_parent_);
   layer->SetDrawsContent(DrawsContent());
+  layer->SetShouldHitTest(should_hit_test());
   // subtree_property_changed_ is propagated to all descendants while building
   // property trees. So, it is enough to check it only for the current layer.
   if (subtree_property_changed_)
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index e77765e..bbf9c0bbb 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -141,6 +141,9 @@
     return inputs_.is_root_for_isolated_group;
   }
 
+  void SetShouldHitTest(bool should_hit_test);
+  bool should_hit_test() const { return inputs_.should_hit_test; }
+
   void SetFilters(const FilterOperations& filters);
   const FilterOperations& filters() const { return inputs_.filters; }
 
@@ -542,6 +545,8 @@
 
     bool is_root_for_isolated_group : 1;
 
+    bool should_hit_test : 1;
+
     bool contents_opaque : 1;
 
     gfx::PointF position;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index ede6881a..e30b44d 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -65,6 +65,7 @@
       should_check_backface_visibility_(false),
       draws_content_(false),
       contributes_to_drawn_render_surface_(false),
+      should_hit_test_(false),
       viewport_layer_type_(NOT_VIEWPORT_LAYER),
       background_color_(0),
       safe_opaque_background_color_(0),
@@ -323,6 +324,7 @@
   layer->use_parent_backface_visibility_ = use_parent_backface_visibility_;
   layer->should_check_backface_visibility_ = should_check_backface_visibility_;
   layer->draws_content_ = draws_content_;
+  layer->should_hit_test_ = should_hit_test_;
   layer->non_fast_scrollable_region_ = non_fast_scrollable_region_;
   layer->touch_action_region_ = touch_action_region_;
   layer->background_color_ = background_color_;
@@ -579,6 +581,16 @@
     return;
 
   draws_content_ = draws_content;
+  if (draws_content)
+    SetShouldHitTest(true);
+  NoteLayerPropertyChanged();
+}
+
+void LayerImpl::SetShouldHitTest(bool should_hit_test) {
+  if (should_hit_test_ == should_hit_test)
+    return;
+
+  should_hit_test_ = should_hit_test;
   NoteLayerPropertyChanged();
 }
 
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 9c2e758..c8e2610 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -160,6 +160,9 @@
   void SetDrawsContent(bool draws_content);
   bool DrawsContent() const { return draws_content_; }
 
+  void SetShouldHitTest(bool should_hit_test);
+  bool should_hit_test() const { return should_hit_test_; }
+
   LayerImplTestProperties* test_properties() {
     if (!test_properties_)
       test_properties_.reset(new LayerImplTestProperties(this));
@@ -494,6 +497,7 @@
   bool should_check_backface_visibility_ : 1;
   bool draws_content_ : 1;
   bool contributes_to_drawn_render_surface_ : 1;
+  bool should_hit_test_ : 1;
 
   static_assert(LAST_VIEWPORT_LAYER_TYPE < (1u << 3),
                 "enough bits for ViewportLayerType (viewport_layer_type_)");
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 3adf653..28c61eb6 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -403,6 +403,85 @@
     return scroll_layer;
   }
 
+  void CreateAndTestNonScrollableLayers(const bool& transparent_layer) {
+    LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
+    gfx::Size content_size = gfx::Size(360, 600);
+    gfx::Size scroll_content_size = gfx::Size(345, 3800);
+    gfx::Size scrollbar_size = gfx::Size(15, 600);
+
+    host_impl_->SetViewportSize(content_size);
+    std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
+    root->SetBounds(content_size);
+    root->SetPosition(gfx::PointF());
+
+    std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2);
+    clip->SetBounds(content_size);
+    clip->SetPosition(gfx::PointF());
+
+    std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
+    scroll->SetBounds(scroll_content_size);
+    scroll->SetScrollClipLayer(clip->id());
+    scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
+    scroll->SetDrawsContent(true);
+
+    std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
+        SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10,
+                                             0, false, true);
+    scrollbar->SetBounds(scrollbar_size);
+    scrollbar->SetPosition(gfx::PointF(345, 0));
+    scrollbar->SetScrollElementId(scroll->element_id());
+    scrollbar->SetDrawsContent(true);
+    scrollbar->test_properties()->opacity = 1.f;
+
+    std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5);
+    squash1->SetBounds(gfx::Size(140, 300));
+    squash1->SetPosition(gfx::PointF(220, 0));
+    if (transparent_layer) {
+      // In the it is a transparent layer but should still participate
+      // in hit testing.
+      squash1->test_properties()->opacity = 0.0f;
+      squash1->SetShouldHitTest(true);
+    } else {
+      squash1->SetDrawsContent(true);
+    }
+
+    std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6);
+    squash2->SetBounds(gfx::Size(140, 300));
+    squash2->SetPosition(gfx::PointF(220, 300));
+    squash2->SetDrawsContent(true);
+
+    scroll->test_properties()->AddChild(std::move(squash2));
+    clip->test_properties()->AddChild(std::move(scroll));
+    clip->test_properties()->AddChild(std::move(scrollbar));
+    clip->test_properties()->AddChild(std::move(squash1));
+    root->test_properties()->AddChild(std::move(clip));
+
+    layer_tree_impl->SetRootLayerForTesting(std::move(root));
+    layer_tree_impl->BuildPropertyTreesForTesting();
+    layer_tree_impl->DidBecomeActive();
+
+    // The point hits squash1 layer and also scroll layer, because scroll layer
+    // is not an ancestor of squash1 layer, we cannot scroll on impl thread.
+    InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
+        BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL);
+    ASSERT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
+    ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest,
+              status.main_thread_scrolling_reasons);
+
+    // The point hits squash1 layer and also scrollbar layer.
+    status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(),
+                                     InputHandler::WHEEL);
+    ASSERT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
+    ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest,
+              status.main_thread_scrolling_reasons);
+
+    // The point hits squash2 layer and also scroll layer, because scroll layer
+    // is an ancestor of squash2 layer, we should scroll on impl.
+    status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(),
+                                     InputHandler::WHEEL);
+    ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
+  }
+
   // Sets up a typical virtual viewport setup with one child content layer.
   // Returns a pointer to the content layer.
   LayerImpl* CreateBasicVirtualViewportLayers(const gfx::Size& viewport_size,
@@ -1099,75 +1178,12 @@
 }
 
 TEST_F(LayerTreeHostImplTest, ScrollWithOverlappingNonScrollableLayer) {
-  LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
-  gfx::Size content_size = gfx::Size(360, 600);
-  gfx::Size scroll_content_size = gfx::Size(345, 3800);
-  gfx::Size scrollbar_size = gfx::Size(15, 600);
+  CreateAndTestNonScrollableLayers(false);
+}
 
-  host_impl_->SetViewportSize(content_size);
-  std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
-  root->SetBounds(content_size);
-  root->SetPosition(gfx::PointF());
-
-  std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2);
-  clip->SetBounds(content_size);
-  clip->SetPosition(gfx::PointF());
-
-  std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
-  scroll->SetBounds(scroll_content_size);
-  scroll->SetScrollClipLayer(clip->id());
-  scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
-  scroll->SetDrawsContent(true);
-
-  std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
-      SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, 0,
-                                           false, true);
-  scrollbar->SetBounds(scrollbar_size);
-  scrollbar->SetPosition(gfx::PointF(345, 0));
-  scrollbar->SetScrollElementId(scroll->element_id());
-  scrollbar->SetDrawsContent(true);
-  scrollbar->test_properties()->opacity = 1.f;
-
-  std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5);
-  squash1->SetBounds(gfx::Size(140, 300));
-  squash1->SetPosition(gfx::PointF(220, 0));
-  squash1->SetDrawsContent(true);
-
-  std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6);
-  squash2->SetBounds(gfx::Size(140, 300));
-  squash2->SetPosition(gfx::PointF(220, 300));
-  squash2->SetDrawsContent(true);
-
-  scroll->test_properties()->AddChild(std::move(squash2));
-  clip->test_properties()->AddChild(std::move(scroll));
-  clip->test_properties()->AddChild(std::move(scrollbar));
-  clip->test_properties()->AddChild(std::move(squash1));
-  root->test_properties()->AddChild(std::move(clip));
-
-  layer_tree_impl->SetRootLayerForTesting(std::move(root));
-  layer_tree_impl->BuildPropertyTreesForTesting();
-  layer_tree_impl->DidBecomeActive();
-
-  // The point hits squash1 layer and also scroll layer, because scroll layer is
-  // not an ancestor of squash1 layer, we cannot scroll on impl thread.
-  InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
-      BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL);
-  EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
-  EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
-            status.main_thread_scrolling_reasons);
-
-  // The point hits squash1 layer and also scrollbar layer.
-  status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(),
-                                   InputHandler::WHEEL);
-  EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
-  EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
-            status.main_thread_scrolling_reasons);
-
-  // The point hits squash2 layer and also scroll layer, because scroll layer is
-  // an ancestor of squash2 layer, we should scroll on impl.
-  status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(),
-                                   InputHandler::WHEEL);
-  EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
+TEST_F(LayerTreeHostImplTest,
+       ScrollWithOverlappingTransparentNonScrollableLayer) {
+  CreateAndTestNonScrollableLayers(true);
 }
 
 TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 8f83f803..9b361177 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -1934,8 +1934,7 @@
 
 struct HitTestVisibleScrollableOrTouchableFunctor {
   bool operator()(LayerImpl* layer) const {
-    return layer->scrollable() ||
-           layer->contributes_to_drawn_render_surface() ||
+    return layer->scrollable() || layer->should_hit_test() ||
            !layer->touch_action_region().region().IsEmpty();
   }
 };
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 771ba1d..5023619f 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2320,6 +2320,11 @@
      SINGLE_VALUE_TYPE(extensions::switches::kDisableTabForDesktopShare)},
 #endif  // ENABLE_EXTENSIONS
 #if defined(OS_ANDROID)
+    {"keep-prefetched-content-suggestions",
+     flag_descriptions::kKeepPrefetchedContentSuggestionsName,
+     flag_descriptions::kKeepPrefetchedContentSuggestionsDescription,
+     kOsAndroid,
+     FEATURE_VALUE_TYPE(ntp_snippets::kKeepPrefetchedContentSuggestions)},
     {"content-suggestions-category-order",
      flag_descriptions::kContentSuggestionsCategoryOrderName,
      flag_descriptions::kContentSuggestionsCategoryOrderDescription, kOsAndroid,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 85c6903f..b8c9859 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -151,7 +151,7 @@
     "ContentSuggestionsLargeThumbnail", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kContentSuggestionsSettings{
-    "ContentSuggestionsSettings", base::FEATURE_DISABLED_BY_DEFAULT};
+    "ContentSuggestionsSettings", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kContentSuggestionsShowSummary{
     "ContentSuggestionsShowSummary", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/vr_shell/textures/url_bar_texture.cc b/chrome/browser/android/vr_shell/textures/url_bar_texture.cc
index 485bcc3..65a84f9 100644
--- a/chrome/browser/android/vr_shell/textures/url_bar_texture.cc
+++ b/chrome/browser/android/vr_shell/textures/url_bar_texture.cc
@@ -367,23 +367,25 @@
   render_text->SetFontList(font_list);
   render_text->SetColor(SK_ColorBLACK);
   render_text->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  render_text->SetElideBehavior(gfx::TRUNCATE);
+  render_text->SetElideBehavior(gfx::ELIDE_TAIL);
+  render_text->SetText(text);
+  render_text->SetDisplayRect(bounds);
 
+  // Until we can properly elide a URL, we need to bail if the origin portion
+  // cannot be displayed in its entirety.
   base::string16 mandatory_prefix = text;
   int length = parsed.CountCharactersBefore(url::Parsed::PORT, false);
   if (length > 0)
     mandatory_prefix = text.substr(0, length);
-  gfx::Rect expanded_bounds = bounds;
-  expanded_bounds.set_width(2 * bounds.width());
-  render_text->SetDisplayRect(expanded_bounds);
-  render_text->SetText(mandatory_prefix);
-
-  if (render_text->GetStringSize().width() > bounds.width()) {
+  // Ellipsis-based eliding replaces the last character in the string with an
+  // ellipsis, so to reliably check that the origin is intact, check both length
+  // and string equality.
+  if (render_text->GetDisplayText().size() < mandatory_prefix.size() ||
+      render_text->GetDisplayText().substr(0, mandatory_prefix.size()) !=
+          mandatory_prefix) {
     failure_callback_.Run(UiUnsupportedMode::kCouldNotElideURL);
   }
 
-  render_text->SetText(text);
-  render_text->SetDisplayRect(bounds);
   vr_shell::RenderTextWrapper vr_render_text(render_text.get());
   ApplyUrlStyling(text, parsed, security_level_, &vr_render_text,
                   color_scheme());
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
index 3ce9aec..be2d234 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
@@ -69,13 +69,37 @@
   return extension_ime_util::GetInputMethodIDByEngineID(id);
 }
 
-std::string GetCurrentImeIdFromAsh() {
-  return ash::Shell::Get()->ime_controller()->current_ime().id;
-}
+class TestImeController : ash::mojom::ImeController {
+ public:
+  TestImeController() : binding_(this) {}
+  ~TestImeController() override = default;
 
-size_t GetAvailableImeCountFromAsh() {
-  return ash::Shell::Get()->ime_controller()->available_imes().size();
-}
+  // Returns a mojo interface pointer bound to this object.
+  ash::mojom::ImeControllerPtr CreateInterfacePtr() {
+    ash::mojom::ImeControllerPtr ptr;
+    binding_.Bind(mojo::MakeRequest(&ptr));
+    return ptr;
+  }
+
+  // ash::mojom::ImeController:
+  void SetClient(ash::mojom::ImeControllerClientPtr client) override {}
+  void RefreshIme(ash::mojom::ImeInfoPtr current_ime,
+                  std::vector<ash::mojom::ImeInfoPtr> available_imes,
+                  std::vector<ash::mojom::ImeMenuItemPtr> menu_items) override {
+    current_ime_ = std::move(current_ime);
+    available_imes_ = std::move(available_imes);
+  }
+  void SetImesManagedByPolicy(bool managed) override {}
+  void ShowImeMenuOnShelf(bool show) override {}
+
+  ash::mojom::ImeInfoPtr current_ime_;
+  std::vector<ash::mojom::ImeInfoPtr> available_imes_;
+
+ private:
+  mojo::Binding<ash::mojom::ImeController> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestImeController);
+};
 
 class TestObserver : public InputMethodManager::Observer,
                      public ui::ime::InputMethodMenuManager::Observer {
@@ -1574,41 +1598,51 @@
 // Verifies that the combination of InputMethodManagerImpl and
 // ImeControllerClient sends the correct data to ash.
 TEST_F(InputMethodManagerImplTest, IntegrationWithAsh) {
+  TestImeController ime_controller;  // Mojo interface to ash.
   ImeControllerClient ime_controller_client(manager_.get());
+  ime_controller_client.InitForTesting(ime_controller.CreateInterfacePtr());
 
+  // Setup 3 IMEs.
   InitComponentExtension();
   manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
   std::vector<std::string> ids;
   ids.push_back(ImeIdFromEngineId("xkb:us:dvorak:eng"));
   ids.push_back(ImeIdFromEngineId(kExt2Engine2Id));
   ids.push_back(ImeIdFromEngineId(kExt2Engine1Id));
-  EXPECT_TRUE(manager_->GetActiveIMEState()->ReplaceEnabledInputMethods(ids));
+  manager_->GetActiveIMEState()->ReplaceEnabledInputMethods(ids);
+  ime_controller_client.FlushMojoForTesting();
 
-  EXPECT_EQ(3u, GetAvailableImeCountFromAsh());
-  EXPECT_EQ(ImeIdFromEngineId(ids[0]), GetCurrentImeIdFromAsh());
+  // Ash received the IMEs.
+  ASSERT_EQ(3u, ime_controller.available_imes_.size());
+  EXPECT_EQ(ImeIdFromEngineId(ids[0]), ime_controller.current_ime_->id);
 
   // Switch to Mozc.
   manager_->GetActiveIMEState()->SwitchToNextInputMethod();
-  EXPECT_EQ(ImeIdFromEngineId(ids[1]), GetCurrentImeIdFromAsh());
+  ime_controller_client.FlushMojoForTesting();
+  EXPECT_EQ(ImeIdFromEngineId(ids[1]), ime_controller.current_ime_->id);
 
-  // Lock screen
+  // Lock the screen.
   scoped_refptr<input_method::InputMethodManager::State> saved_ime_state =
       manager_->GetActiveIMEState();
   manager_->SetState(saved_ime_state->Clone());
   manager_->GetActiveIMEState()->EnableLockScreenLayouts();
   manager_->SetUISessionState(InputMethodManager::STATE_LOCK_SCREEN);
-  EXPECT_EQ(2u, GetAvailableImeCountFromAsh());  // Qwerty+Dvorak.
-  EXPECT_EQ(ImeIdFromEngineId("xkb:us:dvorak:eng"), GetCurrentImeIdFromAsh());
+  ime_controller_client.FlushMojoForTesting();
+  EXPECT_EQ(2u, ime_controller.available_imes_.size());  // Qwerty+Dvorak.
+  EXPECT_EQ(ImeIdFromEngineId("xkb:us:dvorak:eng"),
+            ime_controller.current_ime_->id);
 
   manager_->GetActiveIMEState()->SwitchToNextInputMethod();
+  ime_controller_client.FlushMojoForTesting();
   EXPECT_EQ(ImeIdFromEngineId("xkb:us::eng"),  // The hardware keyboard layout.
-            GetCurrentImeIdFromAsh());
+            ime_controller.current_ime_->id);
 
   // Unlock screen. The original state, pinyin-dv, is restored.
   manager_->SetState(saved_ime_state);
   manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
-  EXPECT_EQ(3u, GetAvailableImeCountFromAsh());  // Dvorak and 2 IMEs.
-  EXPECT_EQ(ImeIdFromEngineId(ids[1]), GetCurrentImeIdFromAsh());
+  ime_controller_client.FlushMojoForTesting();
+  ASSERT_EQ(3u, ime_controller.available_imes_.size());  // Dvorak and 2 IMEs.
+  EXPECT_EQ(ImeIdFromEngineId(ids[1]), ime_controller.current_ime_->id);
 }
 
 }  // namespace input_method
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc
index 9dc0057..94702527 100644
--- a/chrome/browser/chromeos/login/app_launch_controller.cc
+++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -56,7 +56,17 @@
 };
 
 // Application install splash screen minimum show time in milliseconds.
-const int kAppInstallSplashScreenMinTimeMS = 3000;
+constexpr int kAppInstallSplashScreenMinTimeMS = 3000;
+
+// Parameters for test:
+bool skip_splash_wait = false;
+int network_wait_time_in_seconds = 10;
+base::Closure* network_timeout_callback = nullptr;
+AppLaunchController::ReturnBoolCallback* can_configure_network_callback =
+    nullptr;
+AppLaunchController::ReturnBoolCallback*
+    need_owner_auth_to_configure_network_callback = nullptr;
+bool block_app_launch = false;
 
 bool IsEnterpriseManaged() {
   return g_browser_process->platform_part()
@@ -85,14 +95,6 @@
 
 }  // namespace
 
-// static
-bool AppLaunchController::skip_splash_wait_ = false;
-int AppLaunchController::network_wait_time_ = 10;
-base::Closure* AppLaunchController::network_timeout_callback_ = NULL;
-AppLaunchController::ReturnBoolCallback*
-    AppLaunchController::can_configure_network_callback_ = NULL;
-AppLaunchController::ReturnBoolCallback*
-    AppLaunchController::need_owner_auth_to_configure_network_callback_ = NULL;
 
 ////////////////////////////////////////////////////////////////////////////////
 // AppLaunchController::AppWindowWatcher
@@ -154,7 +156,7 @@
 }
 
 AppLaunchController::~AppLaunchController() {
-  app_launch_splash_screen_view_->SetDelegate(NULL);
+  app_launch_splash_screen_view_->SetDelegate(nullptr);
 }
 
 void AppLaunchController::StartAppLaunch(bool is_auto_launch) {
@@ -207,30 +209,35 @@
 
 // static
 void AppLaunchController::SkipSplashWaitForTesting() {
-  skip_splash_wait_ = true;
+  skip_splash_wait = true;
 }
 
 // static
 void AppLaunchController::SetNetworkWaitForTesting(int wait_time_secs) {
-  network_wait_time_ = wait_time_secs;
+  network_wait_time_in_seconds = wait_time_secs;
 }
 
 // static
 void AppLaunchController::SetNetworkTimeoutCallbackForTesting(
     base::Closure* callback) {
-  network_timeout_callback_ = callback;
+  network_timeout_callback = callback;
 }
 
 // static
 void AppLaunchController::SetCanConfigureNetworkCallbackForTesting(
-    ReturnBoolCallback* can_configure_network_callback) {
-  can_configure_network_callback_ = can_configure_network_callback;
+    ReturnBoolCallback* callback) {
+  can_configure_network_callback = callback;
 }
 
 // static
 void AppLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
-    ReturnBoolCallback* need_owner_auth_callback) {
-  need_owner_auth_to_configure_network_callback_ = need_owner_auth_callback;
+    ReturnBoolCallback* callback) {
+  need_owner_auth_to_configure_network_callback = callback;
+}
+
+// static
+void AppLaunchController::SetBlockAppLaunchForTesting(bool block) {
+  block_app_launch = block;
 }
 
 void AppLaunchController::OnConfigureNetwork() {
@@ -340,8 +347,8 @@
 
   MaybeShowNetworkConfigureUI();
 
-  if (network_timeout_callback_)
-    network_timeout_callback_->Run();
+  if (network_timeout_callback)
+    network_timeout_callback->Run();
 }
 
 void AppLaunchController::OnAppWindowCreated() {
@@ -350,8 +357,8 @@
 }
 
 bool AppLaunchController::CanConfigureNetwork() {
-  if (can_configure_network_callback_)
-    return can_configure_network_callback_->Run();
+  if (can_configure_network_callback)
+    return can_configure_network_callback->Run();
 
   if (IsEnterpriseManaged()) {
     bool should_prompt;
@@ -370,8 +377,8 @@
 }
 
 bool AppLaunchController::NeedOwnerAuthToConfigureNetwork() {
-  if (need_owner_auth_to_configure_network_callback_)
-    return need_owner_auth_to_configure_network_callback_->Run();
+  if (need_owner_auth_to_configure_network_callback)
+    return need_owner_auth_to_configure_network_callback->Run();
 
   return !IsEnterpriseManaged();
 }
@@ -411,8 +418,7 @@
   // after a brief wait time.
   waiting_for_network_ = true;
   network_wait_timer_.Start(
-      FROM_HERE,
-      base::TimeDelta::FromSeconds(network_wait_time_),
+      FROM_HERE, base::TimeDelta::FromSeconds(network_wait_time_in_seconds),
       this, &AppLaunchController::OnNetworkWaitTimedout);
 
   app_launch_splash_screen_view_->UpdateAppLaunchState(
@@ -456,6 +462,9 @@
 void AppLaunchController::OnReadyToLaunch() {
   launcher_ready_ = true;
 
+  if (block_app_launch)
+    return;
+
   if (network_config_requested_)
     return;
 
@@ -474,7 +483,7 @@
 
   // Enforce that we show app install splash screen for some minimum amount
   // of time.
-  if (!skip_splash_wait_ && time_taken_ms < kAppInstallSplashScreenMinTimeMS) {
+  if (!skip_splash_wait && time_taken_ms < kAppInstallSplashScreenMinTimeMS) {
     splash_wait_timer_.Start(
         FROM_HERE,
         base::TimeDelta::FromMilliseconds(
diff --git a/chrome/browser/chromeos/login/app_launch_controller.h b/chrome/browser/chromeos/login/app_launch_controller.h
index be4b189..c4856ed 100644
--- a/chrome/browser/chromeos/login/app_launch_controller.h
+++ b/chrome/browser/chromeos/login/app_launch_controller.h
@@ -58,9 +58,10 @@
   static void SetNetworkTimeoutCallbackForTesting(base::Closure* callback);
   static void SetNetworkWaitForTesting(int wait_time_secs);
   static void SetCanConfigureNetworkCallbackForTesting(
-      ReturnBoolCallback* can_configure_network_callback);
+      ReturnBoolCallback* callback);
   static void SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
-      ReturnBoolCallback* need_owner_auth_callback);
+      ReturnBoolCallback* callback);
+  static void SetBlockAppLaunchForTesting(bool block);
 
  private:
   // A class to watch app window creation.
@@ -143,12 +144,6 @@
   bool show_network_config_ui_after_profile_load_ = false;
   int64_t launch_splash_start_time_ = 0;
 
-  static bool skip_splash_wait_;
-  static int network_wait_time_;
-  static base::Closure* network_timeout_callback_;
-  static ReturnBoolCallback* can_configure_network_callback_;
-  static ReturnBoolCallback* need_owner_auth_to_configure_network_callback_;
-
   DISALLOW_COPY_AND_ASSIGN(AppLaunchController);
 };
 
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index 6b2ea59a..4813f64 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -17,7 +17,6 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "base/synchronization/lock.h"
 #include "base/sys_info.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/fake_cws.h"
@@ -58,7 +57,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/common/signin_pref_names.h"
-#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
@@ -228,12 +226,6 @@
   runner_quit_task.Run();
 }
 
-// Helper function for LockFileThread.
-void LockAndUnlock(std::unique_ptr<base::Lock> lock) {
-  lock->Acquire();
-  lock->Release();
-}
-
 bool IsAppInstalled(const std::string& app_id, const std::string& version) {
   Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
   DCHECK(app_profile);
@@ -786,22 +778,6 @@
     return LoginDisplayHost::default_host()->GetAppLaunchController();
   }
 
-  // Returns a lock that is holding a task on the FILE thread. Any tasks posted
-  // to the FILE thread after this call will be blocked until the returned
-  // lock is released.
-  // This can be used to prevent app installation from completing until some
-  // other conditions are checked and triggered. For example, this can be used
-  // to trigger the network screen during app launch without racing with the
-  // app launching process itself.
-  std::unique_ptr<base::AutoLock> LockFileThread() {
-    std::unique_ptr<base::Lock> lock(new base::Lock);
-    std::unique_ptr<base::AutoLock> auto_lock(new base::AutoLock(*lock));
-    content::BrowserThread::PostTask(
-        content::BrowserThread::FILE, FROM_HERE,
-        base::Bind(&LockAndUnlock, base::Passed(&lock)));
-    return auto_lock;
-  }
-
   MockUserManager* mock_user_manager() { return mock_user_manager_.get(); }
 
   void set_test_app_id(const std::string& test_app_id) {
@@ -943,7 +919,7 @@
   ScopedCanConfigureNetwork can_configure_network(true, false);
 
   // Block app loading until the network screen is shown.
-  std::unique_ptr<base::AutoLock> lock = LockFileThread();
+  AppLaunchController::SetBlockAppLaunchForTesting(true);
 
   // Start app launch and wait for network connectivity timeout.
   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
@@ -961,6 +937,9 @@
   // Continue button should be visible since we are online.
   JsExpect("$('continue-network-config-btn').hidden == false");
 
+  // Let app launching resume.
+  AppLaunchController::SetBlockAppLaunchForTesting(false);
+
   // Click on [Continue] button.
   ASSERT_TRUE(content::ExecuteScript(
       GetLoginUI()->GetWebContents(),
@@ -969,9 +948,6 @@
       "$('continue-network-config-btn').dispatchEvent(e);"
       "})();"));
 
-  // Let app launching resume.
-  lock.reset();
-
   WaitForAppLaunchSuccess();
 }
 
diff --git a/chrome/browser/chromeos/login/lock_screen_utils.cc b/chrome/browser/chromeos/login/lock_screen_utils.cc
index c9d856f..cd395fc18 100644
--- a/chrome/browser/chromeos/login/lock_screen_utils.cc
+++ b/chrome/browser/chromeos/login/lock_screen_utils.cc
@@ -115,7 +115,8 @@
   chromeos::input_method::InputMethodManager* imm =
       chromeos::input_method::InputMethodManager::Get();
   imm->GetActiveIMEState()->SetAllowedInputMethods(allowed_input_methods);
-  ImeControllerClient::Get()->SetImesManagedByPolicy(true);
+  if (ImeControllerClient::Get())  // Can be null in tests.
+    ImeControllerClient::Get()->SetImesManagedByPolicy(true);
 }
 
 void StopEnforcingPolicyInputMethods() {
@@ -124,7 +125,8 @@
   chromeos::input_method::InputMethodManager* imm =
       chromeos::input_method::InputMethodManager::Get();
   imm->GetActiveIMEState()->SetAllowedInputMethods(allowed_input_methods);
-  ImeControllerClient::Get()->SetImesManagedByPolicy(false);
+  if (ImeControllerClient::Get())  // Can be null in tests.
+    ImeControllerClient::Get()->SetImesManagedByPolicy(false);
 }
 
 void SetKeyboardSettings(const AccountId& account_id) {
diff --git a/chrome/browser/component_updater/recovery_improved_component_installer.cc b/chrome/browser/component_updater/recovery_improved_component_installer.cc
index fd3b11ec..3fdf6652 100644
--- a/chrome/browser/component_updater/recovery_improved_component_installer.cc
+++ b/chrome/browser/component_updater/recovery_improved_component_installer.cc
@@ -9,6 +9,7 @@
 
 #include "base/callback.h"
 #include "build/build_config.h"
+#include "chrome/browser/component_updater/component_updater_utils.h"
 
 // This component is behind a Finch experiment. To enable the registration of
 // the component, run Chrome with --enable-features=ImprovedRecoveryComponent.
@@ -83,6 +84,12 @@
                                        PrefService* prefs) {
 #if defined(GOOGLE_CHROME_BUILD)
 #if defined(OS_WIN) || defined(OS_MACOSX)
+  // The improved recovery components requires elevation in the case where
+  // Chrome is installed per-machine. The elevation mechanism is not implemented
+  // yet; therefore, the component is not registered in this case.
+  if (!IsPerUserInstall())
+    return;
+
   DVLOG(1) << "Registering RecoveryImproved component.";
 
   std::unique_ptr<ComponentInstallerTraits> traits(
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 1e62404..2fc4c87 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2314,6 +2314,13 @@
 
 #if defined(OS_ANDROID)
 
+const char kKeepPrefetchedContentSuggestionsName[] =
+    "Keep prefetched content suggestions";
+
+const char kKeepPrefetchedContentSuggestionsDescription[] =
+    "If enabled, some of prefetched content suggestions are not replaced by "
+    "the new fetched suggestions.";
+
 const char kContentSuggestionsCategoryOrderName[] =
     "Default content suggestions category order (e.g. on NTP)";
 
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index bd289b1..f714cf1 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -999,6 +999,9 @@
 extern const char kHerbPrototypeChoicesDescription[];
 extern const char kHerbPrototypeFlavorElderberry[];
 
+extern const char kKeepPrefetchedContentSuggestionsName[];
+extern const char kKeepPrefetchedContentSuggestionsDescription[];
+
 extern const char kLsdPermissionPromptName[];
 extern const char kLsdPermissionPromptDescription[];
 
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css
index e049ee5..1fa5dbe9 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -94,7 +94,7 @@
 
 #fakebox-text {
   bottom: 4px;
-  color: #bbb;
+  color: rgba(0, 0, 0, 0.38);
   font-family: arial, sans-serif;
   font-size: 16px;
   left: 13px;
@@ -165,9 +165,10 @@
 }
 
 #mv-tiles {
-  /* We need a 16px margin and the tiles have 130px height. */
-  height: calc(2*130px + 16px);
-  line-height: calc(130px + 16px);
+  /* Two rows of tiles of 128px each, 16px of spacing between the rows, and
+   * 4px/8px of margin on top and bottom respectively. If you change this, also
+   * change the corresponding values in most_visited_single.css. */
+  height: calc(2*128px + 16px + 4px + 8px);
   margin: 0;
   position: relative;
   text-align: -webkit-auto;
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.css b/chrome/browser/resources/local_ntp/most_visited_single.css
index 5e16510..85b8c3d7 100644
--- a/chrome/browser/resources/local_ntp/most_visited_single.css
+++ b/chrome/browser/resources/local_ntp/most_visited_single.css
@@ -33,9 +33,12 @@
 .mv-tiles-old {
   -webkit-user-select: none;
   font-size: 0;
-  height: calc(146px + 130px);
-  line-height: 146px;
-  margin: 2px 0 0 0;
+  /* Two rows of tiles of 128px each, and 16px of spacing between the rows.
+   * If you change this, also change the corresponding values in
+   * local_ntp.css. */
+  height: calc(2*128px + 16px);
+  line-height: calc(128px + 16px);
+  margin: 4px 0 8px 0;
   opacity: 0;
   position: absolute;
   /* This align correctly for both LTR and RTL */
@@ -139,8 +142,6 @@
 }
 
 .mv-thumb {
-  border: none;
-  border-radius: 0;
   cursor: pointer;
   display: block;
   height: 96px;
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc
index 957603e..f066d65c 100644
--- a/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -103,17 +103,19 @@
 // static
 ProfileSyncService* ProfileSyncServiceFactory::GetForProfile(
     Profile* profile) {
-  if (!ProfileSyncService::IsSyncAllowedByFlag())
-    return nullptr;
-
   return static_cast<ProfileSyncService*>(
-      GetInstance()->GetServiceForBrowserContext(profile, true));
+      GetSyncServiceForBrowserContext(profile));
 }
 
 // static
 syncer::SyncService* ProfileSyncServiceFactory::GetSyncServiceForBrowserContext(
     content::BrowserContext* context) {
-  return GetForProfile(Profile::FromBrowserContext(context));
+  if (!ProfileSyncService::IsSyncAllowedByFlag()) {
+    return nullptr;
+  }
+
+  return static_cast<syncer::SyncService*>(
+      GetInstance()->GetServiceForBrowserContext(context, true));
 }
 
 ProfileSyncServiceFactory::ProfileSyncServiceFactory()
diff --git a/chrome/browser/ui/ash/ime_controller_client.cc b/chrome/browser/ui/ash/ime_controller_client.cc
index 54d6929e..16385ce 100644
--- a/chrome/browser/ui/ash/ime_controller_client.cc
+++ b/chrome/browser/ui/ash/ime_controller_client.cc
@@ -7,12 +7,11 @@
 #include <memory>
 #include <vector>
 
-#include "ash/ime/ime_controller.h"
-#include "ash/public/interfaces/ime_info.mojom.h"
-#include "ash/shell.h"
-#include "ash/system/tray/system_tray_notifier.h"
+#include "ash/public/interfaces/constants.mojom.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/public/common/service_manager_connection.h"
+#include "services/service_manager/public/cpp/connector.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
 #include "ui/base/ime/chromeos/input_method_descriptor.h"
 #include "ui/base/ime/chromeos/input_method_util.h"
@@ -29,13 +28,13 @@
 }  // namespace
 
 ImeControllerClient::ImeControllerClient(InputMethodManager* manager)
-    : input_method_manager_(manager) {
+    : input_method_manager_(manager), binding_(this) {
   DCHECK(input_method_manager_);
   input_method_manager_->AddObserver(this);
   input_method_manager_->AddImeMenuObserver(this);
   InputMethodMenuManager::GetInstance()->AddObserver(this);
 
-  // This does not need send the initial state to ash because that happens
+  // This does not need to send the initial state to ash because that happens
   // via observers when the InputMethodManager initializes its list of IMEs.
 
   DCHECK(!g_instance);
@@ -51,13 +50,44 @@
   input_method_manager_->RemoveObserver(this);
 }
 
+void ImeControllerClient::Init() {
+  // Connect to the controller in ash.
+  content::ServiceManagerConnection::GetForProcess()
+      ->GetConnector()
+      ->BindInterface(ash::mojom::kServiceName, &ime_controller_ptr_);
+  BindAndSetClient();
+}
+
+void ImeControllerClient::InitForTesting(
+    ash::mojom::ImeControllerPtr controller) {
+  ime_controller_ptr_ = std::move(controller);
+  BindAndSetClient();
+}
+
 // static
 ImeControllerClient* ImeControllerClient::Get() {
   return g_instance;
 }
 
 void ImeControllerClient::SetImesManagedByPolicy(bool managed) {
-  ash::Shell::Get()->ime_controller()->SetImesManagedByPolicy(managed);
+  ime_controller_ptr_->SetImesManagedByPolicy(managed);
+}
+
+// ash::mojom::ImeControllerClient:
+void ImeControllerClient::SwitchToNextIme() {
+  NOTIMPLEMENTED();
+}
+
+void ImeControllerClient::SwitchToPreviousIme() {
+  NOTIMPLEMENTED();
+}
+
+void ImeControllerClient::SwitchImeById(const std::string& id) {
+  NOTIMPLEMENTED();
+}
+
+void ImeControllerClient::ActivateImeProperty(const std::string& key) {
+  NOTIMPLEMENTED();
 }
 
 // chromeos::input_method::InputMethodManager::Observer:
@@ -69,7 +99,7 @@
 
 // chromeos::input_method::InputMethodManager::ImeMenuObserver:
 void ImeControllerClient::ImeMenuActivationChanged(bool is_active) {
-  ash::Shell::Get()->ime_controller()->ShowImeMenuOnShelf(is_active);
+  ime_controller_ptr_->ShowImeMenuOnShelf(is_active);
 }
 
 void ImeControllerClient::ImeMenuListChanged() {
@@ -86,53 +116,63 @@
   RefreshIme();
 }
 
-ash::mojom::ImeInfo ImeControllerClient::GetAshImeInfo(
+void ImeControllerClient::FlushMojoForTesting() {
+  ime_controller_ptr_.FlushForTesting();
+}
+
+void ImeControllerClient::BindAndSetClient() {
+  ash::mojom::ImeControllerClientPtr client;
+  binding_.Bind(mojo::MakeRequest(&client));
+  ime_controller_ptr_->SetClient(std::move(client));
+}
+
+ash::mojom::ImeInfoPtr ImeControllerClient::GetAshImeInfo(
     const InputMethodDescriptor& ime) const {
   InputMethodUtil* util = input_method_manager_->GetInputMethodUtil();
-  ash::mojom::ImeInfo info;
-  info.id = ime.id();
-  info.name = util->GetInputMethodLongName(ime);
-  info.medium_name = util->GetInputMethodMediumName(ime);
-  info.short_name = util->GetInputMethodShortName(ime);
-  info.third_party = chromeos::extension_ime_util::IsExtensionIME(ime.id());
+  ash::mojom::ImeInfoPtr info = ash::mojom::ImeInfo::New();
+  info->id = ime.id();
+  info->name = util->GetInputMethodLongName(ime);
+  info->medium_name = util->GetInputMethodMediumName(ime);
+  info->short_name = util->GetInputMethodShortName(ime);
+  info->third_party = chromeos::extension_ime_util::IsExtensionIME(ime.id());
   return info;
 }
 
 void ImeControllerClient::RefreshIme() {
-  ash::ImeController* ime_controller = ash::Shell::Get()->ime_controller();
   InputMethodManager::State* state =
       input_method_manager_->GetActiveIMEState().get();
   if (!state) {
-    ime_controller->RefreshIme(ash::mojom::ImeInfo(),
-                               std::vector<ash::mojom::ImeInfo>(),
-                               std::vector<ash::mojom::ImeMenuItem>());
+    ime_controller_ptr_->RefreshIme(ash::mojom::ImeInfo::New(),
+                                    std::vector<ash::mojom::ImeInfoPtr>(),
+                                    std::vector<ash::mojom::ImeMenuItemPtr>());
     return;
   }
 
   InputMethodDescriptor current_descriptor = state->GetCurrentInputMethod();
-  ash::mojom::ImeInfo current_ime = GetAshImeInfo(current_descriptor);
-  current_ime.selected = true;
+  ash::mojom::ImeInfoPtr current_ime = GetAshImeInfo(current_descriptor);
+  current_ime->selected = true;
 
-  std::vector<ash::mojom::ImeInfo> available_imes;
+  std::vector<ash::mojom::ImeInfoPtr> available_imes;
   std::unique_ptr<std::vector<InputMethodDescriptor>>
       available_ime_descriptors = state->GetActiveInputMethods();
   for (const InputMethodDescriptor& descriptor : *available_ime_descriptors) {
-    ash::mojom::ImeInfo info = GetAshImeInfo(descriptor);
-    info.selected = descriptor.id() == current_ime.id;
-    available_imes.push_back(info);
+    ash::mojom::ImeInfoPtr info = GetAshImeInfo(descriptor);
+    info->selected = descriptor.id() == current_ime->id;
+    available_imes.push_back(std::move(info));
   }
 
-  std::vector<ash::mojom::ImeMenuItem> ash_menu_items;
+  std::vector<ash::mojom::ImeMenuItemPtr> ash_menu_items;
   ui::ime::InputMethodMenuItemList menu_list =
       ui::ime::InputMethodMenuManager::GetInstance()
           ->GetCurrentInputMethodMenuItemList();
   for (const ui::ime::InputMethodMenuItem& menu_item : menu_list) {
-    ash::mojom::ImeMenuItem ash_item;
-    ash_item.key = menu_item.key;
-    ash_item.label = base::UTF8ToUTF16(menu_item.label);
-    ash_item.checked = menu_item.is_selection_item_checked;
-    ash_menu_items.push_back(ash_item);
+    ash::mojom::ImeMenuItemPtr ash_item = ash::mojom::ImeMenuItem::New();
+    ash_item->key = menu_item.key;
+    ash_item->label = base::UTF8ToUTF16(menu_item.label);
+    ash_item->checked = menu_item.is_selection_item_checked;
+    ash_menu_items.push_back(std::move(ash_item));
   }
-  ash::Shell::Get()->ime_controller()->RefreshIme(current_ime, available_imes,
-                                                  ash_menu_items);
+  ime_controller_ptr_->RefreshIme(std::move(current_ime),
+                                  std::move(available_imes),
+                                  std::move(ash_menu_items));
 }
diff --git a/chrome/browser/ui/ash/ime_controller_client.h b/chrome/browser/ui/ash/ime_controller_client.h
index e7f947a..e83f379 100644
--- a/chrome/browser/ui/ash/ime_controller_client.h
+++ b/chrome/browser/ui/ash/ime_controller_client.h
@@ -5,20 +5,17 @@
 #ifndef CHROME_BROWSER_UI_ASH_IME_CONTROLLER_CLIENT_H_
 #define CHROME_BROWSER_UI_ASH_IME_CONTROLLER_CLIENT_H_
 
+#include "ash/public/interfaces/ime_controller.mojom.h"
+#include "ash/public/interfaces/ime_info.mojom.h"
 #include "base/macros.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 #include "ui/chromeos/ime/input_method_menu_manager.h"
 
-namespace ash {
-namespace mojom {
-class ImeInfo;
-}
-}
-
 // Connects the ImeController in ash to the InputMethodManagerImpl in chrome.
-// TODO(jamescook): Convert to using mojo interfaces.
 class ImeControllerClient
-    : public chromeos::input_method::InputMethodManager::Observer,
+    : public ash::mojom::ImeControllerClient,
+      public chromeos::input_method::InputMethodManager::Observer,
       public chromeos::input_method::InputMethodManager::ImeMenuObserver,
       public ui::ime::InputMethodMenuManager::Observer {
  public:
@@ -26,11 +23,23 @@
       chromeos::input_method::InputMethodManager* manager);
   ~ImeControllerClient() override;
 
+  // Initializes and connects to ash.
+  void Init();
+
+  // Tests can shim in a mock mojo interface for the ash controller.
+  void InitForTesting(ash::mojom::ImeControllerPtr controller);
+
   static ImeControllerClient* Get();
 
   // Sets whether the list of IMEs is managed by device policy.
   void SetImesManagedByPolicy(bool managed);
 
+  // ash::mojom::ImeControllerClient:
+  void SwitchToNextIme() override;
+  void SwitchToPreviousIme() override;
+  void SwitchImeById(const std::string& id) override;
+  void ActivateImeProperty(const std::string& key) override;
+
   // chromeos::input_method::InputMethodManager::Observer:
   void InputMethodChanged(chromeos::input_method::InputMethodManager* manager,
                           Profile* profile,
@@ -48,9 +57,14 @@
   void InputMethodMenuItemChanged(
       ui::ime::InputMethodMenuManager* manager) override;
 
+  void FlushMojoForTesting();
+
  private:
+  // Binds this object to its mojo interface and sets it as the ash client.
+  void BindAndSetClient();
+
   // Converts IME information from |descriptor| into the ash mojo format.
-  ash::mojom::ImeInfo GetAshImeInfo(
+  ash::mojom::ImeInfoPtr GetAshImeInfo(
       const chromeos::input_method::InputMethodDescriptor& descriptor) const;
 
   // Sends information about current and available IMEs to ash.
@@ -58,6 +72,12 @@
 
   chromeos::input_method::InputMethodManager* const input_method_manager_;
 
+  // Binds this object to the mojo interface.
+  mojo::Binding<ash::mojom::ImeControllerClient> binding_;
+
+  // ImeController interface in ash.
+  ash::mojom::ImeControllerPtr ime_controller_ptr_;
+
   DISALLOW_COPY_AND_ASSIGN(ImeControllerClient);
 };
 
diff --git a/chrome/browser/ui/ash/ime_controller_client_unittest.cc b/chrome/browser/ui/ash/ime_controller_client_unittest.cc
index 76317c51..dc101460 100644
--- a/chrome/browser/ui/ash/ime_controller_client_unittest.cc
+++ b/chrome/browser/ui/ash/ime_controller_client_unittest.cc
@@ -5,26 +5,267 @@
 #include "chrome/browser/ui/ash/ime_controller_client.h"
 
 #include <memory>
+#include <string>
+#include <utility>
+#include <vector>
 
+#include "ash/public/interfaces/ime_controller.mojom.h"
+#include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "chrome/browser/chromeos/input_method/mock_input_method_manager_impl.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/ime/chromeos/fake_input_method_delegate.h"
+#include "ui/base/ime/chromeos/input_method_descriptor.h"
+#include "ui/base/ime/chromeos/input_method_util.h"
+#include "ui/base/ime/chromeos/mock_input_method_manager.h"
+#include "ui/chromeos/ime/input_method_menu_item.h"
+#include "ui/chromeos/ime/input_method_menu_manager.h"
 
-using ImeControllerClientTest = testing::Test;
+using chromeos::input_method::FakeInputMethodDelegate;
+using chromeos::input_method::InputMethodDescriptor;
+using chromeos::input_method::InputMethodManager;
+using chromeos::input_method::InputMethodUtil;
+using chromeos::input_method::MockInputMethodManager;
+using ui::ime::InputMethodMenuItem;
+using ui::ime::InputMethodMenuManager;
 
-TEST_F(ImeControllerClientTest, Basics) {
-  chromeos::input_method::MockInputMethodManagerImpl input_method_manager;
+namespace {
+
+// Used to look up IME names.
+base::string16 GetLocalizedString(int resource_id) {
+  return base::ASCIIToUTF16("localized string");
+}
+
+// InputMethodManager with available IMEs.
+class TestInputMethodManager : public MockInputMethodManager {
+ public:
+  class TestState : public MockInputMethodManager::State {
+   public:
+    TestState() {
+      // Set up two input methods.
+      std::vector<std::string> layouts({"us"});
+      std::vector<std::string> languages({"en-US"});
+      InputMethodDescriptor ime1("id1", "name1", "indicator1", layouts,
+                                 languages, true /* is_login_keyboard */,
+                                 GURL(), GURL());
+      InputMethodDescriptor ime2("id2", "name2", "indicator2", layouts,
+                                 languages, false /* is_login_keyboard */,
+                                 GURL(), GURL());
+      current_ime_id_ = ime1.id();
+      input_methods_ = {ime1, ime2};
+    }
+
+    // MockInputMethodManager::State:
+    std::unique_ptr<std::vector<InputMethodDescriptor>> GetActiveInputMethods()
+        const override {
+      return base::MakeUnique<std::vector<InputMethodDescriptor>>(
+          input_methods_);
+    }
+    const InputMethodDescriptor* GetInputMethodFromId(
+        const std::string& input_method_id) const override {
+      for (const InputMethodDescriptor& descriptor : input_methods_) {
+        if (input_method_id == descriptor.id())
+          return &descriptor;
+      }
+      return nullptr;
+    }
+    InputMethodDescriptor GetCurrentInputMethod() const override {
+      for (const InputMethodDescriptor& descriptor : input_methods_) {
+        if (current_ime_id_ == descriptor.id())
+          return descriptor;
+      }
+      return InputMethodUtil::GetFallbackInputMethodDescriptor();
+    }
+
+    std::string current_ime_id_;
+    std::vector<InputMethodDescriptor> input_methods_;
+
+   protected:
+    friend base::RefCounted<InputMethodManager::State>;
+    ~TestState() override {}
+
+    DISALLOW_COPY_AND_ASSIGN(TestState);
+  };
+
+  TestInputMethodManager() : state_(new TestState), util_(&delegate_) {}
+  ~TestInputMethodManager() override = default;
+
+  // MockInputMethodManager:
+  void AddObserver(InputMethodManager::Observer* observer) override {
+    ++add_observer_count_;
+  }
+  void AddImeMenuObserver(ImeMenuObserver* observer) override {
+    ++add_menu_observer_count_;
+  }
+  void RemoveObserver(InputMethodManager::Observer* observer) override {
+    ++remove_observer_count_;
+  }
+  void RemoveImeMenuObserver(ImeMenuObserver* observer) override {
+    ++remove_menu_observer_count_;
+  }
+  InputMethodUtil* GetInputMethodUtil() override { return &util_; }
+  scoped_refptr<InputMethodManager::State> GetActiveIMEState() override {
+    return state_;
+  }
+
+  scoped_refptr<TestState> state_;
+  int add_observer_count_ = 0;
+  int remove_observer_count_ = 0;
+  int add_menu_observer_count_ = 0;
+  int remove_menu_observer_count_ = 0;
+  FakeInputMethodDelegate delegate_;
+  InputMethodUtil util_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestInputMethodManager);
+};
+
+class TestImeController : ash::mojom::ImeController {
+ public:
+  TestImeController() : binding_(this) {}
+  ~TestImeController() override = default;
+
+  // Returns a mojo interface pointer bound to this object.
+  ash::mojom::ImeControllerPtr CreateInterfacePtr() {
+    ash::mojom::ImeControllerPtr ptr;
+    binding_.Bind(mojo::MakeRequest(&ptr));
+    return ptr;
+  }
+
+  // ash::mojom::ImeController:
+  void SetClient(ash::mojom::ImeControllerClientPtr client) override {}
+  void RefreshIme(ash::mojom::ImeInfoPtr current_ime,
+                  std::vector<ash::mojom::ImeInfoPtr> available_imes,
+                  std::vector<ash::mojom::ImeMenuItemPtr> menu_items) override {
+    current_ime_ = std::move(current_ime);
+    available_imes_ = std::move(available_imes);
+    menu_items_ = std::move(menu_items);
+  }
+  void SetImesManagedByPolicy(bool managed) override {
+    managed_by_policy_ = managed;
+  }
+  void ShowImeMenuOnShelf(bool show) override {
+    show_ime_menu_on_shelf_ = show;
+  }
+
+  // The most recent values received via mojo.
+  ash::mojom::ImeInfoPtr current_ime_;
+  std::vector<ash::mojom::ImeInfoPtr> available_imes_;
+  std::vector<ash::mojom::ImeMenuItemPtr> menu_items_;
+  bool managed_by_policy_ = false;
+  bool show_ime_menu_on_shelf_ = false;
+
+ private:
+  mojo::Binding<ash::mojom::ImeController> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestImeController);
+};
+
+class ImeControllerClientTest : public testing::Test {
+ public:
+  ImeControllerClientTest() = default;
+  ~ImeControllerClientTest() override = default;
+
+ private:
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+  DISALLOW_COPY_AND_ASSIGN(ImeControllerClientTest);
+};
+
+TEST_F(ImeControllerClientTest, Construction) {
+  TestInputMethodManager input_method_manager;
+  TestImeController ime_controller;
 
   std::unique_ptr<ImeControllerClient> client =
       base::MakeUnique<ImeControllerClient>(&input_method_manager);
-  EXPECT_EQ(1, input_method_manager.add_observer_count());
-  EXPECT_EQ(1, input_method_manager.add_menu_observer_count());
+  client->InitForTesting(ime_controller.CreateInterfacePtr());
+  EXPECT_EQ(1, input_method_manager.add_observer_count_);
+  EXPECT_EQ(1, input_method_manager.add_menu_observer_count_);
 
   client.reset();
-  EXPECT_EQ(1, input_method_manager.remove_observer_count());
-  EXPECT_EQ(1, input_method_manager.remove_menu_observer_count());
+  EXPECT_EQ(1, input_method_manager.remove_observer_count_);
+  EXPECT_EQ(1, input_method_manager.remove_menu_observer_count_);
 }
 
-// TODO(jamescook): When ImeControllerClient switches to using mojo add
-// additional tests that the correct mojo interface methods are called to send
-// data to ash.
+TEST_F(ImeControllerClientTest, SetImesManagedByPolicy) {
+  TestInputMethodManager input_method_manager;
+  TestImeController ime_controller;
+
+  ImeControllerClient client(&input_method_manager);
+  client.InitForTesting(ime_controller.CreateInterfacePtr());
+
+  client.SetImesManagedByPolicy(true);
+  client.FlushMojoForTesting();
+  EXPECT_TRUE(ime_controller.managed_by_policy_);
+}
+
+TEST_F(ImeControllerClientTest, ShowImeMenuOnShelf) {
+  TestInputMethodManager input_method_manager;
+  TestImeController ime_controller;
+
+  ImeControllerClient client(&input_method_manager);
+  client.InitForTesting(ime_controller.CreateInterfacePtr());
+
+  client.ImeMenuActivationChanged(true);
+  client.FlushMojoForTesting();
+  EXPECT_TRUE(ime_controller.show_ime_menu_on_shelf_);
+}
+
+TEST_F(ImeControllerClientTest, InputMethodChanged) {
+  TestInputMethodManager input_method_manager;
+  input_method_manager.delegate_.set_get_localized_string_callback(
+      base::Bind(&GetLocalizedString));
+  TestImeController ime_controller;
+
+  ImeControllerClient client(&input_method_manager);
+  client.InitForTesting(ime_controller.CreateInterfacePtr());
+
+  // Simulate a switch to IME 2.
+  input_method_manager.state_->current_ime_id_ = "id2";
+  client.InputMethodChanged(&input_method_manager, nullptr /* profile */,
+                            false /* show_message */);
+  client.FlushMojoForTesting();
+
+  // IME controller received the change and the list of available IMEs.
+  EXPECT_EQ("id2", ime_controller.current_ime_->id);
+  ASSERT_EQ(2u, ime_controller.available_imes_.size());
+  EXPECT_EQ("id1", ime_controller.available_imes_[0]->id);
+  EXPECT_EQ(base::ASCIIToUTF16("name1"),
+            ime_controller.available_imes_[0]->name);
+  EXPECT_EQ("id2", ime_controller.available_imes_[1]->id);
+  EXPECT_EQ(base::ASCIIToUTF16("name2"),
+            ime_controller.available_imes_[1]->name);
+}
+
+TEST_F(ImeControllerClientTest, MenuItemChanged) {
+  TestInputMethodManager input_method_manager;
+  input_method_manager.delegate_.set_get_localized_string_callback(
+      base::Bind(&GetLocalizedString));
+  TestImeController ime_controller;
+
+  ImeControllerClient client(&input_method_manager);
+  client.InitForTesting(ime_controller.CreateInterfacePtr());
+
+  const bool is_selection_item = true;
+  InputMethodMenuItem item1("key1", "label1", is_selection_item,
+                            true /* checked */);
+  InputMethodMenuItem item2("key2", "label2", is_selection_item,
+                            false /* checked */);
+
+  // Setting the list triggers the InputMethodMenuItemChanged event.
+  InputMethodMenuManager::GetInstance()->SetCurrentInputMethodMenuItemList(
+      {item1, item2});
+  client.FlushMojoForTesting();
+
+  // IME controller received the menu items.
+  ASSERT_EQ(2u, ime_controller.menu_items_.size());
+  EXPECT_EQ("key1", ime_controller.menu_items_[0]->key);
+  EXPECT_TRUE(ime_controller.menu_items_[0]->checked);
+  EXPECT_EQ("key2", ime_controller.menu_items_[1]->key);
+  EXPECT_FALSE(ime_controller.menu_items_[1]->checked);
+}
+
+}  // namespace
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc
index 92107074..2d25e705 100644
--- a/chrome/browser/ui/browser_list.cc
+++ b/chrome/browser/ui/browser_list.cc
@@ -165,7 +165,8 @@
     }
   }
 
-  on_close_success.Run(profile_path);
+  if (on_close_success)
+    on_close_success.Run(profile_path);
 
   for (Browser* b : browsers_to_close) {
     // BeforeUnload handlers may close browser windows, so we need to explicitly
@@ -197,7 +198,8 @@
          it != browsers_to_close.end(); ++it) {
       (*it)->ResetTryToCloseWindow();
     }
-    on_close_aborted.Run(profile_path);
+    if (on_close_aborted)
+      on_close_aborted.Run(profile_path);
   }
 }
 
diff --git a/chrome/browser/ui/browser_list.h b/chrome/browser/ui/browser_list.h
index 7fff2637..ba78df21 100644
--- a/chrome/browser/ui/browser_list.h
+++ b/chrome/browser/ui/browser_list.h
@@ -92,13 +92,14 @@
   static void CloseAllBrowsersWithProfile(Profile* profile);
 
   // Closes all browsers for |profile| across all desktops. Uses
-  // TryToCloseBrowserList() to do the actual closing. Trigger any
-  // OnBeforeUnload events if |if_force| is false. If all OnBeforeUnload events
-  // are confirmed or |skip_beforeunload| is true, |on_close_success| is called,
-  // otherwise |on_close_aborted| is called.
-  // Note that if there is any browser window has been used before, user
-  // should always has a chance to save his or her work before closing windows
-  // without trigger beforeunload event.
+  // TryToCloseBrowserList() to do the actual closing. Triggers any
+  // OnBeforeUnload events unless |skip_beforeunload| is true. If all
+  // OnBeforeUnload events are confirmed or |skip_beforeunload| is true,
+  // |on_close_success| is called, otherwise |on_close_aborted| is called. Both
+  // callbacks may be null.
+  // Note that if there is any browser window that has been used before, the
+  // user should always have a chance to save their work before closing windows
+  // without triggering beforeunload events.
   static void CloseAllBrowsersWithProfile(Profile* profile,
                                           const CloseCallback& on_close_success,
                                           const CloseCallback& on_close_aborted,
diff --git a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
index 9e6572e8f..ac2ba6d 100644
--- a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
+++ b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
@@ -88,11 +88,9 @@
 
   // Must be available at login screen, so initialize before profile.
   system_tray_client_ = base::MakeUnique<SystemTrayClient>();
-  // TODO(jamescook): Enable in mash once converted to mojo.
-  if (!ash_util::IsRunningInMash()) {
-    ime_controller_client_ = base::MakeUnique<ImeControllerClient>(
-        chromeos::input_method::InputMethodManager::Get());
-  }
+  ime_controller_client_ = base::MakeUnique<ImeControllerClient>(
+      chromeos::input_method::InputMethodManager::Get());
+  ime_controller_client_->Init();
   new_window_client_ = base::MakeUnique<ChromeNewWindowClient>();
   volume_controller_ = base::MakeUnique<VolumeController>();
   vpn_list_forwarder_ = base::MakeUnique<VpnListForwarder>();
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals_message_handler.cc
index 5d4ecfa..5bf52b8 100644
--- a/chrome/browser/ui/webui/sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals_message_handler.cc
@@ -297,7 +297,7 @@
 }
 
 SyncService* SyncInternalsMessageHandler::GetSyncService() {
-  return ProfileSyncServiceFactory::GetForProfile(
+  return ProfileSyncServiceFactory::GetSyncServiceForBrowserContext(
       Profile::FromWebUI(web_ui())->GetOriginalProfile());
 }
 
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc
index 92a2c1b..4b5ac4d 100644
--- a/chrome/browser/unload_browsertest.cc
+++ b/chrome/browser/unload_browsertest.cc
@@ -463,6 +463,57 @@
   window_observer.Wait();
 }
 
+// Tests closing the browser by BrowserList::CloseAllBrowsersWithProfile, with
+// a null success callback, a beforeunload handler and clicking Leave in the
+// beforeunload confirm dialog. The test succeed if no crash happens.
+IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserListCloseBeforeUnloadNullCallbackOk) {
+  NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload");
+  PrepareForDialog(browser());
+
+  content::WindowedNotificationObserver window_observer(
+      chrome::NOTIFICATION_BROWSER_CLOSED,
+      content::NotificationService::AllSources());
+  UnloadResults unload_results;
+  BrowserList::CloseAllBrowsersWithProfile(browser()->profile(),
+                                           BrowserList::CloseCallback(),
+                                           BrowserList::CloseCallback(), false);
+  ClickModalDialogButton(true);
+  window_observer.Wait();
+}
+
+// Tests closing the browser by BrowserList::CloseAllBrowsersWithProfile, with
+// a null failure callback, a beforeunload handler and clicking Stay in the
+// beforeunload confirm dialog. The test succeed if no crash happens.
+IN_PROC_BROWSER_TEST_F(UnloadTest,
+                       BrowserListCloseBeforeUnloadNullCallbackCancel) {
+  NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload");
+  PrepareForDialog(browser());
+
+  UnloadResults unload_results;
+  BrowserList::CloseAllBrowsersWithProfile(browser()->profile(),
+                                           BrowserList::CloseCallback(),
+                                           BrowserList::CloseCallback(), false);
+
+  // We wait for the title to change after cancelling the closure of browser
+  // window, to ensure that in-flight IPCs from the renderer reach the browser.
+  // Otherwise the browser won't put up the beforeunload dialog because it's
+  // waiting for an ack from the renderer.
+  base::string16 expected_title = base::ASCIIToUTF16("cancelled");
+  content::TitleWatcher title_watcher(
+      browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
+  ClickModalDialogButton(false);
+  ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+
+  // The test harness cannot close the window automatically, because it requires
+  // confirmation. We close the window manually instead.
+  content::WindowedNotificationObserver window_observer(
+      chrome::NOTIFICATION_BROWSER_CLOSED,
+      content::NotificationService::AllSources());
+  chrome::CloseWindow(browser());
+  ClickModalDialogButton(true);
+  window_observer.Wait();
+}
+
 // Tests terminating the browser with a beforeunload handler.
 // Currently only ChromeOS shuts down gracefully.
 #if defined(OS_CHROMEOS)
diff --git a/components/ntp_snippets/features.cc b/components/ntp_snippets/features.cc
index 6a4b9df..e9539a6 100644
--- a/components/ntp_snippets/features.cc
+++ b/components/ntp_snippets/features.cc
@@ -21,6 +21,7 @@
                                         &kContentSuggestionsPushFeature,
                                         &kForeignSessionsSuggestionsFeature,
                                         &kIncreasedVisibility,
+                                        &kKeepPrefetchedContentSuggestions,
                                         &kNotificationsFeature,
                                         &kPhysicalWebPageSuggestionsFeature,
                                         &kPublisherFaviconsFromNewServerFeature,
@@ -145,4 +146,7 @@
 const char kNotificationsDailyLimit[] = "daily_limit";
 const char kNotificationsIgnoredLimitParam[] = "ignored_limit";
 
+const base::Feature kKeepPrefetchedContentSuggestions{
+    "KeepPrefetchedContentSuggestions", base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace ntp_snippets
diff --git a/components/ntp_snippets/features.h b/components/ntp_snippets/features.h
index aae63b3..be450632 100644
--- a/components/ntp_snippets/features.h
+++ b/components/ntp_snippets/features.h
@@ -119,6 +119,10 @@
 extern const char kNotificationsIgnoredLimitParam[];
 constexpr int kNotificationsIgnoredDefaultLimit = 3;
 
+// Whether to keep some prefetched content suggestions even when new suggestions
+// have been fetched.
+extern const base::Feature kKeepPrefetchedContentSuggestions;
+
 }  // namespace ntp_snippets
 
 #endif  // COMPONENTS_NTP_SNIPPETS_FEATURES_H_
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
index d8367430..91af43c 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -920,27 +920,6 @@
   return handlers;
 }
 
-blink::WebMediaStreamTrack GetRemoteTrack(
-    const std::map<webrtc::MediaStreamInterface*,
-                   std::unique_ptr<content::RemoteMediaStreamImpl>>&
-        remote_streams,
-    const blink::WebString& id,
-    blink::WebMediaStreamTrack (blink::WebMediaStream::*get_track_method)(
-        const blink::WebString& trackId) const) {
-  // TODO(hbos): Tracks and streams are currently added/removed on a per-stream
-  // basis, but tracks could be removed from a stream or added to an existing
-  // stream. We need to listen to events of tracks being added and removed, and
-  // have a list of tracks that is separate from the list of streams.
-  // https://crbug.com/705901
-  for (const auto& remote_stream_pair : remote_streams) {
-    blink::WebMediaStreamTrack web_track =
-        (remote_stream_pair.second->webkit_stream().*get_track_method)(id);
-    if (!web_track.IsNull())
-      return web_track;
-  }
-  return blink::WebMediaStreamTrack();
-}
-
 }  // namespace
 
 // Implementation of LocalRTCStatsRequest.
@@ -1671,32 +1650,16 @@
   for (size_t i = 0; i < web_senders.size(); ++i) {
     rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track =
         webrtc_senders[i]->track();
-    std::unique_ptr<blink::WebMediaStreamTrack> web_track;
-
+    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter;
     if (webrtc_track) {
-      std::string track_id = webrtc_track->id();
-      bool is_audio_track = (webrtc_track->kind() ==
-                             webrtc::MediaStreamTrackInterface::kAudioKind);
-      for (const auto& stream_adapter : local_streams_) {
-        blink::WebVector<blink::WebMediaStreamTrack> tracks;
-        if (is_audio_track)
-          stream_adapter->web_stream().AudioTracks(tracks);
-        else
-          stream_adapter->web_stream().VideoTracks(tracks);
-        for (const blink::WebMediaStreamTrack& track : tracks) {
-          if (track.Id() == track_id.c_str()) {
-            web_track.reset(new blink::WebMediaStreamTrack(track));
-            break;
-          }
-        }
-        if (web_track)
-          break;
-      }
-      DCHECK(web_track);
+      track_adapter =
+          track_adapter_map_->GetLocalTrackAdapter(webrtc_track->id());
+      DCHECK(track_adapter);
     }
-
+    // Create a reference to the sender. Multiple |RTCRtpSender|s can reference
+    // the same webrtc track, see |id|.
     web_senders[i] = base::MakeUnique<RTCRtpSender>(webrtc_senders[i].get(),
-                                                    std::move(web_track));
+                                                    std::move(track_adapter));
   }
   return web_senders;
 }
@@ -1713,22 +1676,14 @@
     rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track =
         webrtc_receivers[i]->track();
     DCHECK(webrtc_track);
+    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_adapter =
+            track_adapter_map_->GetRemoteTrackAdapter(webrtc_track->id());
+    DCHECK(track_adapter);
     // Create a reference to the receiver. Multiple |RTCRtpReceiver|s can
     // reference the same webrtc track, see |id|.
-    blink::WebMediaStreamTrack web_track;
-    if (webrtc_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind) {
-      web_track = GetRemoteAudioTrack(webrtc_track->id());
-    } else {
-      web_track = GetRemoteVideoTrack(webrtc_track->id());
-    }
-    // TODO(hbos): Any existing remote track should be known but the case of a
-    // track being added or removed separately from streams is not handled
-    // properly, see todo in |GetRemoteTrack|. When that is addressed, DCHECK
-    // that the track is not null. https://crbug.com/705901
-    if (!web_track.IsNull()) {
-      web_receivers.push_back(base::MakeUnique<RTCRtpReceiver>(
-          webrtc_receivers[i].get(), web_track));
-    }
+    web_receivers.push_back(base::MakeUnique<RTCRtpReceiver>(
+        webrtc_receivers[i].get(), std::move(track_adapter)));
   }
 
   // |blink::WebVector|'s size must be known at construction, that is why
@@ -2102,20 +2057,6 @@
   }
 }
 
-blink::WebMediaStreamTrack RTCPeerConnectionHandler::GetRemoteAudioTrack(
-    const std::string& track_id) const {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return GetRemoteTrack(remote_streams_, blink::WebString::FromUTF8(track_id),
-                        &blink::WebMediaStream::GetAudioTrack);
-}
-
-blink::WebMediaStreamTrack RTCPeerConnectionHandler::GetRemoteVideoTrack(
-    const std::string& track_id) const {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return GetRemoteTrack(remote_streams_, blink::WebString::FromUTF8(track_id),
-                        &blink::WebMediaStream::GetVideoTrack);
-}
-
 void RTCPeerConnectionHandler::ReportICEState(
     webrtc::PeerConnectionInterface::IceConnectionState new_state) {
   DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/content/renderer/media/rtc_peer_connection_handler.h b/content/renderer/media/rtc_peer_connection_handler.h
index d0db835b..bd58e2df 100644
--- a/content/renderer/media/rtc_peer_connection_handler.h
+++ b/content/renderer/media/rtc_peer_connection_handler.h
@@ -237,13 +237,6 @@
   void RunSynchronousClosureOnSignalingThread(const base::Closure& closure,
                                               const char* trace_event_name);
 
-  // If a track is not found with the specified id, the returned track's
-  // |isNull| will return true.
-  blink::WebMediaStreamTrack GetRemoteAudioTrack(
-      const std::string& track_id) const;
-  blink::WebMediaStreamTrack GetRemoteVideoTrack(
-      const std::string& track_id) const;
-
   base::ThreadChecker thread_checker_;
 
   // |client_| is a weak pointer to the blink object (blink::RTCPeerConnection)
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver.cc b/content/renderer/media/webrtc/rtc_rtp_receiver.cc
index c23a1349..71fc802a 100644
--- a/content/renderer/media/webrtc/rtc_rtp_receiver.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_receiver.cc
@@ -11,27 +11,19 @@
 
 namespace content {
 
-namespace {
-
-inline bool operator==(const blink::WebMediaStreamTrack& web_track,
-                       const webrtc::MediaStreamTrackInterface& webrtc_track) {
-  return !web_track.IsNull() && web_track.Id() == webrtc_track.id().c_str();
-}
-
-}  // namespace
-
 uintptr_t RTCRtpReceiver::getId(
     const webrtc::RtpReceiverInterface* webrtc_rtp_receiver) {
   return reinterpret_cast<uintptr_t>(webrtc_rtp_receiver);
 }
 
 RTCRtpReceiver::RTCRtpReceiver(
-    webrtc::RtpReceiverInterface* webrtc_rtp_receiver,
-    const blink::WebMediaStreamTrack& web_track)
-    : webrtc_rtp_receiver_(webrtc_rtp_receiver), web_track_(web_track) {
+    scoped_refptr<webrtc::RtpReceiverInterface> webrtc_rtp_receiver,
+    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter)
+    : webrtc_rtp_receiver_(std::move(webrtc_rtp_receiver)),
+      track_adapter_(std::move(track_adapter)) {
   DCHECK(webrtc_rtp_receiver_);
-  DCHECK(!web_track_.IsNull());
-  DCHECK(web_track_ == webrtc_track());
+  DCHECK(track_adapter_);
+  DCHECK_EQ(track_adapter_->webrtc_track(), webrtc_rtp_receiver_->track());
 }
 
 RTCRtpReceiver::~RTCRtpReceiver() {}
@@ -41,8 +33,8 @@
 }
 
 const blink::WebMediaStreamTrack& RTCRtpReceiver::Track() const {
-  DCHECK(web_track_ == webrtc_track());
-  return web_track_;
+  DCHECK(track_adapter_->webrtc_track() == webrtc_rtp_receiver_->track());
+  return track_adapter_->web_track();
 }
 
 blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
@@ -57,11 +49,9 @@
 }
 
 const webrtc::MediaStreamTrackInterface& RTCRtpReceiver::webrtc_track() const {
-  const webrtc::MediaStreamTrackInterface* webrtc_track =
-      webrtc_rtp_receiver_->track();
-  DCHECK(webrtc_track);
-  DCHECK(web_track_ == *webrtc_track);
-  return *webrtc_track;
+  DCHECK(track_adapter_->webrtc_track() == webrtc_rtp_receiver_->track());
+  DCHECK(track_adapter_->webrtc_track());
+  return *track_adapter_->webrtc_track();
 }
 
 }  // namespace content
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver.h b/content/renderer/media/webrtc/rtc_rtp_receiver.h
index 5990976f..78636768 100644
--- a/content/renderer/media/webrtc/rtc_rtp_receiver.h
+++ b/content/renderer/media/webrtc/rtc_rtp_receiver.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
 #include "third_party/WebKit/public/platform/WebRTCRtpReceiver.h"
 #include "third_party/webrtc/api/rtpreceiverinterface.h"
@@ -22,8 +23,10 @@
   static uintptr_t getId(
       const webrtc::RtpReceiverInterface* webrtc_rtp_receiver);
 
-  RTCRtpReceiver(webrtc::RtpReceiverInterface* webrtc_rtp_receiver,
-                 const blink::WebMediaStreamTrack& web_track);
+  RTCRtpReceiver(
+      scoped_refptr<webrtc::RtpReceiverInterface> webrtc_rtp_receiver,
+      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+          track_adapter);
   ~RTCRtpReceiver() override;
 
   uintptr_t Id() const override;
@@ -35,7 +38,10 @@
 
  private:
   const scoped_refptr<webrtc::RtpReceiverInterface> webrtc_rtp_receiver_;
-  const blink::WebMediaStreamTrack web_track_;
+  // The track adapter is the glue between blink and webrtc layer tracks.
+  // Keeping a reference to the adapter ensures it is not disposed, as is
+  // required as long as the webrtc layer track is in use by the receiver.
+  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter_;
 
   DISALLOW_COPY_AND_ASSIGN(RTCRtpReceiver);
 };
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender.cc b/content/renderer/media/webrtc/rtc_rtp_sender.cc
index 2d61389..e312e7f 100644
--- a/content/renderer/media/webrtc/rtc_rtp_sender.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -12,11 +12,12 @@
 namespace {
 
 inline bool operator==(
-    const std::unique_ptr<blink::WebMediaStreamTrack>& web_track,
+    const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+        track_adapter,
     const webrtc::MediaStreamTrackInterface* webrtc_track) {
-  if (!web_track)
+  if (!track_adapter)
     return !webrtc_track;
-  return webrtc_track && web_track->Id() == webrtc_track->id().c_str();
+  return track_adapter->webrtc_track() == webrtc_track;
 }
 
 }  // namespace
@@ -27,11 +28,12 @@
 }
 
 RTCRtpSender::RTCRtpSender(
-    webrtc::RtpSenderInterface* webrtc_rtp_sender,
-    std::unique_ptr<blink::WebMediaStreamTrack> web_track)
-    : webrtc_rtp_sender_(webrtc_rtp_sender), web_track_(std::move(web_track)) {
+    scoped_refptr<webrtc::RtpSenderInterface> webrtc_rtp_sender,
+    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter)
+    : webrtc_rtp_sender_(std::move(webrtc_rtp_sender)),
+      track_adapter_(std::move(track_adapter)) {
   DCHECK(webrtc_rtp_sender_);
-  DCHECK(web_track_ == webrtc_track());
+  DCHECK(track_adapter_ == webrtc_rtp_sender_->track());
 }
 
 RTCRtpSender::~RTCRtpSender() {}
@@ -41,12 +43,13 @@
 }
 
 const blink::WebMediaStreamTrack* RTCRtpSender::Track() const {
-  DCHECK(web_track_ == webrtc_track());
-  return web_track_.get();
+  DCHECK(track_adapter_ == webrtc_rtp_sender_->track());
+  return track_adapter_ ? &track_adapter_->web_track() : nullptr;
 }
 
 const webrtc::MediaStreamTrackInterface* RTCRtpSender::webrtc_track() const {
-  return webrtc_rtp_sender_->track();
+  DCHECK(track_adapter_ == webrtc_rtp_sender_->track());
+  return track_adapter_ ? track_adapter_->webrtc_track() : nullptr;
 }
 
 }  // namespace content
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender.h b/content/renderer/media/webrtc/rtc_rtp_sender.h
index 716e0b0..0a375601 100644
--- a/content/renderer/media/webrtc/rtc_rtp_sender.h
+++ b/content/renderer/media/webrtc/rtc_rtp_sender.h
@@ -7,6 +7,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
 #include "third_party/WebKit/public/platform/WebRTCRtpSender.h"
 #include "third_party/webrtc/api/rtpsenderinterface.h"
@@ -20,8 +21,9 @@
  public:
   static uintptr_t getId(const webrtc::RtpSenderInterface* webrtc_rtp_sender);
 
-  RTCRtpSender(webrtc::RtpSenderInterface* webrtc_rtp_sender,
-               std::unique_ptr<blink::WebMediaStreamTrack> web_track);
+  RTCRtpSender(scoped_refptr<webrtc::RtpSenderInterface> webrtc_rtp_sender,
+               std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+                   track_adapter);
   ~RTCRtpSender() override;
 
   uintptr_t Id() const override;
@@ -31,7 +33,10 @@
 
  private:
   const scoped_refptr<webrtc::RtpSenderInterface> webrtc_rtp_sender_;
-  std::unique_ptr<blink::WebMediaStreamTrack> web_track_;
+  // The track adapter is the glue between blink and webrtc layer tracks.
+  // Keeping a reference to the adapter ensures it is not disposed, as is
+  // required as long as the webrtc layer track is in use by the sender.
+  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter_;
 };
 
 }  // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
index a412625..5f4199b5 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
+++ b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_COLLECTION_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_COLLECTION_H_
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
 
 #include <map>
 #include <string>
@@ -142,4 +142,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_COLLECTION_H_
+#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
diff --git a/docs/speed/addressing_performance_regressions.md b/docs/speed/addressing_performance_regressions.md
index f012a04..e228ef1 100644
--- a/docs/speed/addressing_performance_regressions.md
+++ b/docs/speed/addressing_performance_regressions.md
@@ -118,6 +118,13 @@
 
 ## If you don't believe your CL could be the cause
 
+*** promo
+Please remember that our performance tests exist to catch unexpected
+regressions. Often, the tests catch performance problems the CL author was
+not aware of. Please look at the data carefully and understand what the test
+is measuring before concluding that your CL is not related.
+***
+
 There are some clear reasons to believe the bisect bot made a mistake:
 
   * Your CL changes a test or some code that isn't compiled on the platform
diff --git a/docs/vscode.md b/docs/vscode.md
index 36d3f0a..024afaa 100644
--- a/docs/vscode.md
+++ b/docs/vscode.md
@@ -66,6 +66,10 @@
     Code formatting, debugging, Intellisense.
 *   ***Python*** -
     Linting, intellisense, code formatting, refactoring, debugging, snippets.
+*   ***Toggle Header/Source*** -
+    Toggles between .cc and .h with `F4`. The C/C++ extension supports this as
+    well through `Alt+O` but sometimes chooses the wrong file when there are
+    multiple files in the workspace that have the same name.
 *   ***Protobuf support*** -
     Syntax highlighting for .proto files.
 *   ***you-complete-me*** -
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index b256a8f6..005a523 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -3768,7 +3768,12 @@
 }
 
 error::Error GLES2DecoderPassthroughImpl::DoFlushDriverCachesCHROMIUM() {
-  NOTIMPLEMENTED();
+  // On Adreno Android devices we need to use a workaround to force caches to
+  // clear.
+  if (feature_info_->workarounds().unbind_egl_context_to_flush_driver_caches) {
+    context_->ReleaseCurrent(nullptr);
+    context_->MakeCurrent(surface_.get());
+  }
   return error::kNoError;
 }
 
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 5142449..013a617 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -231,6 +231,16 @@
         ntp_tiles::switches::kDisableNtpMostLikelyFaviconsFromServer);
   }
 
+  // Populate command line flag for the native to WKBackForwardList based
+  // navigation manager experiment.
+  NSString* enableSlimNavigationManager =
+      [defaults stringForKey:@"EnableSlimNavigationManager"];
+  if ([enableSlimNavigationManager isEqualToString:@"Enabled"]) {
+    command_line->AppendSwitch(switches::kEnableSlimNavigationManager);
+  } else if ([enableSlimNavigationManager isEqualToString:@"Disabled"]) {
+    command_line->AppendSwitch(switches::kDisableSlimNavigationManager);
+  }
+
   // Freeform commandline flags.  These are added last, so that any flags added
   // earlier in this function take precedence.
   if ([defaults boolForKey:@"EnableFreeformCommandLineFlags"]) {
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc
index 7c09133c..e51438b 100644
--- a/ios/chrome/browser/chrome_switches.cc
+++ b/ios/chrome/browser/chrome_switches.cc
@@ -56,6 +56,9 @@
 // Disables bookmark reordering.
 const char kDisableBookmarkReordering[] = "disable-bookmark-reordering";
 
+// Disables the WKBackForwardList based navigation manager experiment.
+const char kDisableSlimNavigationManager[] = "disable-slim-navigation-manager";
+
 // Enables Contextual Search.
 const char kEnableContextualSearch[] = "enable-contextual-search";
 
@@ -99,6 +102,9 @@
 // Enables bookmark reordering.
 const char kEnableBookmarkReordering[] = "enable-bookmark-reordering";
 
+// Enables the WKBackForwardList based navigation manager experiment.
+const char kEnableSlimNavigationManager[] = "enable-slim-navigation-manager";
+
 // Forces additional Chrome Variation Ids that will be sent in X-Client-Data
 // header, specified as a 64-bit encoded list of numeric experiment ids. Ids
 // prefixed with the character "t" will be treated as Trigger Variation Ids.
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h
index 127c7d1..f5f681a 100644
--- a/ios/chrome/browser/chrome_switches.h
+++ b/ios/chrome/browser/chrome_switches.h
@@ -23,6 +23,7 @@
 extern const char kDisableRequestMobileSite[];
 extern const char kDisableSuggestionsUI[];
 extern const char kDisableBookmarkReordering[];
+extern const char kDisableSlimNavigationManager[];
 
 extern const char kEnableContextualSearch[];
 extern const char kEnableIOSFastWebScrollViewInsets[];
@@ -38,6 +39,7 @@
 extern const char kEnableIOSPhysicalWeb[];
 extern const char kEnableSuggestionsUI[];
 extern const char kEnableBookmarkReordering[];
+extern const char kEnableSlimNavigationManager[];
 
 extern const char kIOSForceVariationIds[];
 extern const char kUserAgent[];
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h
index b91db0c6..1f8875bee 100644
--- a/ios/chrome/browser/experimental_flags.h
+++ b/ios/chrome/browser/experimental_flags.h
@@ -112,6 +112,9 @@
 // Whether the keyboard accessory view with camera search is enabled.
 bool IsKeyboardAccessoryViewWithCameraSearchEnabled();
 
+// Whether the WKBackForwardList based navigation manager is enabled.
+bool IsSlimNavigationManagerEnabled();
+
 }  // namespace experimental_flags
 
 #endif  // IOS_CHROME_BROWSER_EXPERIMENTAL_FLAGS_H_
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm
index 9cb6d1a4..01ed7db 100644
--- a/ios/chrome/browser/experimental_flags.mm
+++ b/ios/chrome/browser/experimental_flags.mm
@@ -42,6 +42,8 @@
 NSString* const kOriginServerHost = @"AlternateOriginServerHost";
 NSString* const kSafariVCSignInDisabled = @"SafariVCSignInDisabled";
 NSString* const kWhatsNewPromoStatus = @"WhatsNewPromoStatus";
+const base::Feature kEnableSlimNavigationManager{
+    "EnableSlimNavigationManager", base::FEATURE_DISABLED_BY_DEFAULT};
 
 }  // namespace
 
@@ -294,4 +296,17 @@
       boolForKey:@"NewKeyboardAccessoryViewEnabled"];
 }
 
+bool IsSlimNavigationManagerEnabled() {
+  // Check if the experimental flag is forced on or off.
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kEnableSlimNavigationManager)) {
+    return true;
+  } else if (command_line->HasSwitch(switches::kDisableSlimNavigationManager)) {
+    return false;
+  }
+
+  // Check if the Finch experiment is turned on.
+  return base::FeatureList::IsEnabled(kEnableSlimNavigationManager);
+}
+
 }  // namespace experimental_flags
diff --git a/ios/chrome/browser/memory/BUILD.gn b/ios/chrome/browser/memory/BUILD.gn
index dce9792..0673e33a 100644
--- a/ios/chrome/browser/memory/BUILD.gn
+++ b/ios/chrome/browser/memory/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 source_set("memory") {
+  configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
     "memory_debugger.h",
     "memory_debugger.mm",
diff --git a/ios/chrome/browser/memory/memory_debugger.mm b/ios/chrome/browser/memory/memory_debugger.mm
index 6d41fbe5..35b880e 100644
--- a/ios/chrome/browser/memory/memory_debugger.mm
+++ b/ios/chrome/browser/memory/memory_debugger.mm
@@ -8,11 +8,14 @@
 
 #include <memory>
 
-#import "base/mac/scoped_nsobject.h"
 #import "ios/chrome/browser/memory/memory_metrics.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 // The number of bytes in a megabyte.
 const CGFloat kNumBytesInMB = 1024 * 1024;
@@ -22,24 +25,24 @@
 
 @implementation MemoryDebugger {
   // A timer to trigger refreshes.
-  base::scoped_nsobject<NSTimer> _refreshTimer;
+  NSTimer* _refreshTimer;
 
   // A timer to trigger continuous memory warnings.
-  base::scoped_nsobject<NSTimer> _memoryWarningTimer;
+  NSTimer* _memoryWarningTimer;
 
   // The font to use.
-  base::scoped_nsobject<UIFont> _font;
+  UIFont* _font;
 
   // Labels for memory metrics.
-  base::scoped_nsobject<UILabel> _physicalFreeMemoryLabel;
-  base::scoped_nsobject<UILabel> _realMemoryUsedLabel;
-  base::scoped_nsobject<UILabel> _xcodeGaugeLabel;
-  base::scoped_nsobject<UILabel> _dirtyVirtualMemoryLabel;
+  UILabel* _physicalFreeMemoryLabel;
+  UILabel* _realMemoryUsedLabel;
+  UILabel* _xcodeGaugeLabel;
+  UILabel* _dirtyVirtualMemoryLabel;
 
   // Inputs for memory commands.
-  base::scoped_nsobject<UITextField> _bloatField;
-  base::scoped_nsobject<UITextField> _refreshField;
-  base::scoped_nsobject<UITextField> _continuousMemoryWarningField;
+  UITextField* _bloatField;
+  UITextField* _refreshField;
+  UITextField* _continuousMemoryWarningField;
 
   // A place to store the artifical memory bloat.
   std::unique_ptr<uint8_t> _bloat;
@@ -54,7 +57,7 @@
 - (instancetype)init {
   self = [super initWithFrame:CGRectZero];
   if (self) {
-    _font.reset([[UIFont systemFontOfSize:14] retain]);
+    _font = [UIFont systemFontOfSize:14];
     self.backgroundColor = [UIColor colorWithWhite:0.8f alpha:0.9f];
     self.opaque = NO;
 
@@ -74,7 +77,6 @@
 
 - (void)dealloc {
   [[NSNotificationCenter defaultCenter] removeObserver:self];
-  [super dealloc];
 }
 
 #pragma mark UIView methods
@@ -97,19 +99,19 @@
   NSUInteger index = 0;
 
   // Display some metrics.
-  _physicalFreeMemoryLabel.reset([[UILabel alloc] initWithFrame:CGRectZero]);
+  _physicalFreeMemoryLabel = [[UILabel alloc] initWithFrame:CGRectZero];
   [self addMetricWithName:@"Physical Free"
                   atIndex:index++
                usingLabel:_physicalFreeMemoryLabel];
-  _realMemoryUsedLabel.reset([[UILabel alloc] initWithFrame:CGRectZero]);
+  _realMemoryUsedLabel = [[UILabel alloc] initWithFrame:CGRectZero];
   [self addMetricWithName:@"Real Memory Used"
                   atIndex:index++
                usingLabel:_realMemoryUsedLabel];
-  _xcodeGaugeLabel.reset([[UILabel alloc] initWithFrame:CGRectZero]);
+  _xcodeGaugeLabel = [[UILabel alloc] initWithFrame:CGRectZero];
   [self addMetricWithName:@"Xcode Gauge"
                   atIndex:index++
                usingLabel:_xcodeGaugeLabel];
-  _dirtyVirtualMemoryLabel.reset([[UILabel alloc] initWithFrame:CGRectZero]);
+  _dirtyVirtualMemoryLabel = [[UILabel alloc] initWithFrame:CGRectZero];
   [self addMetricWithName:@"Dirty VM"
                   atIndex:index++
                usingLabel:_dirtyVirtualMemoryLabel];
@@ -130,7 +132,7 @@
 
   // Display a text input to set the amount of artificial memory bloat and a
   // button to reset the bloat to zero.
-  _bloatField.reset([[UITextField alloc] initWithFrame:CGRectZero]);
+  _bloatField = [[UITextField alloc] initWithFrame:CGRectZero];
   [self addLabelWithText:@"Set bloat (MB)"
                    input:_bloatField
              inputTarget:self
@@ -148,8 +150,8 @@
 // like them) in official builds.
 #if CHROMIUM_BUILD
   // Display a text input to control the rate of continuous memory warnings.
-  _continuousMemoryWarningField.reset(
-      [[UITextField alloc] initWithFrame:CGRectZero]);
+  _continuousMemoryWarningField =
+      [[UITextField alloc] initWithFrame:CGRectZero];
   [self addLabelWithText:@"Set memory warning interval (secs)"
                    input:_continuousMemoryWarningField
              inputTarget:self
@@ -159,7 +161,7 @@
 #endif  // CHROMIUM_BUILD
 
   // Display a text input to control the refresh rate of the memory debugger.
-  _refreshField.reset([[UITextField alloc] initWithFrame:CGRectZero]);
+  _refreshField = [[UITextField alloc] initWithFrame:CGRectZero];
   [self addLabelWithText:@"Set refresh interval (secs)"
                    input:_refreshField
              inputTarget:self
@@ -204,8 +206,7 @@
   CGPoint nameOrigin = [self originForSubviewAtIndex:index];
   CGRect nameFrame =
       CGRectMake(nameOrigin.x, nameOrigin.y, kNameWidth, [_font lineHeight]);
-  base::scoped_nsobject<UILabel> nameLabel(
-      [[UILabel alloc] initWithFrame:nameFrame]);
+  UILabel* nameLabel = [[UILabel alloc] initWithFrame:nameFrame];
   [nameLabel setText:[NSString stringWithFormat:@"%@: ", name]];
   [nameLabel setFont:_font];
   [self addSubview:nameLabel];
@@ -221,8 +222,7 @@
                     target:(id)target
                     action:(SEL)action
                 withOrigin:(CGPoint)origin {
-  base::scoped_nsobject<UIButton> button(
-      [[UIButton buttonWithType:UIButtonTypeSystem] retain]);
+  UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem];
   [button setTitle:title forState:UIControlStateNormal];
   [button titleLabel].font = _font;
   [[button titleLabel] setTextAlignment:NSTextAlignmentCenter];
@@ -274,8 +274,7 @@
             buttonTarget:(id)buttonTarget
             buttonAction:(SEL)buttonAction
                  atIndex:(NSUInteger)index {
-  base::scoped_nsobject<UILabel> label(
-      [[UILabel alloc] initWithFrame:CGRectZero]);
+  UILabel* label = [[UILabel alloc] initWithFrame:CGRectZero];
   if (labelText) {
     [label setText:[NSString stringWithFormat:@"%@: ", labelText]];
   }
@@ -467,12 +466,11 @@
     return;
   }
   [_refreshTimer invalidate];
-  _refreshTimer.reset(
-      [[NSTimer scheduledTimerWithTimeInterval:refreshTimerValue
-                                        target:self
-                                      selector:@selector(refresh:)
-                                      userInfo:nil
-                                       repeats:YES] retain]);
+  _refreshTimer = [NSTimer scheduledTimerWithTimeInterval:refreshTimerValue
+                                                   target:self
+                                                 selector:@selector(refresh:)
+                                                 userInfo:nil
+                                                  repeats:YES];
 }
 
 #pragma mark Memory warning interval methods
@@ -509,12 +507,12 @@
   // memory warnings.
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wundeclared-selector"
-  _memoryWarningTimer.reset(
-      [[NSTimer scheduledTimerWithTimeInterval:timerValue
-                                        target:[UIApplication sharedApplication]
-                                      selector:@selector(_performMemoryWarning)
-                                      userInfo:nil
-                                       repeats:YES] retain]);
+  _memoryWarningTimer =
+      [NSTimer scheduledTimerWithTimeInterval:timerValue
+                                       target:[UIApplication sharedApplication]
+                                     selector:@selector(_performMemoryWarning)
+                                     userInfo:nil
+                                      repeats:YES];
 #pragma clang diagnostic push
 }
 #endif  // CHROMIUM_BUILD
diff --git a/ios/chrome/browser/memory/memory_debugger_manager.mm b/ios/chrome/browser/memory/memory_debugger_manager.mm
index b177bc96..620db2d1 100644
--- a/ios/chrome/browser/memory/memory_debugger_manager.mm
+++ b/ios/chrome/browser/memory/memory_debugger_manager.mm
@@ -4,18 +4,20 @@
 
 #import "ios/chrome/browser/memory/memory_debugger_manager.h"
 
-#include "base/ios/weak_nsobject.h"
 #import "base/mac/bind_objc_block.h"
-#include "base/mac/scoped_nsobject.h"
 #include "components/prefs/pref_member.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #import "ios/chrome/browser/memory/memory_debugger.h"
 #import "ios/chrome/browser/pref_names.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 @implementation MemoryDebuggerManager {
-  __unsafe_unretained UIView* debuggerParentView_;  // weak
-  base::scoped_nsobject<MemoryDebugger> memoryDebugger_;
+  __weak UIView* debuggerParentView_;
+  MemoryDebugger* memoryDebugger_;
   BooleanPrefMember showMemoryDebugger_;
 }
 
@@ -25,10 +27,9 @@
     debuggerParentView_ = debuggerParentView;
 
     // Set up the callback for when the pref to show/hide the debugger changes.
-    base::WeakNSObject<MemoryDebuggerManager> weakSelf(self);
-    base::Closure callback = base::BindBlock(^{
-      base::scoped_nsobject<MemoryDebuggerManager> strongSelf(
-          [weakSelf retain]);
+    __weak MemoryDebuggerManager* weakSelf = self;
+    base::Closure callback = base::BindBlockArc(^{
+      MemoryDebuggerManager* strongSelf = weakSelf;
       if (strongSelf) {
         [self onShowMemoryDebuggingToolsChange];
       }
@@ -43,7 +44,6 @@
 
 - (void)dealloc {
   [self tearDownDebugger];
-  [super dealloc];
 }
 
 #pragma mark - Pref-handling methods
@@ -56,7 +56,7 @@
 // Shows or hides the debugger when the pref changes.
 - (void)onShowMemoryDebuggingToolsChange {
   if (showMemoryDebugger_.GetValue()) {
-    memoryDebugger_.reset([[MemoryDebugger alloc] init]);
+    memoryDebugger_ = [[MemoryDebugger alloc] init];
     [debuggerParentView_ addSubview:memoryDebugger_];
   } else {
     [self tearDownDebugger];
@@ -67,6 +67,6 @@
 - (void)tearDownDebugger {
   [memoryDebugger_ invalidateTimers];
   [memoryDebugger_ removeFromSuperview];
-  memoryDebugger_.reset();
+  memoryDebugger_ = nil;
 }
 @end
diff --git a/ios/chrome/browser/payments/payment_request_util.mm b/ios/chrome/browser/payments/payment_request_util.mm
index cce44f4..de40f85 100644
--- a/ios/chrome/browser/payments/payment_request_util.mm
+++ b/ios/chrome/browser/payments/payment_request_util.mm
@@ -11,6 +11,7 @@
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/payments/core/payment_request_data_util.h"
 #include "components/payments/core/strings_util.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/application_context.h"
@@ -26,9 +27,10 @@
 
 NSString* GetNameLabelFromAutofillProfile(
     const autofill::AutofillProfile& profile) {
-  return base::SysUTF16ToNSString(
+  base::string16 label =
       profile.GetInfo(autofill::AutofillType(autofill::NAME_FULL),
-                      GetApplicationContext()->GetApplicationLocale()));
+                      GetApplicationContext()->GetApplicationLocale());
+  return !label.empty() ? base::SysUTF16ToNSString(label) : nil;
 }
 
 NSString* GetShippingAddressLabelFromAutofillProfile(
@@ -47,13 +49,16 @@
 
 NSString* GetPhoneNumberLabelFromAutofillProfile(
     const autofill::AutofillProfile& profile) {
-  base::string16 label = profile.GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER);
+  base::string16 label = payments::data_util::GetFormattedPhoneNumberForDisplay(
+      profile, GetApplicationContext()->GetApplicationLocale());
   return !label.empty() ? base::SysUTF16ToNSString(label) : nil;
 }
 
 NSString* GetEmailLabelFromAutofillProfile(
     const autofill::AutofillProfile& profile) {
-  base::string16 label = profile.GetRawInfo(autofill::EMAIL_ADDRESS);
+  base::string16 label =
+      profile.GetInfo(autofill::AutofillType(autofill::EMAIL_ADDRESS),
+                      GetApplicationContext()->GetApplicationLocale());
   return !label.empty() ? base::SysUTF16ToNSString(label) : nil;
 }
 
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 1beacd5..9f094c7 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -4404,7 +4404,12 @@
 }
 
 - (void)updateFindBar:(BOOL)initialUpdate shouldFocus:(BOOL)shouldFocus {
-  DCHECK([_model currentTab]);
+  // TODO(crbug.com/731045): This early return temporarily replaces a DCHECK.
+  // For unknown reasons, this DCHECK sometimes was hit in the wild, resulting
+  // in a crash.
+  if (![_model currentTab]) {
+    return;
+  }
   auto* helper = FindTabHelper::FromWebState([_model currentTab].webState);
   if (helper && helper->IsFindUIActive()) {
     if (initialUpdate && !_isOffTheRecord) {
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm
index 7765a81..c6708818 100644
--- a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm
+++ b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm
@@ -35,7 +35,10 @@
 @property(nonatomic, strong)
     CountrySelectionCoordinator* countrySelectionCoordinator;
 
-@property(nonatomic, strong) PaymentRequestEditViewController* viewController;
+@property(nonatomic, strong) UINavigationController* viewController;
+
+@property(nonatomic, strong)
+    PaymentRequestEditViewController* editViewController;
 
 @property(nonatomic, strong) AddressEditMediator* mediator;
 
@@ -48,24 +51,32 @@
 @synthesize delegate = _delegate;
 @synthesize countrySelectionCoordinator = _countrySelectionCoordinator;
 @synthesize viewController = _viewController;
+@synthesize editViewController = _editViewController;
 @synthesize mediator = _mediator;
 
 - (void)start {
-  self.viewController = [[PaymentRequestEditViewController alloc] init];
+  self.editViewController = [[PaymentRequestEditViewController alloc] init];
   // TODO(crbug.com/602666): Title varies depending on what field is missing.
   // e.g., Add Email vs. Add Phone Number.
   NSString* title = self.address
                         ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_ADDRESS)
                         : l10n_util::GetNSString(IDS_PAYMENTS_ADD_ADDRESS);
-  [self.viewController setTitle:title];
-  [self.viewController setDelegate:self];
-  [self.viewController setValidatorDelegate:self];
+  [self.editViewController setTitle:title];
+  [self.editViewController setDelegate:self];
+  [self.editViewController setValidatorDelegate:self];
   self.mediator =
       [[AddressEditMediator alloc] initWithPaymentRequest:self.paymentRequest
                                                   address:self.address];
-  [self.mediator setConsumer:self.viewController];
-  [self.viewController setDataSource:self.mediator];
-  [self.viewController loadModel];
+  [self.mediator setConsumer:self.editViewController];
+  [self.editViewController setDataSource:self.mediator];
+  [self.editViewController loadModel];
+
+  self.viewController = [[UINavigationController alloc]
+      initWithRootViewController:self.editViewController];
+  [self.viewController setModalPresentationStyle:UIModalPresentationFormSheet];
+  [self.viewController
+      setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
+  [self.viewController setNavigationBarHidden:YES];
 
   [[self baseViewController] presentViewController:self.viewController
                                           animated:YES
@@ -78,6 +89,7 @@
                          completion:nil];
   [self.countrySelectionCoordinator stop];
   self.countrySelectionCoordinator = nil;
+  self.editViewController = nil;
   self.viewController = nil;
 }
 
@@ -115,7 +127,7 @@
                           didSelectField:(EditorField*)field {
   if (field.autofillUIType == AutofillUITypeProfileHomeAddressCountry) {
     self.countrySelectionCoordinator = [[CountrySelectionCoordinator alloc]
-        initWithBaseViewController:self.viewController];
+        initWithBaseViewController:self.editViewController];
     [self.countrySelectionCoordinator setCountries:self.mediator.countries];
     [self.countrySelectionCoordinator
         setSelectedCountryCode:self.mediator.selectedCountryCode];
@@ -171,8 +183,8 @@
            didSelectCountryWithCode:(NSString*)countryCode {
   if (self.mediator.selectedCountryCode != countryCode) {
     [self.mediator setSelectedCountryCode:countryCode];
-    [self.viewController loadModel];
-    [self.viewController.collectionView reloadData];
+    [self.editViewController loadModel];
+    [self.editViewController.collectionView reloadData];
   }
   [self.countrySelectionCoordinator stop];
   self.countrySelectionCoordinator = nil;
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm
index f346763..f46eaf9 100644
--- a/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm
@@ -144,6 +144,11 @@
   // Spin the run loop to trigger the animation.
   base::test::ios::SpinRunLoopWithMaxDelay(base::TimeDelta::FromSecondsD(1.0));
   EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
+  EXPECT_TRUE([navigation_controller.visibleViewController
       isMemberOfClass:[PaymentRequestEditViewController class]]);
 
   [coordinator stop];
@@ -201,9 +206,14 @@
   EXPECT_CALL(*profile_comparator_, Invalidate(_)).Times(0);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewController:view_controller
                          didFinishEditingFields:GetEditorFields()];
 
@@ -260,9 +270,14 @@
       .Times(1);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewController:view_controller
                          didFinishEditingFields:GetEditorFields()];
 
@@ -295,9 +310,14 @@
   EXPECT_NE(nil, base_view_controller.presentedViewController);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewControllerDidCancel:view_controller];
 
   EXPECT_OCMOCK_VERIFY(delegate);
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm
index cec036f..fce47e0 100644
--- a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm
+++ b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm
@@ -31,7 +31,10 @@
 
 @interface ContactInfoEditCoordinator ()
 
-@property(nonatomic, strong) PaymentRequestEditViewController* viewController;
+@property(nonatomic, strong) UINavigationController* viewController;
+
+@property(nonatomic, strong)
+    PaymentRequestEditViewController* editViewController;
 
 @property(nonatomic, strong) ContactInfoEditMediator* mediator;
 
@@ -43,25 +46,33 @@
 @synthesize paymentRequest = _paymentRequest;
 @synthesize delegate = _delegate;
 @synthesize viewController = _viewController;
+@synthesize editViewController = _editViewController;
 @synthesize mediator = _mediator;
 
 - (void)start {
-  self.viewController = [[PaymentRequestEditViewController alloc] init];
+  self.editViewController = [[PaymentRequestEditViewController alloc] init];
   // TODO(crbug.com/602666): Title varies depending on what field is missing.
   // e.g., Add Email vs. Add Phone Number.
   NSString* title =
       self.profile
           ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_CONTACT_DETAILS_LABEL)
           : l10n_util::GetNSString(IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL);
-  [self.viewController setTitle:title];
-  [self.viewController setDelegate:self];
-  [self.viewController setValidatorDelegate:self];
+  [self.editViewController setTitle:title];
+  [self.editViewController setDelegate:self];
+  [self.editViewController setValidatorDelegate:self];
   self.mediator = [[ContactInfoEditMediator alloc]
       initWithPaymentRequest:self.paymentRequest
                      profile:self.profile];
-  [self.mediator setConsumer:self.viewController];
-  [self.viewController setDataSource:self.mediator];
-  [self.viewController loadModel];
+  [self.mediator setConsumer:self.editViewController];
+  [self.editViewController setDataSource:self.mediator];
+  [self.editViewController loadModel];
+
+  self.viewController = [[UINavigationController alloc]
+      initWithRootViewController:self.editViewController];
+  [self.viewController setModalPresentationStyle:UIModalPresentationFormSheet];
+  [self.viewController
+      setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
+  [self.viewController setNavigationBarHidden:YES];
 
   [[self baseViewController] presentViewController:self.viewController
                                           animated:YES
@@ -72,6 +83,7 @@
   [[self.viewController presentingViewController]
       dismissViewControllerAnimated:YES
                          completion:nil];
+  self.editViewController = nil;
   self.viewController = nil;
 }
 
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm
index 6522712..2244182 100644
--- a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm
@@ -135,6 +135,11 @@
   // Spin the run loop to trigger the animation.
   base::test::ios::SpinRunLoopWithMaxDelay(base::TimeDelta::FromSecondsD(1.0));
   EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
+  EXPECT_TRUE([navigation_controller.visibleViewController
       isMemberOfClass:[PaymentRequestEditViewController class]]);
 
   [coordinator stop];
@@ -192,9 +197,14 @@
   EXPECT_CALL(*profile_comparator_, Invalidate(_)).Times(0);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewController:view_controller
                          didFinishEditingFields:GetEditorFields()];
 
@@ -251,9 +261,14 @@
       .Times(1);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewController:view_controller
                          didFinishEditingFields:GetEditorFields()];
 
@@ -286,9 +301,14 @@
   EXPECT_NE(nil, base_view_controller.presentedViewController);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewControllerDidCancel:view_controller];
 
   EXPECT_OCMOCK_VERIFY(delegate);
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm
index a75fa00..63f1c2e4 100644
--- a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm
+++ b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm
@@ -69,7 +69,10 @@
 @property(nonatomic, strong)
     BillingAddressSelectionCoordinator* billingAddressSelectionCoordinator;
 
-@property(nonatomic, strong) PaymentRequestEditViewController* viewController;
+@property(nonatomic, strong) UINavigationController* viewController;
+
+@property(nonatomic, strong)
+    PaymentRequestEditViewController* editViewController;
 
 @property(nonatomic, strong) CreditCardEditViewControllerMediator* mediator;
 
@@ -83,25 +86,33 @@
 @synthesize billingAddressSelectionCoordinator =
     _billingAddressSelectionCoordinator;
 @synthesize viewController = _viewController;
+@synthesize editViewController = _editViewController;
 @synthesize mediator = _mediator;
 
 - (void)start {
-  _viewController = [[PaymentRequestEditViewController alloc] init];
+  _editViewController = [[PaymentRequestEditViewController alloc] init];
   // TODO(crbug.com/602666): Title varies depending on the missing fields.
   NSString* title = _creditCard
                         ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_CARD)
                         : l10n_util::GetNSString(IDS_PAYMENTS_ADD_CARD_LABEL);
-  [_viewController setTitle:title];
-  [_viewController setDelegate:self];
-  [_viewController setValidatorDelegate:self];
+  [_editViewController setTitle:title];
+  [_editViewController setDelegate:self];
+  [_editViewController setValidatorDelegate:self];
   _mediator = [[CreditCardEditViewControllerMediator alloc]
       initWithPaymentRequest:_paymentRequest
                   creditCard:_creditCard];
-  [_mediator setConsumer:_viewController];
-  [_viewController setDataSource:_mediator];
-  [_viewController loadModel];
+  [_mediator setConsumer:_editViewController];
+  [_editViewController setDataSource:_mediator];
+  [_editViewController loadModel];
 
-  [[self baseViewController] presentViewController:_viewController
+  self.viewController = [[UINavigationController alloc]
+      initWithRootViewController:self.editViewController];
+  [self.viewController setModalPresentationStyle:UIModalPresentationFormSheet];
+  [self.viewController
+      setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
+  [self.viewController setNavigationBarHidden:YES];
+
+  [[self baseViewController] presentViewController:self.viewController
                                           animated:YES
                                         completion:nil];
 }
@@ -112,7 +123,8 @@
                          completion:nil];
   [self.billingAddressSelectionCoordinator stop];
   self.billingAddressSelectionCoordinator = nil;
-  _viewController = nil;
+  self.editViewController = nil;
+  self.viewController = nil;
 }
 
 #pragma mark - PaymentRequestEditViewControllerValidator
@@ -148,7 +160,7 @@
   if (field.autofillUIType == AutofillUITypeCreditCardBillingAddress) {
     self.billingAddressSelectionCoordinator =
         [[BillingAddressSelectionCoordinator alloc]
-            initWithBaseViewController:self.viewController];
+            initWithBaseViewController:self.editViewController];
     [self.billingAddressSelectionCoordinator
         setPaymentRequest:self.paymentRequest];
     [self.billingAddressSelectionCoordinator
@@ -222,8 +234,8 @@
   // controller.
   DCHECK(billingAddress);
   [self.mediator setBillingProfile:billingAddress];
-  [self.viewController loadModel];
-  [self.viewController.collectionView reloadData];
+  [self.editViewController loadModel];
+  [self.editViewController.collectionView reloadData];
 
   [self.billingAddressSelectionCoordinator stop];
   self.billingAddressSelectionCoordinator = nil;
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm
index fb0c5ab..9016fd3 100644
--- a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm
@@ -131,6 +131,11 @@
   // Spin the run loop to trigger the animation.
   base::test::ios::SpinRunLoopWithMaxDelay(base::TimeDelta::FromSecondsD(1.0));
   EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
+  EXPECT_TRUE([navigation_controller.visibleViewController
       isMemberOfClass:[PaymentRequestEditViewController class]]);
 
   [coordinator stop];
@@ -186,9 +191,14 @@
   EXPECT_CALL(personal_data_manager_, UpdateCreditCard(_)).Times(0);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewController:view_controller
                          didFinishEditingFields:GetEditorFields(true)];
 
@@ -236,9 +246,14 @@
   EXPECT_CALL(personal_data_manager_, UpdateCreditCard(_)).Times(0);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewController:view_controller
                          didFinishEditingFields:GetEditorFields(false)];
 
@@ -289,9 +304,14 @@
       .Times(1);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewController:view_controller
                          didFinishEditingFields:GetEditorFields(true)];
 
@@ -324,9 +344,14 @@
   EXPECT_NE(nil, base_view_controller.presentedViewController);
 
   // Call the controller delegate method.
+  EXPECT_TRUE([base_view_controller.presentedViewController
+      isMemberOfClass:[UINavigationController class]]);
+  UINavigationController* navigation_controller =
+      base::mac::ObjCCastStrict<UINavigationController>(
+          base_view_controller.presentedViewController);
   PaymentRequestEditViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestEditViewController>(
-          base_view_controller.presentedViewController);
+          navigation_controller.visibleViewController);
   [coordinator paymentRequestEditViewControllerDidCancel:view_controller];
 
   EXPECT_OCMOCK_VERIFY(delegate);
diff --git a/ios/web/navigation/navigation_manager_impl.h b/ios/web/navigation/navigation_manager_impl.h
index d2226ee..fb4fc7d 100644
--- a/ios/web/navigation/navigation_manager_impl.h
+++ b/ios/web/navigation/navigation_manager_impl.h
@@ -86,9 +86,6 @@
   // TODO(stuartmorgan): Re-evaluate this list once the refactorings have
   // settled down.
   CRWSessionController* GetSessionController();
-  void LoadURL(const GURL& url,
-               const Referrer& referrer,
-               ui::PageTransition type);
 
   // Adds a transient item with the given URL. A transient item will be
   // discarded on any navigation.
diff --git a/ios/web/navigation/navigation_manager_impl.mm b/ios/web/navigation/navigation_manager_impl.mm
index a4e07328..46f7e40 100644
--- a/ios/web/navigation/navigation_manager_impl.mm
+++ b/ios/web/navigation/navigation_manager_impl.mm
@@ -137,14 +137,6 @@
   return session_controller_;
 }
 
-void NavigationManagerImpl::LoadURL(const GURL& url,
-                                    const web::Referrer& referrer,
-                                    ui::PageTransition type) {
-  WebState::OpenURLParams params(url, referrer,
-                                 WindowOpenDisposition::CURRENT_TAB, type, NO);
-  delegate_->GetWebState()->OpenURL(params);
-}
-
 void NavigationManagerImpl::AddTransientItem(const GURL& url) {
   [session_controller_ addTransientItemWithURL:url];
 
diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h
index ab7ddee..dbfa4d1 100644
--- a/net/http/http_stream_factory_impl_job.h
+++ b/net/http/http_stream_factory_impl_job.h
@@ -33,6 +33,12 @@
 
 namespace net {
 
+namespace test {
+
+class HttpStreamFactoryImplJobPeer;
+
+}  // namespace test
+
 class ClientSocketHandle;
 class HttpAuthController;
 class HttpNetworkSession;
@@ -252,7 +258,7 @@
   void LogHistograms() const;
 
  private:
-  friend class HttpStreamFactoryImplJobPeer;
+  friend class test::HttpStreamFactoryImplJobPeer;
 
   enum State {
     STATE_START,
diff --git a/net/http/http_stream_factory_impl_job_controller.h b/net/http/http_stream_factory_impl_job_controller.h
index 9b29742..76a70e1a 100644
--- a/net/http/http_stream_factory_impl_job_controller.h
+++ b/net/http/http_stream_factory_impl_job_controller.h
@@ -17,6 +17,12 @@
 
 class NetLogWithSource;
 
+namespace test {
+
+class JobControllerPeer;
+
+}  // namespace test
+
 // HttpStreamFactoryImpl::JobController manages Request and Job(s).
 class HttpStreamFactoryImpl::JobController
     : public HttpStreamFactoryImpl::Job::Delegate,
@@ -181,7 +187,7 @@
   size_t EstimateMemoryUsage() const;
 
  private:
-  friend class JobControllerPeer;
+  friend class test::JobControllerPeer;
 
   enum State {
     STATE_RESOLVE_PROXY,
diff --git a/net/http/http_stream_factory_impl_job_controller_unittest.cc b/net/http/http_stream_factory_impl_job_controller_unittest.cc
index 886f739..9758db52b 100644
--- a/net/http/http_stream_factory_impl_job_controller_unittest.cc
+++ b/net/http/http_stream_factory_impl_job_controller_unittest.cc
@@ -47,6 +47,8 @@
 
 namespace net {
 
+namespace test {
+
 namespace {
 
 const char kServerHostname[] = "www.example.com";
@@ -274,11 +276,11 @@
   HttpStreamFactoryImpl::JobController* job_controller_ = nullptr;
   std::unique_ptr<HttpStreamFactoryImpl::Request> request_;
   std::unique_ptr<SequencedSocketData> tcp_data_;
-  std::unique_ptr<test::MockQuicData> quic_data_;
+  std::unique_ptr<MockQuicData> quic_data_;
   MockCryptoClientStreamFactory crypto_client_stream_factory_;
   MockClock clock_;
-  test::MockRandom random_generator_{0};
-  test::QuicTestPacketMaker client_maker_{
+  MockRandom random_generator_{0};
+  QuicTestPacketMaker client_maker_{
       HttpNetworkSession::Params().quic_supported_versions[0], 0, &clock_,
       kServerHostname, Perspective::IS_CLIENT};
 
@@ -435,8 +437,7 @@
   std::unique_ptr<ProxyService> proxy_service =
       ProxyService::CreateFixedFromPacResult(
           "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT");
-  std::unique_ptr<TestProxyDelegate> test_proxy_delegate =
-      base::MakeUnique<TestProxyDelegate>();
+  auto test_proxy_delegate = base::MakeUnique<TestProxyDelegate>();
   TestProxyDelegate* test_proxy_delegate_raw = test_proxy_delegate.get();
 
   // Before starting the test, verify that there are no proxies marked as bad.
@@ -458,7 +459,7 @@
         ProxyServer::FromPacString("QUIC badproxy:99"));
   }
 
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
 
   // When retrying the job using the second proxy (badFallback:98),
   // alternative job must not be created. So, socket data for only the
@@ -467,21 +468,21 @@
   socket_data_proxy_main_job_2.set_connect_data(MockConnect(ASYNC, mock_error));
   session_deps_.socket_factory->AddSocketDataProvider(
       &socket_data_proxy_main_job_2);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   // First request would use DIRECT, and succeed.
   StaticSocketDataProvider socket_data_direct_first_request;
   socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
   session_deps_.socket_factory->AddSocketDataProvider(
       &socket_data_direct_first_request);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   // Second request would use DIRECT, and succeed.
   StaticSocketDataProvider socket_data_direct_second_request;
   socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK));
   session_deps_.socket_factory->AddSocketDataProvider(
       &socket_data_direct_second_request);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   // Now request a stream. It should succeed using the DIRECT.
   HttpRequestInfo request_info;
@@ -661,7 +662,7 @@
   // Use COLD_START to make the alt job pending.
   crypto_client_stream_factory_.set_handshake_mode(
       MockCryptoClientStream::COLD_START);
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(SYNCHRONOUS, OK);
 
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
@@ -690,7 +691,7 @@
 }
 
 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddConnect(ASYNC, ERR_FAILED);
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
@@ -721,15 +722,15 @@
 
 TEST_F(HttpStreamFactoryImplJobControllerTest,
        AltJobFailsAfterMainJobSucceeds) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(ASYNC, ERR_FAILED);
   crypto_client_stream_factory_.set_handshake_mode(
       MockCryptoClientStream::COLD_START);
 
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(SYNCHRONOUS, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(SYNCHRONOUS, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   HttpRequestInfo request_info;
   request_info.method = "GET";
@@ -767,7 +768,7 @@
 // Regression test for crbug.com/678768.
 TEST_F(HttpStreamFactoryImplJobControllerTest,
        AltJobSucceedsMainJobBlockedControllerDestroyed) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr));
   quic_data_->AddRead(ASYNC, OK);
 
@@ -846,7 +847,7 @@
 // JobController will be cleaned up.
 TEST_F(HttpStreamFactoryImplJobControllerTest,
        OrphanedJobCompletesControllerDestroyed) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   // Use cold start and complete alt job manually.
   crypto_client_stream_factory_.set_handshake_mode(
@@ -854,8 +855,8 @@
 
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   HttpRequestInfo request_info;
   request_info.method = "GET";
@@ -899,7 +900,7 @@
 
 TEST_F(HttpStreamFactoryImplJobControllerTest,
        AltJobSucceedsAfterMainJobFailed) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   // Use cold start and complete alt job manually.
   crypto_client_stream_factory_.set_handshake_mode(
@@ -947,13 +948,13 @@
 
 TEST_F(HttpStreamFactoryImplJobControllerTest,
        MainJobSucceedsAfterAltJobFailed) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED);
 
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   base::HistogramTester histogram_tester;
   HttpRequestInfo request_info;
@@ -991,12 +992,12 @@
 // then the alternative service is not marked as broken.
 TEST_F(HttpStreamFactoryImplJobControllerTest,
        MainJobSucceedsAfterConnectionChanged) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddConnect(SYNCHRONOUS, ERR_NETWORK_CHANGED);
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   base::HistogramTester histogram_tester;
 
@@ -1033,7 +1034,7 @@
 // Get load state after main job fails and before alternative job succeeds.
 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) {
   // Use COLD_START to complete alt job manually.
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   crypto_client_stream_factory_.set_handshake_mode(
       MockCryptoClientStream::COLD_START);
@@ -1078,15 +1079,15 @@
 
 TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) {
   // Use COLD_START to stall alt job.
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   crypto_client_stream_factory_.set_handshake_mode(
       MockCryptoClientStream::COLD_START);
 
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   HttpRequestInfo request_info;
   request_info.method = "GET";
@@ -1428,12 +1429,12 @@
 // Verifies that if the alternative proxy server job fails immediately, the
 // main job is not blocked.
 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED);
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   UseAlternativeProxy();
 
@@ -1478,12 +1479,12 @@
   // Use COLD_START to make the alt job pending.
   crypto_client_stream_factory_.set_handshake_mode(
       MockCryptoClientStream::COLD_START);
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   UseAlternativeProxy();
 
@@ -1527,7 +1528,7 @@
 
 TEST_F(HttpStreamFactoryImplJobControllerTest,
        PreconnectToHostWithValidAltSvc) {
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr));
   quic_data_->AddRead(ASYNC, OK);
 
@@ -1595,9 +1596,9 @@
   tcp_data_ = base::MakeUnique<SequencedSocketData>(reads, arraysize(reads),
                                                     nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  ssl_data->next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  ssl_data.next_proto = kProtoHTTP2;
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
   HttpRequestInfo request_info;
   request_info.method = "GET";
   request_info.url = GURL("https://www.example.com");
@@ -1652,28 +1653,28 @@
 TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequestsFirstRequestHang) {
   base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
   // First socket connect hang.
-  auto hangdata = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
-  hangdata->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
-  session_deps_.socket_factory->AddSocketDataProvider(hangdata.get());
+  SequencedSocketData hangdata(nullptr, 0, nullptr, 0);
+  hangdata.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
+  session_deps_.socket_factory->AddSocketDataProvider(&hangdata);
   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
-  std::vector<std::unique_ptr<SequencedSocketData>> socket_data;
-  std::vector<std::unique_ptr<SSLSocketDataProvider>> ssl_socket_data;
+  std::list<SequencedSocketData> socket_data;
+  std::list<SSLSocketDataProvider> ssl_socket_data;
   // kNumRequests - 1 will resume themselves after a delay. There will be
   // kNumRequests - 1 sockets opened.
   for (int i = 0; i < kNumRequests - 1; i++) {
     // Only the first one needs a MockRead because subsequent sockets are
     // not used to establish a SpdySession.
-    auto tcp_data =
-        i == 0 ? base::MakeUnique<SequencedSocketData>(reads, arraysize(reads),
-                                                       nullptr, 0)
-               : base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
-    tcp_data->set_connect_data(MockConnect(ASYNC, OK));
-    auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-    ssl_data->next_proto = kProtoHTTP2;
-    session_deps_.socket_factory->AddSocketDataProvider(tcp_data.get());
-    session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
-    socket_data.push_back(std::move(tcp_data));
-    ssl_socket_data.push_back(std::move(ssl_data));
+    if (i == 0) {
+      socket_data.emplace_back(reads, arraysize(reads), nullptr, 0);
+    } else {
+      socket_data.emplace_back(nullptr, 0, nullptr, 0);
+    }
+    socket_data.back().set_connect_data(MockConnect(ASYNC, OK));
+    session_deps_.socket_factory->AddSocketDataProvider(&socket_data.back());
+    ssl_socket_data.emplace_back(ASYNC, OK);
+    ssl_socket_data.back().next_proto = kProtoHTTP2;
+    session_deps_.socket_factory->AddSSLSocketDataProvider(
+        &ssl_socket_data.back());
   }
   HttpRequestInfo request_info;
   request_info.method = "GET";
@@ -1719,36 +1720,33 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
-  EXPECT_TRUE(hangdata->AllReadDataConsumed());
+  EXPECT_TRUE(hangdata.AllReadDataConsumed());
   for (const auto& data : socket_data) {
-    EXPECT_TRUE(data->AllReadDataConsumed());
-    EXPECT_TRUE(data->AllWriteDataConsumed());
+    EXPECT_TRUE(data.AllReadDataConsumed());
+    EXPECT_TRUE(data.AllWriteDataConsumed());
   }
 }
 
 TEST_F(JobControllerLimitMultipleH2Requests,
        MultipleRequestsFirstRequestCanceled) {
   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
-  auto first_socket = base::MakeUnique<SequencedSocketData>(
-      reads, arraysize(reads), nullptr, 0);
-  first_socket->set_connect_data(MockConnect(ASYNC, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  ssl_data->next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSocketDataProvider(first_socket.get());
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
-  std::vector<std::unique_ptr<SequencedSocketData>> socket_data;
-  std::vector<std::unique_ptr<SSLSocketDataProvider>> ssl_socket_data;
+  SequencedSocketData first_socket(reads, arraysize(reads), nullptr, 0);
+  first_socket.set_connect_data(MockConnect(ASYNC, OK));
+  SSLSocketDataProvider first_ssl_data(ASYNC, OK);
+  first_ssl_data.next_proto = kProtoHTTP2;
+  session_deps_.socket_factory->AddSocketDataProvider(&first_socket);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&first_ssl_data);
+  std::list<SequencedSocketData> socket_data;
+  std::list<SSLSocketDataProvider> ssl_socket_data;
   // kNumRequests - 1 will be resumed when the first request is canceled.
   for (int i = 0; i < kNumRequests - 1; i++) {
-    auto tcp_data =
-        base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
-    tcp_data->set_connect_data(MockConnect(ASYNC, OK));
-    auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-    ssl_data->next_proto = kProtoHTTP2;
-    session_deps_.socket_factory->AddSocketDataProvider(tcp_data.get());
-    session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
-    socket_data.push_back(std::move(tcp_data));
-    ssl_socket_data.push_back(std::move(ssl_data));
+    socket_data.emplace_back(nullptr, 0, nullptr, 0);
+    socket_data.back().set_connect_data(MockConnect(ASYNC, OK));
+    session_deps_.socket_factory->AddSocketDataProvider(&socket_data.back());
+    ssl_socket_data.emplace_back(ASYNC, OK);
+    ssl_socket_data.back().next_proto = kProtoHTTP2;
+    session_deps_.socket_factory->AddSSLSocketDataProvider(
+        &ssl_socket_data.back());
   }
 
   HttpRequestInfo request_info;
@@ -1792,10 +1790,10 @@
   }
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
-  EXPECT_TRUE(first_socket->AllReadDataConsumed());
+  EXPECT_TRUE(first_socket.AllReadDataConsumed());
   for (const auto& data : socket_data) {
-    EXPECT_TRUE(data->AllReadDataConsumed());
-    EXPECT_TRUE(data->AllWriteDataConsumed());
+    EXPECT_TRUE(data.AllReadDataConsumed());
+    EXPECT_TRUE(data.AllWriteDataConsumed());
   }
 }
 
@@ -1803,9 +1801,9 @@
   // Make sure there is only one socket connect.
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  ssl_data->next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  ssl_data.next_proto = kProtoHTTP2;
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
   HttpRequestInfo request_info;
   request_info.method = "GET";
   request_info.url = GURL("https://www.example.com");
@@ -1836,21 +1834,19 @@
 
 TEST_F(JobControllerLimitMultipleH2Requests, H1NegotiatedForFirstRequest) {
   // First socket is an HTTP/1.1 socket.
-  auto first_socket =
-      base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
-  first_socket->set_connect_data(MockConnect(ASYNC, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSocketDataProvider(first_socket.get());
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SequencedSocketData first_socket(nullptr, 0, nullptr, 0);
+  first_socket.set_connect_data(MockConnect(ASYNC, OK));
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSocketDataProvider(&first_socket);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
   // Second socket is an HTTP/2 socket.
   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
-  auto second_socket = base::MakeUnique<SequencedSocketData>(
-      reads, arraysize(reads), nullptr, 0);
-  second_socket->set_connect_data(MockConnect(ASYNC, OK));
-  auto second_ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  second_ssl_data->next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSocketDataProvider(second_socket.get());
-  session_deps_.socket_factory->AddSSLSocketDataProvider(second_ssl_data.get());
+  SequencedSocketData second_socket(reads, arraysize(reads), nullptr, 0);
+  second_socket.set_connect_data(MockConnect(ASYNC, OK));
+  session_deps_.socket_factory->AddSocketDataProvider(&second_socket);
+  SSLSocketDataProvider second_ssl_data(ASYNC, OK);
+  second_ssl_data.next_proto = kProtoHTTP2;
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&second_ssl_data);
 
   HttpRequestInfo request_info;
   request_info.method = "GET";
@@ -1891,24 +1887,24 @@
   }
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
-  EXPECT_TRUE(first_socket->AllReadDataConsumed());
-  EXPECT_FALSE(second_socket->AllReadDataConsumed());
+  EXPECT_TRUE(first_socket.AllReadDataConsumed());
+  EXPECT_FALSE(second_socket.AllReadDataConsumed());
 }
 
 // Tests that HTTP/2 throttling logic only applies to non-QUIC jobs.
 TEST_F(JobControllerLimitMultipleH2Requests, QuicJobNotThrottled) {
   crypto_client_stream_factory_.set_handshake_mode(
       MockCryptoClientStream::COLD_START);
-  quic_data_ = base::MakeUnique<test::MockQuicData>();
+  quic_data_ = base::MakeUnique<MockQuicData>();
   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
   tcp_data_ = base::MakeUnique<SequencedSocketData>(reads, arraysize(reads),
                                                     nullptr, 0);
 
   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  ssl_data->next_proto = kProtoHTTP2;
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  ssl_data.next_proto = kProtoHTTP2;
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   HttpRequestInfo request_info;
   request_info.method = "GET";
@@ -1963,15 +1959,15 @@
   const bool enable_ip_based_pooling = ::testing::get<0>(GetParam());
   const bool enable_alternative_services = ::testing::get<1>(GetParam());
   if (enable_alternative_services) {
-    quic_data_ = base::MakeUnique<test::MockQuicData>();
+    quic_data_ = base::MakeUnique<MockQuicData>();
     quic_data_->AddConnect(SYNCHRONOUS, OK);
     quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr));
     quic_data_->AddRead(ASYNC, OK);
   }
   tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
-  auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-  session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
+  SSLSocketDataProvider ssl_data(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
 
   HttpRequestInfo request_info;
   request_info.method = "GET";
@@ -2050,20 +2046,18 @@
 
 TEST_P(HttpStreamFactoryImplJobControllerPreconnectTest,
        LimitEarlyPreconnects) {
-  std::vector<std::unique_ptr<SequencedSocketData>> providers;
-  std::vector<std::unique_ptr<SSLSocketDataProvider>> ssl_providers;
+  std::list<SequencedSocketData> providers;
+  std::list<SSLSocketDataProvider> ssl_providers;
   const int kNumPreconects = 5;
   MockRead reads[] = {MockRead(ASYNC, OK)};
   // If experiment is not enabled, there are 5 socket connects.
   const size_t actual_num_connects = GetParam() ? 1 : kNumPreconects;
   for (size_t i = 0; i < actual_num_connects; ++i) {
-    auto data = base::MakeUnique<SequencedSocketData>(reads, arraysize(reads),
-                                                      nullptr, 0);
-    auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
-    session_deps_.socket_factory->AddSocketDataProvider(data.get());
-    session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
-    providers.push_back(std::move(data));
-    ssl_providers.push_back(std::move(ssl_data));
+    providers.emplace_back(reads, arraysize(reads), nullptr, 0);
+    session_deps_.socket_factory->AddSocketDataProvider(&providers.back());
+    ssl_providers.emplace_back(ASYNC, OK);
+    session_deps_.socket_factory->AddSSLSocketDataProvider(
+        &ssl_providers.back());
   }
   Initialize();
   Preconnect(kNumPreconects);
@@ -2075,4 +2069,6 @@
   EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
 }
 
+}  // namespace test
+
 }  // namespace net
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn
index 8c8752b0..d0c0b6e 100644
--- a/testing/libfuzzer/fuzzers/BUILD.gn
+++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -290,13 +290,13 @@
   libfuzzer_options = [ "max_len=500" ]
 }
 
-fuzzer_test("v8_wasm_asmjs_fuzzer") {
+fuzzer_test("v8_wasm_async_fuzzer") {
   sources = []
   deps = [
-    "//v8:wasm_asmjs_fuzzer",
+    "//v8:wasm_async_fuzzer",
   ]
   dict = "dicts/v8_wasm.dict"
-  seed_corpus = "//v8/test/fuzzer/wasm_asmjs_corpus/"
+  seed_corpus = "//v8/test/fuzzer/wasm_corpus/"
   libfuzzer_options = [ "max_len=500" ]
 }
 
diff --git a/testing/libfuzzer/fuzzers/dicts/v8_wasm.dict b/testing/libfuzzer/fuzzers/dicts/v8_wasm.dict
index c381ea5..f86c763 100644
--- a/testing/libfuzzer/fuzzers/dicts/v8_wasm.dict
+++ b/testing/libfuzzer/fuzzers/dicts/v8_wasm.dict
@@ -1,30 +1,2 @@
-wasm_magic="\x6d\x73\x61\x00"
-"memory"
-"\x06memory"
-"signatures"
-"\x0asignatures"
-"functions"
-"\x09functions"
-"globals"
-"\x07globals"
-"data_segments"
-"\x0ddata_segments"
-"function_table"
-"\x0efunction_table"
-"end"
-"\x03end"
-"start_function"
-"\x0estart_function"
-"import_table"
-"\x0cimport_table"
-"export_table"
-"\x0cexport_table"
-"function_signatures"
-"\x13function_signatures"
-"function_bodies"
-"\x0ffunction_bodies"
-"names"
-"\x05names"
-"\x00\x00\x00\x00\x00\x00\x00\x00"
-"\x02\x00"
+"name"
 
diff --git a/third_party/WebKit/API_OWNERS b/third_party/WebKit/API_OWNERS
index e704dd9..e94ffe2 100644
--- a/third_party/WebKit/API_OWNERS
+++ b/third_party/WebKit/API_OWNERS
@@ -7,6 +7,6 @@
 dglazkov@chromium.org
 foolip@chromium.org
 jochen@chromium.org
+mkwst@chromium.org
 rbyers@chromium.org
 tkent@chromium.org
-mkwst@chromium.org
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index 322f5e3..adfad1d3 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -725,6 +725,7 @@
 Bug(none) fast/multicol/line-in-next-row-in-fourth-inner-multicol.html [ Failure ]
 Bug(none) fast/multicol/line-pushed-down-by-float.html [ Failure ]
 Bug(none) fast/multicol/line-too-tall-for-second-outer-row.html [ Failure ]
+Bug(none) fast/multicol/many-lines-overflow-in-single-row-inner.html [ Failure ]
 Bug(none) fast/multicol/margin-collapse.html [ Failure ]
 Bug(none) fast/multicol/mixed-opacity-fixed-test.html [ Failure ]
 Bug(none) fast/multicol/mixed-opacity-test.html [ Failure ]
@@ -1271,6 +1272,7 @@
 Bug(none) paint/invalidation/svg/foreign-object-repaint.svg [ Failure ]
 Bug(none) paint/invalidation/svg/hairline-stroke-squarecap.svg [ Failure ]
 Bug(none) paint/invalidation/svg/image-animation-with-zoom.html [ Pass Failure ]
+Bug(none) paint/invalidation/svg/image-href-change.svg [ Failure ]
 Bug(none) paint/invalidation/svg/image-with-clip-path.svg [ Failure ]
 Bug(none) paint/invalidation/svg/inner-svg-change-viewBox-contract.svg [ Failure ]
 Bug(none) paint/invalidation/svg/inner-svg-change-viewBox.svg [ Failure ]
@@ -1291,6 +1293,7 @@
 Bug(none) paint/invalidation/svg/repaint-in-scrolled-view.html [ Failure ]
 Bug(none) paint/invalidation/svg/resize-svg-invalidate-children-2.html [ Failure ]
 Bug(none) paint/invalidation/svg/resize-svg-invalidate-children.html [ Failure ]
+Bug(none) paint/invalidation/svg/resource-client-removal.svg [ Failure ]
 Bug(none) paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ]
 Bug(none) paint/invalidation/svg/shape-transform-change.html [ Failure ]
 Bug(none) paint/invalidation/svg/tabgroup.svg [ Failure ]
@@ -1369,6 +1372,7 @@
 # Subpixel differences
 Bug(none) fast/backgrounds/animated-svg-as-mask.html [ Failure ]
 Bug(none) images/color-profile-mask-image-svg.html [ Failure ]
+Bug(none) paint/printing/print-box-shadow.html [ Failure ]
 Bug(none) svg/W3C-SVG-1.1/masking-mask-01-b.svg [ Failure ]
 Bug(none) svg/custom/absolute-root-position-masking.xhtml [ Failure ]
 Bug(none) svg/custom/grayscale-gradient-mask-2.svg [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode-expected.txt
deleted file mode 100644
index 5729e39..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-PASS Ensure that body element is loaded. 
-PASS Ensure that style.overflowY can be set properly. 
-PASS document.compatMode should be BackCompat in quirks. 
-FAIL document.scrollingElement should be body element in quirks. assert_equals: scrollingElement in quirks mode should default to body element. expected Element node <body id="thebody" style="overflow-y: scroll;">
-    <div ... but got null
-PASS scrollingElement in quirks should be null when body is potentially scrollable. 
-FAIL scrollingElement in quirks should be body if any of document and body has a visible overflow. assert_equals: expected Element node <body id="thebody" style="overflow-y: scroll;">
-    <div ... but got null
-PASS When body potentially scrollable, document.body.scrollHeight changes when changing the height of the body content in quirks. 
-FAIL When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. visible, scroll) assert_equals: expected 600 but got 240
-PASS When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. scroll, visible) 
-PASS When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. visible, visible) 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode.html b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode.html
index 46fd5010..8255d130 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode.html
@@ -44,6 +44,8 @@
     assert_equals(document.body.style.overflowY, "scroll", "Could not set document.body.style.overflowY to 'scroll'.");
     document.documentElement.style.overflowY = "scroll";
     assert_equals(document.documentElement.style.overflowY, "scroll", "Could not set document.documentElement.style.overflow to 'scroll'.");
+    document.documentElement.style.overflowY = "";
+    document.body.style.overflowY = "";
 }, "Ensure that style.overflowY can be set properly.")
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollingElement-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollingElement-expected.txt
deleted file mode 100644
index 86c987b..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollingElement-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL scrollingElement in quirks mode assert_equals: expected Element node <body style="overflow: scroll;"></body> but got null
-PASS scrollingElement in no-quirks mode 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-draw-canvas-on-canvas-shadow.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-draw-canvas-on-canvas-shadow.html
index 95a0cc9..02d4260 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-draw-canvas-on-canvas-shadow.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-draw-canvas-on-canvas-shadow.html
@@ -47,7 +47,7 @@
     assert_equals(d[2], 0);
     assert_equals(d[3], 255);
     
-    d = ctx.getImageData(200, 299, 1, 1).data;
+    d = ctx.getImageData(205, 299, 1, 1).data;
     assert_equals(d[0], 255);
     assert_equals(d[1], 0);
     assert_equals(d[2], 0);
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored-worker.html
index 4a0a55b..c293135 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored-worker.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored-worker.html
@@ -220,7 +220,7 @@
 var worker = makeWorker(document.getElementById("myWorker").textContent);
 worker.addEventListener('message', t.step_func_done(function(msg) {
     var results = msg.data;
-    assert_equals(results.length, 33);
+    assert_greater_than(results.length, 0);
     for (var i = 0; i < results.length; i++)
         assert_equals(results[i], true);
 }));
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored.html b/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored.html
index fecba800..b0d64c8c 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost-restored.html
@@ -180,7 +180,7 @@
     compareGLError(gl.INVALID_ENUM, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
     // Try re-enabling extension
     OES_texture_float = reGetExtensionAndTestForProperty(gl, "OES_texture_float", false);
-    compareGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
+    compareGLError(gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
   }
 }
 
diff --git a/third_party/WebKit/LayoutTests/nfc/push.html b/third_party/WebKit/LayoutTests/nfc/push.html
index c55d9f6..c3fc515 100644
--- a/third_party/WebKit/LayoutTests/nfc/push.html
+++ b/third_party/WebKit/LayoutTests/nfc/push.html
@@ -12,7 +12,7 @@
       // Invalid NFCPushMessage type
       undefined,
 
-      // NFCMessage.data: should have at least 1 valid record.
+      // NFCMessage.records: should have at least 1 valid record.
       // https://w3c.github.io/web-nfc/#the-push-method - Step 8.
       createMessage([{}]),
 
diff --git a/third_party/WebKit/LayoutTests/nfc/resources/nfc-helpers.js b/third_party/WebKit/LayoutTests/nfc/resources/nfc-helpers.js
index 389b123..70df000 100644
--- a/third_party/WebKit/LayoutTests/nfc/resources/nfc-helpers.js
+++ b/third_party/WebKit/LayoutTests/nfc/resources/nfc-helpers.js
@@ -27,7 +27,7 @@
 function createMessage(records) {
   if (records !== undefined) {
     let message = {}
-    message.data = records;
+    message.records = records;
     return message;
   }
 }
@@ -113,7 +113,7 @@
       let nfcMessage = new nfc.NFCMessage();
       nfcMessage.url = message.url;
       nfcMessage.data = [];
-      for (let record of message.data)
+      for (let record of message.records)
         nfcMessage.data.push(toMojoNFCRecord(record));
       return nfcMessage;
     }
@@ -155,12 +155,12 @@
       else if (typeof providedMessage === 'string')
         provided = createMessage([createTextRecord(providedMessage)]);
 
-      assert_equals(provided.data.length, receivedMessage.data.length,
+      assert_equals(provided.records.length, receivedMessage.data.length,
           'NFCMessages must have same number of NFCRecords');
 
       // Compare contents of each individual NFCRecord
-      for (let i = 0; i < provided.data.length; ++i)
-        compareNFCRecords(provided.data[i], receivedMessage.data[i]);
+      for (let i = 0; i < provided.records.length; ++i)
+        compareNFCRecords(provided.records[i], receivedMessage.data[i]);
     }
 
     // Used to compare two WebNFC messages, one that is provided to mock NFC
@@ -168,10 +168,10 @@
     // callback that is provided to navigator.nfc.watch function.
     function assertWebNFCMessagesEqual(a, b) {
       assert_equals(a.url, b.url);
-      assert_equals(a.data.length, b.data.length);
-      for(let i in a.data) {
-        let recordA = a.data[i];
-        let recordB = b.data[i];
+      assert_equals(a.records.length, b.records.length);
+      for(let i in a.records) {
+        let recordA = a.records[i];
+        let recordB = b.records[i];
         assert_equals(recordA.recordType, recordB.recordType);
         assert_equals(recordA.mediaType, recordB.mediaType);
 
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 3c48c5c5..7d38e31 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2165,6 +2165,7 @@
     if (document_element->ShouldCallRecalcStyle(change)) {
       TRACE_EVENT0("blink,blink_style", "Document::recalcStyle");
       document_element->RecalcStyle(change);
+      UpdateHasOverflowClipForBody();
     }
     if (document_element->NeedsReattachLayoutTree() ||
         document_element->ChildNeedsReattachLayoutTree()) {
@@ -2205,6 +2206,15 @@
   CSSTiming::From(*this).RecordUpdateDuration(update_duration_seconds);
 }
 
+void Document::UpdateHasOverflowClipForBody() {
+  HTMLBodyElement* body = FirstBodyElement();
+  if (!body)
+    return;
+  LayoutObject* layout_object = body->GetLayoutObject();
+  if (layout_object && layout_object->IsLayoutBlock())
+    ToLayoutBlock(layout_object)->UpdateHasOverflowClip();
+}
+
 void Document::NotifyLayoutTreeOfSubtreeChanges() {
   if (!GetLayoutViewItem().WasNotifiedOfSubtreeChange())
     return;
@@ -2985,11 +2995,11 @@
   Element* root_element = documentElement();
   Element* body_element = body();
   if (!root_element)
-    return 0;
+    return nullptr;
   if (!root_style) {
     root_style = root_element->GetComputedStyle();
     if (!root_style)
-      return 0;
+      return nullptr;
   }
   if (body_element && root_style->IsOverflowVisible() &&
       isHTMLHtmlElement(*root_element))
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 758c631f..a7c4aea9 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1380,6 +1380,7 @@
   void UpdateStyleInvalidationIfNeeded();
   void UpdateStyle();
   void NotifyLayoutTreeOfSubtreeChanges();
+  void UpdateHasOverflowClipForBody();
 
   // ImplicitClose() actually does the work of closing the input stream.
   void ImplicitClose();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index ce6e324..527a870 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -272,6 +272,10 @@
 void LayoutBlock::UpdateFromStyle() {
   LayoutBox::UpdateFromStyle();
 
+  UpdateHasOverflowClip();
+}
+
+void LayoutBlock::UpdateHasOverflowClip() {
   bool should_clip_overflow =
       !StyleRef().IsOverflowVisible() && AllowsOverflowClip();
   if (should_clip_overflow != HasOverflowClip()) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.h b/third_party/WebKit/Source/core/layout/LayoutBlock.h
index 50fe207..c8c3f7d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.h
@@ -420,7 +420,7 @@
   void UpdateFromStyle() override;
 
   // Returns true if non-visible overflow should be respected. Otherwise
-  // hasOverflowClip() will be false and we won't create scrollable area for
+  // HasOverflowClip() will be false and we won't create scrollable area for
   // this object even if overflow is non-visible.
   virtual bool AllowsOverflowClip() const;
 
@@ -431,6 +431,7 @@
 
  public:
   virtual void ComputeOverflow(LayoutUnit old_client_after_edge, bool = false);
+  void UpdateHasOverflowClip();
 
  protected:
   virtual void AddOverflowFromChildren();
diff --git a/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h b/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h
index 0d1df02f..e3dded21 100644
--- a/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h
+++ b/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h
@@ -42,8 +42,6 @@
     return ToView()->OverflowClipRect(location);
   }
 
-  void ClearSelection() { return ToView()->ClearSelection(); }
-
   bool HitTest(HitTestResult& result) { return ToView()->HitTest(result); }
 
   bool HitTestNoLifecycleUpdate(HitTestResult& result) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index 99a7f84..2110feca 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -226,6 +226,7 @@
       CreateGraphicsLayer(owning_layer_.GetCompositingReasons(),
                           owning_layer_.GetSquashingDisallowedReasons());
 
+  UpdateShouldHitTest(true);
   UpdateOpacity(GetLayoutObject().StyleRef());
   UpdateTransform(GetLayoutObject().StyleRef());
   UpdateFilters(GetLayoutObject().StyleRef());
@@ -252,6 +253,10 @@
   scrolling_contents_layer_ = nullptr;
 }
 
+void CompositedLayerMapping::UpdateShouldHitTest(const bool& should_hit_test) {
+  graphics_layer_->SetShouldHitTest(should_hit_test);
+}
+
 void CompositedLayerMapping::UpdateOpacity(const ComputedStyle& style) {
   graphics_layer_->SetOpacity(CompositingOpacity(style.Opacity()));
 }
@@ -2380,6 +2385,7 @@
       // Inner layer which renders the content that scrolls.
       scrolling_contents_layer_ =
           CreateGraphicsLayer(kCompositingReasonLayerForScrollingContents);
+      scrolling_contents_layer_->SetShouldHitTest(true);
 
       AnimatingData data;
       GetAnimatingData(owning_layer_, data);
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index 2796c98..c1ee8c9 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -446,6 +446,7 @@
   // Result is transform origin in pixels.
   FloatPoint3D ComputeTransformOrigin(const IntRect& border_box) const;
 
+  void UpdateShouldHitTest(const bool&);
   void UpdateOpacity(const ComputedStyle&);
   void UpdateTransform(const ComputedStyle&);
   void UpdateLayerBlendMode(const ComputedStyle&);
diff --git a/third_party/WebKit/Source/modules/nfc/NFC.cpp b/third_party/WebKit/Source/modules/nfc/NFC.cpp
index 2f055ad..2c7a679 100644
--- a/third_party/WebKit/Source/modules/nfc/NFC.cpp
+++ b/third_party/WebKit/Source/modules/nfc/NFC.cpp
@@ -266,9 +266,9 @@
   static NFCMessagePtr Convert(const blink::NFCMessage& message) {
     NFCMessagePtr messagePtr = NFCMessage::New();
     messagePtr->url = message.url();
-    messagePtr->data.resize(message.data().size());
-    for (size_t i = 0; i < message.data().size(); ++i) {
-      NFCRecordPtr record = NFCRecord::From(message.data()[i]);
+    messagePtr->data.resize(message.records().size());
+    for (size_t i = 0; i < message.records().size(); ++i) {
+      NFCRecordPtr record = NFCRecord::From(message.records()[i]);
       if (record.is_null())
         return nullptr;
 
@@ -508,14 +508,14 @@
 
   if (push_message.isNFCMessage()) {
     // https://w3c.github.io/web-nfc/#the-push-method
-    // If NFCMessage.data is empty, reject promise with TypeError
+    // If NFCMessage.records is empty, reject promise with TypeError
     const NFCMessage& message = push_message.getAsNFCMessage();
-    if (!message.hasData() || message.data().IsEmpty()) {
+    if (!message.hasRecords() || message.records().IsEmpty()) {
       return RejectWithTypeError(script_state,
                                  "Empty NFCMessage was provided.");
     }
 
-    return RejectIfInvalidNFCRecordArray(script_state, message.data());
+    return RejectIfInvalidNFCRecordArray(script_state, message.records());
   }
 
   return ScriptPromise();
@@ -616,7 +616,7 @@
   blink::HeapVector<NFCRecord> records;
   for (size_t i = 0; i < message->data.size(); ++i)
     records.push_back(ToNFCRecord(script_state, message->data[i]));
-  nfc_message.setData(records);
+  nfc_message.setRecords(records);
   return nfc_message;
 }
 
diff --git a/third_party/WebKit/Source/modules/nfc/NFCMessage.idl b/third_party/WebKit/Source/modules/nfc/NFCMessage.idl
index 5cea9c70..de49b5d 100644
--- a/third_party/WebKit/Source/modules/nfc/NFCMessage.idl
+++ b/third_party/WebKit/Source/modules/nfc/NFCMessage.idl
@@ -5,6 +5,6 @@
 // https://w3c.github.io/web-nfc/#the-nfcmessage-dictionary
 
 dictionary NFCMessage {
-    sequence<NFCRecord> data;
+    sequence<NFCRecord> records;
     USVString url;
 };
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
index 15dd92002..8b1f298 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -1135,9 +1135,6 @@
   stream->UnregisterObserver(this);
 
   peer_handler_->RemoveStream(stream->Descriptor());
-
-  // The senders of removed tracks will have become inactive.
-  RemoveInactiveSenders();
 }
 
 MediaStreamVector RTCPeerConnection::getLocalStreams() const {
@@ -1288,32 +1285,6 @@
   return tracks_.at(static_cast<MediaStreamComponent*>(web_track));
 }
 
-void RTCPeerConnection::RemoveInactiveSenders() {
-  std::set<uintptr_t> inactive_sender_ids;
-  for (uintptr_t id : rtp_senders_.Keys()) {
-    inactive_sender_ids.insert(id);
-  }
-  for (const auto& web_rtp_sender : peer_handler_->GetSenders()) {
-    inactive_sender_ids.erase(web_rtp_sender->Id());
-  }
-  for (uintptr_t id : inactive_sender_ids) {
-    rtp_senders_.erase(id);
-  }
-}
-
-void RTCPeerConnection::RemoveInactiveReceivers() {
-  std::set<uintptr_t> inactive_receiver_ids;
-  for (uintptr_t id : rtp_receivers_.Keys()) {
-    inactive_receiver_ids.insert(id);
-  }
-  for (const auto& web_rtp_receiver : peer_handler_->GetReceivers()) {
-    inactive_receiver_ids.erase(web_rtp_receiver->Id());
-  }
-  for (uintptr_t id : inactive_receiver_ids) {
-    rtp_receivers_.erase(id);
-  }
-}
-
 RTCDTMFSender* RTCPeerConnection::createDTMFSender(
     MediaStreamTrack* track,
     ExceptionState& exception_state) {
@@ -1443,9 +1414,6 @@
   remote_streams_.erase(pos);
   stream->UnregisterObserver(this);
 
-  // The receivers of removed tracks will have become inactive.
-  RemoveInactiveReceivers();
-
   ScheduleDispatchEvent(
       MediaStreamEvent::Create(EventTypeNames::removestream, stream));
 }
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
index 4bc2b0f0..d9fba38 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
@@ -211,7 +211,14 @@
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  friend class RTCPeerConnectionTest;
+  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioTrack);
+  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetVideoTrack);
+  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioAndVideoTrack);
+  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetTrackRemoveStreamAndGCAll);
+  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest,
+                           GetTrackRemoveStreamAndGCWithPersistentComponent);
+  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest,
+                           GetTrackRemoveStreamAndGCWithPersistentStream);
 
   typedef Function<bool()> BoolFunction;
   class EventWrapper : public GarbageCollectedFinalized<EventWrapper> {
@@ -239,12 +246,6 @@
   void ScheduleDispatchEvent(Event*, std::unique_ptr<BoolFunction>);
   void DispatchScheduledEvent();
   MediaStreamTrack* GetTrack(const WebMediaStreamTrack& web_track) const;
-  // Senders and receivers returned by the handler are in use by the peer
-  // connection, a sender or receiver that is no longer in use is permanently
-  // inactive and does not need to be referenced anymore. These methods removes
-  // such senders/receivers from |rtp_senders_|/|rtp_receivers_|.
-  void RemoveInactiveSenders();
-  void RemoveInactiveReceivers();
 
   void ChangeSignalingState(WebRTCPeerConnectionHandlerClient::SignalingState);
   void ChangeIceGatheringState(
@@ -273,8 +274,8 @@
   // |rtp_receivers_|.
   HeapHashMap<WeakMember<MediaStreamComponent>, WeakMember<MediaStreamTrack>>
       tracks_;
-  HeapHashMap<uintptr_t, Member<RTCRtpSender>> rtp_senders_;
-  HeapHashMap<uintptr_t, Member<RTCRtpReceiver>> rtp_receivers_;
+  HeapHashMap<uintptr_t, WeakMember<RTCRtpSender>> rtp_senders_;
+  HeapHashMap<uintptr_t, WeakMember<RTCRtpReceiver>> rtp_receivers_;
 
   std::unique_ptr<WebRTCPeerConnectionHandler> peer_handler_;
 
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionTest.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionTest.cpp
index 2530a422..7346788 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionTest.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionTest.cpp
@@ -70,11 +70,6 @@
     EXPECT_EQ("", GetExceptionMessage(scope));
   }
 
-  MediaStreamTrack* GetTrack(RTCPeerConnection* pc,
-                             MediaStreamComponent* component) {
-    return pc->GetTrack(component);
-  }
-
  private:
   ScopedTestingPlatformSupport<TestingPlatformSupportWithWebRTC> platform;
 };
@@ -93,9 +88,9 @@
       MediaStream::Create(scope.GetExecutionContext(), tracks);
   ASSERT_TRUE(stream);
 
-  EXPECT_FALSE(GetTrack(pc, track->Component()));
+  EXPECT_FALSE(pc->GetTrack(track->Component()));
   AddStream(scope, pc, stream);
-  EXPECT_TRUE(GetTrack(pc, track->Component()));
+  EXPECT_TRUE(pc->GetTrack(track->Component()));
 }
 
 TEST_F(RTCPeerConnectionTest, GetVideoTrack) {
@@ -112,9 +107,9 @@
       MediaStream::Create(scope.GetExecutionContext(), tracks);
   ASSERT_TRUE(stream);
 
-  EXPECT_FALSE(GetTrack(pc, track->Component()));
+  EXPECT_FALSE(pc->GetTrack(track->Component()));
   AddStream(scope, pc, stream);
-  EXPECT_TRUE(GetTrack(pc, track->Component()));
+  EXPECT_TRUE(pc->GetTrack(track->Component()));
 }
 
 TEST_F(RTCPeerConnectionTest, GetAudioAndVideoTrack) {
@@ -135,11 +130,11 @@
       MediaStream::Create(scope.GetExecutionContext(), tracks);
   ASSERT_TRUE(stream);
 
-  EXPECT_FALSE(GetTrack(pc, audio_track->Component()));
-  EXPECT_FALSE(GetTrack(pc, video_track->Component()));
+  EXPECT_FALSE(pc->GetTrack(audio_track->Component()));
+  EXPECT_FALSE(pc->GetTrack(video_track->Component()));
   AddStream(scope, pc, stream);
-  EXPECT_TRUE(GetTrack(pc, audio_track->Component()));
-  EXPECT_TRUE(GetTrack(pc, video_track->Component()));
+  EXPECT_TRUE(pc->GetTrack(audio_track->Component()));
+  EXPECT_TRUE(pc->GetTrack(video_track->Component()));
 }
 
 TEST_F(RTCPeerConnectionTest, GetTrackRemoveStreamAndGCAll) {
@@ -158,16 +153,16 @@
 
   MediaStreamComponent* track_component = track->Component();
 
-  EXPECT_FALSE(GetTrack(pc, track_component));
+  EXPECT_FALSE(pc->GetTrack(track_component));
   AddStream(scope, pc, stream);
-  EXPECT_TRUE(GetTrack(pc, track_component));
+  EXPECT_TRUE(pc->GetTrack(track_component));
 
   RemoveStream(scope, pc, stream);
   // This will destroy |MediaStream|, |MediaStreamTrack| and its
   // |MediaStreamComponent|, which will remove its mapping from the peer
   // connection.
   WebHeap::CollectAllGarbageForTesting();
-  EXPECT_FALSE(GetTrack(pc, track_component));
+  EXPECT_FALSE(pc->GetTrack(track_component));
 }
 
 TEST_F(RTCPeerConnectionTest,
@@ -187,16 +182,16 @@
 
   Persistent<MediaStreamComponent> track_component = track->Component();
 
-  EXPECT_FALSE(GetTrack(pc, track_component));
+  EXPECT_FALSE(pc->GetTrack(track_component.Get()));
   AddStream(scope, pc, stream);
-  EXPECT_TRUE(GetTrack(pc, track_component));
+  EXPECT_TRUE(pc->GetTrack(track_component.Get()));
 
   RemoveStream(scope, pc, stream);
   // This will destroy |MediaStream| and |MediaStreamTrack| (but not
   // |MediaStreamComponent|), which will remove its mapping from the peer
   // connection.
   WebHeap::CollectAllGarbageForTesting();
-  EXPECT_FALSE(GetTrack(pc, track_component));
+  EXPECT_FALSE(pc->GetTrack(track_component.Get()));
 }
 
 TEST_F(RTCPeerConnectionTest, GetTrackRemoveStreamAndGCWithPersistentStream) {
@@ -215,22 +210,22 @@
 
   MediaStreamComponent* track_component = track->Component();
 
-  EXPECT_FALSE(GetTrack(pc, track_component));
+  EXPECT_FALSE(pc->GetTrack(track_component));
   AddStream(scope, pc, stream);
-  EXPECT_TRUE(GetTrack(pc, track_component));
+  EXPECT_TRUE(pc->GetTrack(track_component));
 
   RemoveStream(scope, pc, stream);
   // With a persistent |MediaStream|, the |MediaStreamTrack| and
   // |MediaStreamComponent| will not be destroyed and continue to be mapped by
   // peer connection.
   WebHeap::CollectAllGarbageForTesting();
-  EXPECT_TRUE(GetTrack(pc, track_component));
+  EXPECT_TRUE(pc->GetTrack(track_component));
 
   stream = nullptr;
   // Now |MediaStream|, |MediaStreamTrack| and |MediaStreamComponent| will be
   // destroyed and the mapping removed from the peer connection.
   WebHeap::CollectAllGarbageForTesting();
-  EXPECT_FALSE(GetTrack(pc, track_component));
+  EXPECT_FALSE(pc->GetTrack(track_component));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp b/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp
index 829bf44..3cc1380 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp
+++ b/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp
@@ -30,6 +30,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/plugins/PluginData.h"
 #include "platform/wtf/Vector.h"
+#include "platform/wtf/debug/Alias.h"
 #include "platform/wtf/text/AtomicString.h"
 
 namespace blink {
@@ -53,6 +54,24 @@
     return nullptr;
 
   // TODO(lfg): Temporary to track down https://crbug.com/731239.
+  if (!GetPluginData()) {
+    LocalFrame* frame = GetFrame();
+    LocalFrameClient* client = GetFrame()->Client();
+    Settings* settings = GetFrame()->GetSettings();
+    ExecutionContext* context = GetExecutionContext();
+    Page* page = GetFrame()->GetPage();
+    bool allow_plugins =
+        frame->Loader().AllowPlugins(kNotAboutToInstantiatePlugin);
+
+    CHECK(false);
+
+    WTF::debug::Alias(frame);
+    WTF::debug::Alias(client);
+    WTF::debug::Alias(settings);
+    WTF::debug::Alias(context);
+    WTF::debug::Alias(page);
+    WTF::debug::Alias(&allow_plugins);
+  }
   CHECK(main_frame_origin_->IsSameSchemeHostPort(GetPluginData()->Origin()));
 
   if (!dom_plugins_[index]) {
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index 2377771..2cc1805 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -95,6 +95,7 @@
       draws_content_(false),
       contents_visible_(true),
       is_root_for_isolated_group_(false),
+      should_hit_test_(false),
       has_scroll_parent_(false),
       has_clip_parent_(false),
       painted_(false),
@@ -996,6 +997,13 @@
   PlatformLayer()->SetIsRootForIsolatedGroup(isolated);
 }
 
+void GraphicsLayer::SetShouldHitTest(bool hit_test) {
+  if (should_hit_test_ == hit_test)
+    return;
+  should_hit_test_ = hit_test;
+  PlatformLayer()->SetShouldHitTest(hit_test);
+}
+
 void GraphicsLayer::SetContentsNeedsDisplay() {
   if (WebLayer* contents_layer = ContentsLayerIfRegistered()) {
     contents_layer->Invalidate();
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index 3554391..c5a020b 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -179,6 +179,8 @@
   void SetBlendMode(WebBlendMode);
   void SetIsRootForIsolatedGroup(bool);
 
+  void SetShouldHitTest(bool);
+
   void SetFilters(CompositorFilterOperations);
   void SetBackdropFilters(CompositorFilterOperations);
 
@@ -349,6 +351,7 @@
   bool draws_content_ : 1;
   bool contents_visible_ : 1;
   bool is_root_for_isolated_group_ : 1;
+  bool should_hit_test_ : 1;
 
   bool has_scroll_parent_ : 1;
   bool has_clip_parent_ : 1;
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FEMerge.cpp b/third_party/WebKit/Source/platform/graphics/filters/FEMerge.cpp
index 26c43b4..a02da66 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FEMerge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FEMerge.cpp
@@ -46,7 +46,7 @@
         InputEffect(i), OperatingInterpolationSpace());
   }
   SkImageFilter::CropRect rect = GetCropRect();
-  return SkMergeImageFilter::MakeN(input_refs.get(), size, nullptr, &rect);
+  return SkMergeImageFilter::Make(input_refs.get(), size, &rect);
 }
 
 TextStream& FEMerge::ExternalRepresentation(TextStream& ts, int indent) const {
diff --git a/third_party/WebKit/public/platform/WebLayer.h b/third_party/WebKit/public/platform/WebLayer.h
index dc6efa8..12a7329 100644
--- a/third_party/WebKit/public/platform/WebLayer.h
+++ b/third_party/WebKit/public/platform/WebLayer.h
@@ -97,6 +97,9 @@
   virtual void SetIsRootForIsolatedGroup(bool) = 0;
   virtual bool IsRootForIsolatedGroup() = 0;
 
+  virtual void SetShouldHitTest(bool) = 0;
+  virtual bool ShouldHitTest() = 0;
+
   virtual void SetOpaque(bool) = 0;
   virtual bool Opaque() const = 0;
 
diff --git a/tools/android/kerberos/README.md b/tools/android/kerberos/README.md
index 4daa473..6ce9639 100644
--- a/tools/android/kerberos/README.md
+++ b/tools/android/kerberos/README.md
@@ -35,7 +35,7 @@
     The policies to set are:
 
      *   AuthServerWhitelist: `*`
-     *   AuthSpnegoAccountType: `org.chromium.tools.SpnegoAuthenticator`
+     *   AuthAndroidNegotiateAccountType: `org.chromium.tools.SpnegoAuthenticator`
 
     To set them you have to be able to set restrictions for apps on the device.
     This can be achieved using the TestDPC app ([Play store][testdpc-play],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index ab2f840..8a295e5 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -22021,6 +22021,7 @@
   <int value="-1963427770" label="EmojiHandwritingVoiceInput:disabled"/>
   <int value="-1963402827" label="enable-topchrome-md"/>
   <int value="-1961648833" label="show_summary"/>
+  <int value="-1960567385" label="KeepPrefetchedContentSuggestions:enabled"/>
   <int value="-1956349722" label="disable-smooth-scrolling"/>
   <int value="-1948540128" label="disable-webrtc-hw-encoding (deprecated)"/>
   <int value="-1946595906" label="enable-push-api-background-mode"/>
@@ -22131,6 +22132,7 @@
   <int value="-1617183455" label="OfflineRecentPages:disabled"/>
   <int value="-1616855537" label="enable-manual-password-generation:disabled"/>
   <int value="-1614912400" label="enable-link-disambiguation-popup"/>
+  <int value="-1611305202" label="KeepPrefetchedContentSuggestions:disabled"/>
   <int value="-1605567628" label="disable-overlay-scrollbar"/>
   <int value="-1604051051" label="SpecialLocale:disabled"/>
   <int value="-1599538279" label="enable-md-policy-page"/>
diff --git a/tools/roll_webrtc.py b/tools/roll_webrtc.py
index 543075f..0f2f56f 100755
--- a/tools/roll_webrtc.py
+++ b/tools/roll_webrtc.py
@@ -269,7 +269,8 @@
     readme.write(m)
     readme.truncate()
 
-  def PrepareRoll(self, dry_run, ignore_checks, no_commit, close_previous_roll):
+  def PrepareRoll(self, dry_run, ignore_checks, no_commit, close_previous_roll,
+                  revision):
     # TODO(kjellander): use os.path.normcase, os.path.join etc for all paths for
     # cross platform compatibility.
 
@@ -298,21 +299,22 @@
     deps = _ParseDepsFile(deps_filename)
     webrtc_current = self._GetDepsCommitInfo(deps, WEBRTC_PATH)
 
-    # Find ToT revisions.
-    webrtc_latest = self._GetCommitInfo(WEBRTC_PATH)
+    # Get the commit info for the given revision. If it's None, get the commit
+    # info for ToT.
+    revision_info = self._GetCommitInfo(WEBRTC_PATH, revision)
 
     if IS_WIN:
       # Make sure the roll script doesn't use Windows line endings.
       self._RunCommand(['git', 'config', 'core.autocrlf', 'true'])
 
-    self._UpdateDep(deps_filename, WEBRTC_PATH, webrtc_latest)
+    self._UpdateDep(deps_filename, WEBRTC_PATH, revision_info)
 
     if self._IsTreeClean():
       print 'The latest revision is already rolled for WebRTC.'
       self._DeleteRollBranch()
     else:
       description = self._GenerateCLDescriptionCommand(
-        webrtc_current, webrtc_latest)
+        webrtc_current, revision_info)
       logging.debug('Committing changes locally.')
       self._RunCommand(['git', 'add', '--update', '.'])
       self._RunCommand(['git', 'commit', '-m', description])
@@ -414,6 +416,9 @@
       help=('Skips checks for being on the master branch, dirty workspaces and '
             'the updating of the checkout. Will still delete and create local '
             'Git branches.'))
+  parser.add_argument('-r', '--revision', default=None,
+                      help='WebRTC revision to roll. If not specified,'
+                           'the latest version will be used')
   parser.add_argument('-v', '--verbose', action='store_true', default=False,
       help='Be extra verbose in printing of log messages.')
   args = parser.parse_args()
@@ -430,7 +435,8 @@
     return autoroller.WaitForTrybots()
   else:
     return autoroller.PrepareRoll(args.dry_run, args.ignore_checks,
-                                  args.no_commit, args.close_previous_roll)
+                                  args.no_commit, args.close_previous_roll,
+                                  args.revision)
 
 if __name__ == '__main__':
   sys.exit(main())