diff --git a/DEPS b/DEPS
index db2158c..df45fdc 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '1b0126b01511fe23d6e8f7b5be402d4d81921245',
+  'skia_revision': '3f93b7265f558c414d0f33a7771be52b1fd1ce61',
   # 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': '175a595935ba451d675245238d3c2f9ba7075cbc',
+  'v8_revision': '13d38e4a87153ab3b0a8d0612ea1c7ee3f664d77',
   # 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.
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 14c0548..e1677842 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -740,7 +740,7 @@
   root_window_layout_manager_->OnWindowResized();
   if (root_window_type == RootWindowType::PRIMARY) {
     if (Shell::GetAshConfig() != Config::MASH)
-      shell->InitKeyboard();
+      shell->CreateKeyboard();
   } else {
     window_tree_host_->Show();
 
diff --git a/ash/shell.cc b/ash/shell.cc
index fdc5bff..6eb191a 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -354,12 +354,27 @@
 }
 
 void Shell::CreateKeyboard() {
-  InitKeyboard();
+  if (keyboard::IsKeyboardEnabled()) {
+    if (keyboard::KeyboardController::GetInstance()) {
+      RootWindowControllerList controllers = GetAllRootWindowControllers();
+      for (RootWindowControllerList::iterator iter = controllers.begin();
+           iter != controllers.end(); ++iter) {
+        (*iter)->DeactivateKeyboard(
+            keyboard::KeyboardController::GetInstance());
+      }
+    }
+    keyboard::KeyboardController::ResetInstance(
+        new keyboard::KeyboardController(shell_delegate_->CreateKeyboardUI(),
+                                         virtual_keyboard_controller_.get()));
+    for (auto& observer : shell_observers_)
+      observer.OnKeyboardControllerCreated();
+  }
+
   GetPrimaryRootWindowController()->ActivateKeyboard(
       keyboard::KeyboardController::GetInstance());
 }
 
-void Shell::DeactivateKeyboard() {
+void Shell::DestroyKeyboard() {
   // TODO(jamescook): Move keyboard create and hide into ShellPort.
   keyboard_ui_->Hide();
   if (keyboard::KeyboardController::GetInstance()) {
@@ -672,7 +687,7 @@
 
   // Destroy the keyboard before closing the shelf, since it will invoke a shelf
   // layout.
-  DeactivateKeyboard();
+  DestroyKeyboard();
 
   toast_manager_.reset();
 
@@ -1126,24 +1141,6 @@
     user_metrics_recorder_->OnShellInitialized();
 }
 
-void Shell::InitKeyboard() {
-  if (keyboard::IsKeyboardEnabled()) {
-    if (keyboard::KeyboardController::GetInstance()) {
-      RootWindowControllerList controllers = GetAllRootWindowControllers();
-      for (RootWindowControllerList::iterator iter = controllers.begin();
-           iter != controllers.end(); ++iter) {
-        (*iter)->DeactivateKeyboard(
-            keyboard::KeyboardController::GetInstance());
-      }
-    }
-    keyboard::KeyboardController::ResetInstance(
-        new keyboard::KeyboardController(shell_delegate_->CreateKeyboardUI(),
-                                         virtual_keyboard_controller_.get()));
-    for (auto& observer : shell_observers_)
-      observer.OnKeyboardControllerCreated();
-  }
-}
-
 void Shell::InitRootWindow(aura::Window* root_window) {
   DCHECK(focus_controller_);
   DCHECK(visibility_controller_.get());
diff --git a/ash/shell.h b/ash/shell.h
index 749e17e..fa34265 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -284,12 +284,12 @@
   // Called when a root window is created.
   void OnRootWindowAdded(aura::Window* root_window);
 
-  // Creates a virtual keyboard. Deletes the old virtual keyboard if it already
-  // exists.
+  // Creates a keyboard controller and associate it with the primary root window
+  // controller. Destroys the old keyboard controller if it already exists.
   void CreateKeyboard();
 
-  // Deactivates the virtual keyboard.
-  void DeactivateKeyboard();
+  // Destroys the virtual keyboard.
+  void DestroyKeyboard();
 
   // Test if MaximizeModeWindowManager is not enabled, and if
   // MaximizeModeController is not currently setting a display rotation. Or if
@@ -623,9 +623,6 @@
 
   void Init(const ShellInitParams& init_params);
 
-  // Initializes virtual keyboard controller.
-  void InitKeyboard();
-
   // Initializes the root window so that it can host browser windows.
   void InitRootWindow(aura::Window* root_window);
 
diff --git a/ash/virtual_keyboard_controller.cc b/ash/virtual_keyboard_controller.cc
index 671c174a8..f60412bf 100644
--- a/ash/virtual_keyboard_controller.cc
+++ b/ash/virtual_keyboard_controller.cc
@@ -212,7 +212,7 @@
   if (is_enabled) {
     Shell::Get()->CreateKeyboard();
   } else {
-    Shell::Get()->DeactivateKeyboard();
+    Shell::Get()->DestroyKeyboard();
   }
 }
 
diff --git a/base/logging.cc b/base/logging.cc
index 70e928a..11ed652 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -87,8 +87,9 @@
 VlogInfo* g_vlog_info = nullptr;
 VlogInfo* g_vlog_info_prev = nullptr;
 
-const char* const log_severity_names[LOG_NUM_SEVERITIES] = {
-  "INFO", "WARNING", "ERROR", "FATAL" };
+const char* const log_severity_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
+static_assert(LOG_NUM_SEVERITIES == arraysize(log_severity_names),
+              "Incorrect number of log_severity_names");
 
 const char* log_severity_name(int severity) {
   if (severity >= 0 && severity < LOG_NUM_SEVERITIES)
diff --git a/base/logging.h b/base/logging.h
index 96ef7c3..ccfb62a2 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -206,7 +206,7 @@
 // whether NDEBUG is defined or not so that we'll fail to link if someone tries
 // to compile logging.cc with NDEBUG but includes logging.h without defining it,
 // or vice versa.
-#if NDEBUG
+#if defined(NDEBUG)
 #define BaseInitLoggingImpl BaseInitLoggingImpl_built_with_NDEBUG
 #else
 #define BaseInitLoggingImpl BaseInitLoggingImpl_built_without_NDEBUG
@@ -337,7 +337,7 @@
 const LogSeverity LOG_NUM_SEVERITIES = 4;
 
 // LOG_DFATAL is LOG_FATAL in debug mode, ERROR in normal mode
-#ifdef NDEBUG
+#if defined(NDEBUG)
 const LogSeverity LOG_DFATAL = LOG_ERROR;
 #else
 const LogSeverity LOG_DFATAL = LOG_FATAL;
@@ -804,7 +804,7 @@
 #if DCHECK_IS_ON()
 
 #define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \
-  COMPACT_GOOGLE_LOG_EX_FATAL(ClassName , ##__VA_ARGS__)
+  COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ##__VA_ARGS__)
 #define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_FATAL
 const LogSeverity LOG_DCHECK = LOG_FATAL;
 
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index 5cb3d05..0a1fed40 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -35,14 +35,14 @@
 using ::testing::_;
 
 // Needs to be global since log assert handlers can't maintain state.
-int log_sink_call_count = 0;
+int g_log_sink_call_count = 0;
 
 #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG)
 void LogSink(const char* file,
              int line,
              const base::StringPiece message,
              const base::StringPiece stack_trace) {
-  ++log_sink_call_count;
+  ++g_log_sink_call_count;
 }
 #endif
 
@@ -54,7 +54,7 @@
 
   ~LogStateSaver() {
     SetMinLogLevel(old_min_log_level_);
-    log_sink_call_count = 0;
+    g_log_sink_call_count = 0;
   }
 
  private:
@@ -145,7 +145,7 @@
   EXPECT_FALSE(LOG_IS_ON(WARNING));
   EXPECT_FALSE(LOG_IS_ON(ERROR));
   EXPECT_TRUE(LOG_IS_ON(FATAL));
-  EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
+  EXPECT_EQ(kDfatalIsFatal, LOG_IS_ON(DFATAL));
 }
 
 TEST_F(LoggingTest, LoggingIsLazyBySeverity) {
@@ -371,7 +371,7 @@
 #endif  // OS_POSIX
 
 TEST_F(LoggingTest, DebugLoggingReleaseBehavior) {
-#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+#if DCHECK_IS_ON()
   int debug_only_variable = 1;
 #endif
   // These should avoid emitting references to |debug_only_variable|
@@ -428,33 +428,33 @@
   EXPECT_TRUE(DLOG_IS_ON(DCHECK));
 #endif
 
-  EXPECT_EQ(0, log_sink_call_count);
+  EXPECT_EQ(0, g_log_sink_call_count);
   DCHECK(false);
-  EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
+  EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
   DPCHECK(false);
-  EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count);
+  EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count);
   DCHECK_EQ(0, 1);
-  EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count);
+  EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, g_log_sink_call_count);
 
   // Test DCHECK on std::nullptr_t
-  log_sink_call_count = 0;
+  g_log_sink_call_count = 0;
   const void* p_null = nullptr;
   const void* p_not_null = &p_null;
   DCHECK_EQ(p_null, nullptr);
   DCHECK_EQ(nullptr, p_null);
   DCHECK_NE(p_not_null, nullptr);
   DCHECK_NE(nullptr, p_not_null);
-  EXPECT_EQ(0, log_sink_call_count);
+  EXPECT_EQ(0, g_log_sink_call_count);
 
   // Test DCHECK on a scoped enum.
   enum class Animal { DOG, CAT };
   DCHECK_EQ(Animal::DOG, Animal::DOG);
-  EXPECT_EQ(0, log_sink_call_count);
+  EXPECT_EQ(0, g_log_sink_call_count);
   DCHECK_EQ(Animal::DOG, Animal::CAT);
-  EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
+  EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
 
   // Test DCHECK on functions and function pointers.
-  log_sink_call_count = 0;
+  g_log_sink_call_count = 0;
   struct MemberFunctions {
     void MemberFunction1() {
       // See the comment in DcheckEmptyFunction1().
@@ -468,15 +468,15 @@
   void (*fp2)() = DcheckEmptyFunction2;
   void (*fp3)() = DcheckEmptyFunction1;
   DCHECK_EQ(fp1, fp3);
-  EXPECT_EQ(0, log_sink_call_count);
+  EXPECT_EQ(0, g_log_sink_call_count);
   DCHECK_EQ(mp1, &MemberFunctions::MemberFunction1);
-  EXPECT_EQ(0, log_sink_call_count);
+  EXPECT_EQ(0, g_log_sink_call_count);
   DCHECK_EQ(mp2, &MemberFunctions::MemberFunction2);
-  EXPECT_EQ(0, log_sink_call_count);
+  EXPECT_EQ(0, g_log_sink_call_count);
   DCHECK_EQ(fp1, fp2);
-  EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
+  EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
   DCHECK_EQ(mp2, &MemberFunctions::MemberFunction1);
-  EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count);
+  EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count);
 }
 
 TEST_F(LoggingTest, DcheckReleaseBehavior) {
diff --git a/base/syslog_logging.cc b/base/syslog_logging.cc
index 087b4fd..aff90a4 100644
--- a/base/syslog_logging.cc
+++ b/base/syslog_logging.cc
@@ -12,7 +12,10 @@
 
 #include <windows.h>
 #elif defined(OS_LINUX)
+// <syslog.h> defines a LOG_WARNING macro that could conflict with
+// base::LOG_WARNING.
 #include <syslog.h>
+#undef LOG_WARNING
 #endif
 
 #include <cstring>
diff --git a/base/test/gtest_util.h b/base/test/gtest_util.h
index 8dfb1f2..569e39b 100644
--- a/base/test/gtest_util.h
+++ b/base/test/gtest_util.h
@@ -38,18 +38,18 @@
 // conditions in which it's needed here.
 // TODO(gab): Expose macro in upstream gtest repo for consumers like us that
 // want more specific death tests and remove this hack.
-# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
-    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
-    if (::testing::internal::AlwaysTrue()) { \
-      GTEST_LOG_(WARNING) \
-          << "Death tests are not supported on this platform.\n" \
-          << "Statement '" #statement "' cannot be verified."; \
-    } else if (::testing::internal::AlwaysFalse()) { \
-      ::testing::internal::RE::PartialMatch(".*", (regex)); \
-      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
-      terminator; \
-    } else \
-      ::testing::Message()
+#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator)  \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                     \
+  if (::testing::internal::AlwaysTrue()) {                          \
+    GTEST_LOG_(WARNING)                                             \
+        << "Death tests are not supported in this configuration.\n" \
+        << "Statement '" #statement "' cannot be verified.";        \
+  } else if (::testing::internal::AlwaysFalse()) {                  \
+    ::testing::internal::RE::PartialMatch(".*", (regex));           \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);      \
+    terminator;                                                     \
+  } else                                                            \
+    ::testing::Message()
 
 #define EXPECT_DCHECK_DEATH(statement) \
     GTEST_UNSUPPORTED_DEATH_TEST(statement, "Check failed", )
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index 3e7f7a1e..bd8c325e 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -190,37 +190,51 @@
   g_instance_for_testing = nullptr;
 }
 
+// static
+HeapProfilingMode MemoryDumpManager::GetHeapProfilingModeFromCommandLine() {
+  if (!CommandLine::InitializedForCurrentProcess() ||
+      !CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableHeapProfiling)) {
+    return kHeapProfilingModeNone;
+  }
+#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
+  std::string profiling_mode =
+      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kEnableHeapProfiling);
+  if (profiling_mode == switches::kEnableHeapProfilingModePseudo)
+    return kHeapProfilingModePseudo;
+  if (profiling_mode == switches::kEnableHeapProfilingModeNative)
+    return kHeapProfilingModeNative;
+  if (profiling_mode == switches::kEnableHeapProfilingTaskProfiler &&
+      base::debug::ThreadHeapUsageTracker::IsHeapTrackingEnabled()) {
+    return kHeapProfilingModeTaskProfiler;
+  }
+#endif  // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
+  return kHeapProfilingModeInvalid;
+}
+
 void MemoryDumpManager::EnableHeapProfilingIfNeeded() {
   if (heap_profiling_enabled_)
     return;
 
-  if (!CommandLine::InitializedForCurrentProcess() ||
-      !CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableHeapProfiling))
-    return;
-
-  std::string profiling_mode = CommandLine::ForCurrentProcess()
-      ->GetSwitchValueASCII(switches::kEnableHeapProfiling);
-  if (profiling_mode == switches::kEnableHeapProfilingModePseudo) {
-    AllocationContextTracker::SetCaptureMode(
-        AllocationContextTracker::CaptureMode::PSEUDO_STACK);
-#if !defined(OS_NACL)
-  } else if (profiling_mode == switches::kEnableHeapProfilingModeNative) {
-    // If we don't have frame pointers then native tracing falls-back to
-    // using base::debug::StackTrace, which may be slow.
-    AllocationContextTracker::SetCaptureMode(
-        AllocationContextTracker::CaptureMode::NATIVE_STACK);
-#endif  // !defined(OS_NACL)
-#if BUILDFLAG(USE_ALLOCATOR_SHIM)
-  } else if (profiling_mode == switches::kEnableHeapProfilingTaskProfiler) {
-    // Enable heap tracking, which in turn enables capture of heap usage
-    // tracking in tracked_objects.cc.
-    if (!base::debug::ThreadHeapUsageTracker::IsHeapTrackingEnabled())
+  HeapProfilingMode profiling_mode = GetHeapProfilingModeFromCommandLine();
+  switch (profiling_mode) {
+    case kHeapProfilingModeNone:
+    case kHeapProfilingModeInvalid:
+      return;
+    case kHeapProfilingModePseudo:
+      AllocationContextTracker::SetCaptureMode(
+          AllocationContextTracker::CaptureMode::PSEUDO_STACK);
+      break;
+    case kHeapProfilingModeNative:
+      // If we don't have frame pointers then native tracing falls-back to
+      // using base::debug::StackTrace, which may be slow.
+      AllocationContextTracker::SetCaptureMode(
+          AllocationContextTracker::CaptureMode::NATIVE_STACK);
+      break;
+    case kHeapProfilingModeTaskProfiler:
       base::debug::ThreadHeapUsageTracker::EnableHeapTracking();
-#endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
-  } else {
-    LOG(FATAL) << "Invalid mode '" << profiling_mode << "' for "
-               << switches::kEnableHeapProfiling << " flag.";
+      break;
   }
 
   for (auto mdp : dump_providers_)
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h
index 0e2af24..f51df48a 100644
--- a/base/trace_event/memory_dump_manager.h
+++ b/base/trace_event/memory_dump_manager.h
@@ -36,6 +36,14 @@
 class MemoryDumpProvider;
 class HeapProfilerSerializationState;
 
+enum HeapProfilingMode {
+  kHeapProfilingModeNone,
+  kHeapProfilingModePseudo,
+  kHeapProfilingModeNative,
+  kHeapProfilingModeTaskProfiler,
+  kHeapProfilingModeInvalid
+};
+
 // This is the interface exposed to the rest of the codebase to deal with
 // memory tracing. The main entry point for clients is represented by
 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider).
@@ -137,7 +145,12 @@
   void CreateProcessDump(const MemoryDumpRequestArgs& args,
                          const ProcessMemoryDumpCallback& callback);
 
-  // Enable heap profiling if kEnableHeapProfiling is specified.
+  // Returns the heap profiling mode configured on the command-line, if any.
+  // If heap profiling is configured but not supported by this binary, or if an
+  // invalid mode is specified, then kHeapProfilingInvalid is returned.
+  static HeapProfilingMode GetHeapProfilingModeFromCommandLine();
+
+  // Enable heap profiling if supported, and kEnableHeapProfiling is specified.
   void EnableHeapProfilingIfNeeded();
 
   // Lets tests see if a dump provider is registered.
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index bb48708b..0e191073 100755
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -23,7 +23,7 @@
 
 
 # Use MSVS2015 as the default toolchain.
-CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2017'
+CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2015'
 
 
 def SetEnvironmentAndGetRuntimeDllDirs():
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a8df1b8..2607db9c 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5208,6 +5208,11 @@
         usage statistics
       </message>
 
+      <!-- Unimplemented Flags Info Bar-->
+      <message name="IDS_UNIMPLEMENTED_FLAGS_WARNING_MESSAGE" desc="Message shown when a command-line flag is used that is not implemented by this build. [Keep it short so it fits in the infobar.]">
+        <ph name="BAD_FLAG">$1<ex>--enable-heap-profiling</ex></ph> is not implemented in this build.
+      </message>
+
       <!-- Bad Flags Info Bar-->
       <message name="IDS_BAD_FLAGS_WARNING_MESSAGE" desc="Message shown when an unsupported command-line flag is used. [Keep it short so it fits in the infobar.]">
         You are using an unsupported command-line flag: <ph name="BAD_FLAG">$1<ex>--no-sandbox</ex></ph>. Stability and security will suffer.
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
index d6d1cc3..f39cbaa 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -802,7 +802,7 @@
     if (keyboard::IsKeyboardEnabled())
       ash::Shell::Get()->CreateKeyboard();
     else
-      ash::Shell::Get()->DeactivateKeyboard();
+      ash::Shell::Get()->DestroyKeyboard();
   } else {
     // TODO(mash): Support on-screen keyboard. See http://crbug.com/646565
     NOTIMPLEMENTED();
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
index c110da5..004743f 100644
--- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
+++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -191,7 +191,7 @@
   if (is_enabled)
     ash::Shell::Get()->CreateKeyboard();
   else
-    ash::Shell::Get()->DeactivateKeyboard();
+    ash::Shell::Get()->DestroyKeyboard();
   return true;
 }
 
diff --git a/chrome/browser/search/suggestions/suggestions_service_factory.cc b/chrome/browser/search/suggestions/suggestions_service_factory.cc
index aa3bc29..dd054a2 100644
--- a/chrome/browser/search/suggestions/suggestions_service_factory.cc
+++ b/chrome/browser/search/suggestions/suggestions_service_factory.cc
@@ -65,7 +65,7 @@
     content::BrowserContext* context) const {
   scoped_refptr<base::SequencedTaskRunner> background_task_runner =
       base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::BACKGROUND});
+          {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
 
   Profile* profile = static_cast<Profile*>(context);
 
@@ -91,9 +91,8 @@
       new ImageFetcherImpl(
           base::MakeUnique<suggestions::ImageDecoderImpl>(),
           profile->GetRequestContext()));
-  std::unique_ptr<ImageManager> thumbnail_manager(new ImageManager(
-      std::move(image_fetcher), std::move(db), database_dir,
-      BrowserThread::GetTaskRunnerForThread(BrowserThread::DB)));
+  std::unique_ptr<ImageManager> thumbnail_manager(
+      new ImageManager(std::move(image_fetcher), std::move(db), database_dir));
   return new SuggestionsServiceImpl(
       signin_manager, token_service, sync_service, profile->GetRequestContext(),
       std::move(suggestions_store), std::move(thumbnail_manager),
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index fd12cbc..8db0a9e 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -1048,7 +1048,7 @@
   if (!ash_util::IsRunningInMash()) {
     const bool is_enabled = keyboard::IsKeyboardEnabled();
     if (was_enabled && !is_enabled)
-      ash::Shell::Get()->DeactivateKeyboard();
+      ash::Shell::Get()->DestroyKeyboard();
     else if (is_enabled && !was_enabled)
       ash::Shell::Get()->CreateKeyboard();
   }
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc
index d24c2e68..de0b34c7 100644
--- a/chrome/browser/ui/startup/bad_flags_prompt.cc
+++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -4,9 +4,11 @@
 
 #include "chrome/browser/ui/startup/bad_flags_prompt.h"
 
+#include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/trace_event/memory_dump_manager.h"
 #include "build/build_config.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/ui/browser.h"
@@ -35,12 +37,51 @@
 
 namespace chrome {
 
+namespace {
+
+void ShowBadFlagsInfoBar(content::WebContents* web_contents,
+                         int message_id,
+                         const char* flag) {
+  std::string switch_value =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(flag);
+  if (!switch_value.empty())
+    switch_value = "=" + switch_value;
+  SimpleAlertInfoBarDelegate::Create(
+      InfoBarService::FromWebContents(web_contents),
+      infobars::InfoBarDelegate::BAD_FLAGS_PROMPT, nullptr,
+      l10n_util::GetStringFUTF16(
+          message_id,
+          base::UTF8ToUTF16(std::string("--") + flag + switch_value)),
+      false);
+}
+
+}  // namespace
+
 void ShowBadFlagsPrompt(Browser* browser) {
   content::WebContents* web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
   if (!web_contents)
     return;
 
+  // Flags only available in specific builds, for which to display a warning
+  // "the flag is not implemented in this build", if necessary.
+  struct {
+    const char* name;
+    bool is_invalid;
+  } conditional_flags[] = {
+      {switches::kEnableHeapProfiling,
+       base::trace_event::MemoryDumpManager::
+               GetHeapProfilingModeFromCommandLine() ==
+           base::trace_event::kHeapProfilingModeInvalid},
+  };
+  for (auto conditional_flag : conditional_flags) {
+    if (conditional_flag.is_invalid) {
+      ShowBadFlagsInfoBar(web_contents, IDS_UNIMPLEMENTED_FLAGS_WARNING_MESSAGE,
+                          conditional_flag.name);
+      return;
+    }
+  }
+
   // Unsupported flags for which to display a warning that "stability and
   // security will suffer".
   static const char* kBadFlags[] = {
@@ -95,20 +136,12 @@
 
     // This flag allows sites to access protected media identifiers without
     // getting the user's permission.
-    switches::kUnsafelyAllowProtectedMediaIdentifierForDomain,
-
-    NULL
+    switches::kUnsafelyAllowProtectedMediaIdentifierForDomain
   };
 
-  for (const char** flag = kBadFlags; *flag; ++flag) {
-    if (base::CommandLine::ForCurrentProcess()->HasSwitch(*flag)) {
-      SimpleAlertInfoBarDelegate::Create(
-          InfoBarService::FromWebContents(web_contents),
-          infobars::InfoBarDelegate::BAD_FLAGS_PROMPT, nullptr,
-          l10n_util::GetStringFUTF16(
-              IDS_BAD_FLAGS_WARNING_MESSAGE,
-              base::UTF8ToUTF16(std::string("--") + *flag)),
-          false);
+  for (const char* flag : kBadFlags) {
+    if (base::CommandLine::ForCurrentProcess()->HasSwitch(flag)) {
+      ShowBadFlagsInfoBar(web_contents, IDS_BAD_FLAGS_WARNING_MESSAGE, flag);
       return;
     }
   }
diff --git a/components/suggestions/image_manager.cc b/components/suggestions/image_manager.cc
index d2fb227f..321aef28 100644
--- a/components/suggestions/image_manager.cc
+++ b/components/suggestions/image_manager.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/task_runner_util.h"
+#include "base/task_scheduler/post_task.h"
 #include "components/image_fetcher/core/image_fetcher.h"
 #include "components/suggestions/image_encoder.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -82,11 +83,11 @@
 ImageManager::ImageManager(
     std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
     std::unique_ptr<ProtoDatabase<ImageData>> database,
-    const base::FilePath& database_dir,
-    scoped_refptr<base::TaskRunner> background_task_runner)
+    const base::FilePath& database_dir)
     : image_fetcher_(std::move(image_fetcher)),
       database_(std::move(database)),
-      background_task_runner_(background_task_runner),
+      background_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
+          {base::TaskPriority::USER_VISIBLE})),
       database_ready_(false),
       weak_ptr_factory_(this) {
   image_fetcher_->SetImageFetcherDelegate(this);
@@ -216,6 +217,8 @@
 void ImageManager::SaveImage(const std::string& url, const SkBitmap& bitmap) {
   scoped_refptr<base::RefCountedBytes> encoded_data(
       new base::RefCountedBytes());
+  // TODO(treib): Should encoding happen on the |background_task_runner_|?
+  // *De*coding happens there.
   if (!EncodeSkBitmapToJPEG(bitmap, &encoded_data->data())) {
     return;
   }
diff --git a/components/suggestions/image_manager.h b/components/suggestions/image_manager.h
index 20de2eea..04ffc00 100644
--- a/components/suggestions/image_manager.h
+++ b/components/suggestions/image_manager.h
@@ -47,8 +47,7 @@
   ImageManager(
       std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
       std::unique_ptr<leveldb_proto::ProtoDatabase<ImageData>> database,
-      const base::FilePath& database_dir,
-      scoped_refptr<base::TaskRunner> background_task_runner);
+      const base::FilePath& database_dir);
   ~ImageManager() override;
 
   virtual void Initialize(const SuggestionsProfile& suggestions);
diff --git a/components/suggestions/image_manager_unittest.cc b/components/suggestions/image_manager_unittest.cc
index 86717dd..5c42a290 100644
--- a/components/suggestions/image_manager_unittest.cc
+++ b/components/suggestions/image_manager_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "components/image_fetcher/core/image_fetcher.h"
 #include "components/image_fetcher/core/image_fetcher_delegate.h"
 #include "components/leveldb_proto/proto_database.h"
@@ -23,7 +22,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_skia.h"
 #include "url/gurl.h"
 
 using ::testing::Return;
@@ -129,8 +127,7 @@
     EXPECT_CALL(*mock_image_fetcher_, SetImageFetcherDelegate(_));
     return new ImageManager(base::WrapUnique(mock_image_fetcher_),
                             base::WrapUnique(fake_db),
-                            FakeDB<ImageData>::DirectoryForTestDB(),
-                            base::ThreadTaskRunnerHandle::Get());
+                            FakeDB<ImageData>::DirectoryForTestDB());
   }
 
   EntryMap db_model_;
diff --git a/content/browser/net_info_browsertest.cc b/content/browser/net_info_browsertest.cc
index e62acb5..10fb1e5 100644
--- a/content/browser/net_info_browsertest.cc
+++ b/content/browser/net_info_browsertest.cc
@@ -269,7 +269,7 @@
   EXPECT_FALSE(
       histogram_tester.GetAllSamples("NQE.RenderThreadNotified").empty());
 
-  EXPECT_EQ(network_quality_1.transport_rtt().InMilliseconds(),
+  EXPECT_EQ(network_quality_1.http_rtt().InMilliseconds(),
             RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(
       static_cast<double>(network_quality_1.downstream_throughput_kbps()) /
@@ -282,7 +282,7 @@
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_2);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(network_quality_2.transport_rtt().InMilliseconds(),
+  EXPECT_EQ(network_quality_2.http_rtt().InMilliseconds(),
             RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(
       static_cast<double>(network_quality_2.downstream_throughput_kbps()) /
@@ -310,16 +310,16 @@
   EXPECT_TRUE(embedded_test_server()->Start());
   EXPECT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
-  EXPECT_EQ(200, RunScriptExtractInt("getRtt()"));
+  EXPECT_EQ(125, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(0.300, RunScriptExtractDouble("getDownlink()"));
 
   net::nqe::internal::NetworkQuality network_quality_2(
-      base::TimeDelta::FromMilliseconds(123),
-      base::TimeDelta::FromMilliseconds(1217), 1317);
+      base::TimeDelta::FromMilliseconds(1123),
+      base::TimeDelta::FromMilliseconds(212), 1317);
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_2);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1225, RunScriptExtractInt("getRtt()"));
+  EXPECT_EQ(1125, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.325, RunScriptExtractDouble("getDownlink()"));
 
   net::nqe::internal::NetworkQuality network_quality_3(
@@ -350,7 +350,7 @@
   EXPECT_TRUE(embedded_test_server()->Start());
   EXPECT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
-  EXPECT_EQ(1200, RunScriptExtractInt("getRtt()"));
+  EXPECT_EQ(1125, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.300, RunScriptExtractDouble("getDownlink()"));
 
   // All the 3 metrics change by less than 10%. So, the observers are not
@@ -361,18 +361,18 @@
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_2);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1200, RunScriptExtractInt("getRtt()"));
+  EXPECT_EQ(1125, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.300, RunScriptExtractDouble("getDownlink()"));
 
-  // Transport RTT has changed by more than 10% from the last notified value of
+  // HTTP RTT has changed by more than 10% from the last notified value of
   // |network_quality_1|. The observers should be notified.
   net::nqe::internal::NetworkQuality network_quality_3(
-      base::TimeDelta::FromMilliseconds(1223),
-      base::TimeDelta::FromMilliseconds(2312), 1403);
+      base::TimeDelta::FromMilliseconds(2223),
+      base::TimeDelta::FromMilliseconds(1312), 1403);
   estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
       network_quality_3);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(2300, RunScriptExtractInt("getRtt()"));
+  EXPECT_EQ(2225, RunScriptExtractInt("getRtt()"));
   EXPECT_EQ(1.400, RunScriptExtractDouble("getDownlink()"));
 }
 
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 0c4cad3..5142449 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -262,6 +262,15 @@
     command_line->AppendSwitch(switches::kDisableSigninPromo);
   }
 
+  // Populate command line flag for Bookmark reordering.
+  NSString* enableBookmarkReordering =
+      [defaults stringForKey:@"EnableBookmarkReordering"];
+  if ([enableBookmarkReordering isEqualToString:@"Enabled"]) {
+    command_line->AppendSwitch(switches::kEnableBookmarkReordering);
+  } else if ([enableBookmarkReordering isEqualToString:@"Disabled"]) {
+    command_line->AppendSwitch(switches::kDisableBookmarkReordering);
+  }
+
   // Populate command line flag for the request mobile site experiment from the
   // configuration plist.
   if ([defaults boolForKey:@"RequestMobileSiteDisabled"])
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc
index 1c7fede..7c09133c 100644
--- a/ios/chrome/browser/chrome_switches.cc
+++ b/ios/chrome/browser/chrome_switches.cc
@@ -53,6 +53,9 @@
 // Disables the Suggestions UI
 const char kDisableSuggestionsUI[] = "disable-suggestions-ui";
 
+// Disables bookmark reordering.
+const char kDisableBookmarkReordering[] = "disable-bookmark-reordering";
+
 // Enables Contextual Search.
 const char kEnableContextualSearch[] = "enable-contextual-search";
 
@@ -93,6 +96,9 @@
 // Enables the Suggestions UI
 const char kEnableSuggestionsUI[] = "enable-suggestions-ui";
 
+// Enables bookmark reordering.
+const char kEnableBookmarkReordering[] = "enable-bookmark-reordering";
+
 // 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 a862788..127c7d1 100644
--- a/ios/chrome/browser/chrome_switches.h
+++ b/ios/chrome/browser/chrome_switches.h
@@ -22,6 +22,7 @@
 extern const char kDisableIOSPhysicalWeb[];
 extern const char kDisableRequestMobileSite[];
 extern const char kDisableSuggestionsUI[];
+extern const char kDisableBookmarkReordering[];
 
 extern const char kEnableContextualSearch[];
 extern const char kEnableIOSFastWebScrollViewInsets[];
@@ -36,6 +37,7 @@
 extern const char kEnableSpotlightActions[];
 extern const char kEnableIOSPhysicalWeb[];
 extern const char kEnableSuggestionsUI[];
+extern const char kEnableBookmarkReordering[];
 
 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 03d0a9dc..b91db0c6 100644
--- a/ios/chrome/browser/experimental_flags.h
+++ b/ios/chrome/browser/experimental_flags.h
@@ -100,6 +100,9 @@
 // Whether Sign-in promo is enabled.
 bool IsSigninPromoEnabled();
 
+// Whether Bookmark reordering is enabled.
+bool IsBookmarkReorderingEnabled();
+
 // Whether Google Native App Launcher is enabled.
 bool IsNativeAppLauncherEnabled();
 
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm
index e19d040b..9cb6d1a4 100644
--- a/ios/chrome/browser/experimental_flags.mm
+++ b/ios/chrome/browser/experimental_flags.mm
@@ -267,6 +267,18 @@
                           base::CompareCase::INSENSITIVE_ASCII);
 }
 
+bool IsBookmarkReorderingEnabled() {
+  // Check if the experimental flag is forced on or off.
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kEnableBookmarkReordering))
+    return true;
+  if (command_line->HasSwitch(switches::kDisableBookmarkReordering))
+    return false;
+
+  // By default, disable it.
+  return false;
+}
+
 bool IsNativeAppLauncherEnabled() {
   return [[NSUserDefaults standardUserDefaults]
       boolForKey:@"NativeAppLauncherEnabled"];
diff --git a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
index bd63303..457b5c0 100644
--- a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
+++ b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
@@ -560,6 +560,28 @@
 		</dict>
 		<dict>
 			<key>Type</key>
+			<string>PSMultiValueSpecifier</string>
+			<key>Title</key>
+			<string>Enable Bookmark Reordering</string>
+			<key>Key</key>
+			<string>EnableBookmarkReordering</string>
+			<key>DefaultValue</key>
+			<string></string>
+			<key>Values</key>
+			<array>
+				<string></string>
+				<string>Enabled</string>
+				<string>Disabled</string>
+			</array>
+			<key>Titles</key>
+			<array>
+				<string>Default</string>
+				<string>Enabled</string>
+				<string>Disabled</string>
+			</array>
+		</dict>
+		<dict>
+			<key>Type</key>
 			<string>PSGroupSpecifier</string>
 			<key>Title</key>
 			<string>Web APIs</string>
diff --git a/ios/chrome/browser/suggestions/suggestions_service_factory.mm b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
index 4d71509c..6b1c60c 100644
--- a/ios/chrome/browser/suggestions/suggestions_service_factory.mm
+++ b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
@@ -96,9 +96,8 @@
               web::WebThread::GetBlockingPool()),
           browser_state->GetRequestContext());
 
-  std::unique_ptr<ImageManager> thumbnail_manager(new ImageManager(
-      std::move(image_fetcher), std::move(db), database_dir,
-      web::WebThread::GetTaskRunnerForThread(web::WebThread::DB)));
+  std::unique_ptr<ImageManager> thumbnail_manager(
+      new ImageManager(std::move(image_fetcher), std::move(db), database_dir));
 
   return base::MakeUnique<SuggestionsServiceImpl>(
       signin_manager, token_service, sync_service,
diff --git a/mojo/edk/embedder/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc
index 262f919..45d5222e 100644
--- a/mojo/edk/embedder/entrypoints.cc
+++ b/mojo/edk/embedder/entrypoints.cc
@@ -64,8 +64,8 @@
   return g_core->CreateMessage(context, thunks, message);
 }
 
-MojoResult MojoFreeMessageImpl(MojoMessageHandle message) {
-  return g_core->FreeMessage(message);
+MojoResult MojoDestroyMessageImpl(MojoMessageHandle message) {
+  return g_core->DestroyMessage(message);
 }
 
 MojoResult MojoSerializeMessageImpl(MojoMessageHandle message) {
@@ -256,7 +256,7 @@
                                     MojoArmWatcherImpl,
                                     MojoFuseMessagePipesImpl,
                                     MojoCreateMessageImpl,
-                                    MojoFreeMessageImpl,
+                                    MojoDestroyMessageImpl,
                                     MojoSerializeMessageImpl,
                                     MojoGetSerializedMessageContentsImpl,
                                     MojoReleaseMessageContextImpl,
diff --git a/mojo/edk/js/core.cc b/mojo/edk/js/core.cc
index bf8933a..af3acf0a 100644
--- a/mojo/edk/js/core.cc
+++ b/mojo/edk/js/core.cc
@@ -144,7 +144,7 @@
 
   result = MojoSerializeMessage(message);
   if (result != MOJO_RESULT_OK && result != MOJO_RESULT_FAILED_PRECONDITION) {
-    MojoFreeMessage(message);
+    MojoDestroyMessage(message);
     gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
     dictionary.Set("result", MOJO_RESULT_ABORTED);
     return dictionary;
@@ -166,7 +166,7 @@
   }
 
   if (result != MOJO_RESULT_OK) {
-    MojoFreeMessage(message);
+    MojoDestroyMessage(message);
     gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
     dictionary.Set("result", MOJO_RESULT_ABORTED);
     return dictionary;
@@ -181,7 +181,7 @@
     memcpy(buffer.bytes(), bytes, num_bytes);
   }
 
-  MojoFreeMessage(message);
+  MojoDestroyMessage(message);
 
   gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
   dictionary.Set("result", result);
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index a9a1d90f..51782ee7 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -483,7 +483,7 @@
   return MOJO_RESULT_OK;
 }
 
-MojoResult Core::FreeMessage(MojoMessageHandle message_handle) {
+MojoResult Core::DestroyMessage(MojoMessageHandle message_handle) {
   if (!message_handle)
     return MOJO_RESULT_INVALID_ARGUMENT;
 
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h
index ca95c63a..c996cbb 100644
--- a/mojo/edk/system/core.h
+++ b/mojo/edk/system/core.h
@@ -193,7 +193,7 @@
   MojoResult CreateMessage(uintptr_t context,
                            const MojoMessageOperationThunks* thunks,
                            MojoMessageHandle* message_handle);
-  MojoResult FreeMessage(MojoMessageHandle message_handle);
+  MojoResult DestroyMessage(MojoMessageHandle message_handle);
   MojoResult SerializeMessage(MojoMessageHandle message_handle);
   MojoResult GetSerializedMessageContents(
       MojoMessageHandle message_handle,
diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc
index 13d67f89..ba831e0 100644
--- a/mojo/edk/system/core_unittest.cc
+++ b/mojo/edk/system/core_unittest.cc
@@ -211,7 +211,7 @@
   uintptr_t context;
   ASSERT_EQ(MOJO_RESULT_OK, core()->ReleaseMessageContext(message, &context));
   ASSERT_EQ(kTestMessageContext, context);
-  ASSERT_EQ(MOJO_RESULT_OK, core()->FreeMessage(message));
+  ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
 
   // |h[0]| should no longer be readable.
   hss[0] = kEmptyMojoHandleSignalsState;
@@ -248,7 +248,7 @@
   // Discard a message from |h[1]|.
   ASSERT_EQ(MOJO_RESULT_OK,
             core()->ReadMessage(h[1], &message, MOJO_READ_MESSAGE_FLAG_NONE));
-  ASSERT_EQ(MOJO_RESULT_OK, core()->FreeMessage(message));
+  ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
 
   // |h[1]| is no longer readable (and will never be).
   hss[1] = kFullMojoHandleSignalsState;
@@ -292,7 +292,7 @@
   ASSERT_EQ(MOJO_RESULT_OK,
             core()->ReleaseMessageContext(message_handle, &context));
   ASSERT_EQ(kTestMessageContext, context);
-  ASSERT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message_handle));
+  ASSERT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
 
   ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
   ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
diff --git a/mojo/edk/system/message_pipe_unittest.cc b/mojo/edk/system/message_pipe_unittest.cc
index eb15d96..c662da4c 100644
--- a/mojo/edk/system/message_pipe_unittest.cc
+++ b/mojo/edk/system/message_pipe_unittest.cc
@@ -72,7 +72,7 @@
       CHECK(bytes);
       memcpy(bytes, buffer, *num_bytes);
     }
-    CHECK_EQ(MOJO_RESULT_OK, MojoFreeMessage(message_handle));
+    CHECK_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
     return rv;
   }
 
diff --git a/mojo/edk/system/message_unittest.cc b/mojo/edk/system/message_unittest.cc
index 8078b01..e3aa8d9 100644
--- a/mojo/edk/system/message_unittest.cc
+++ b/mojo/edk/system/message_unittest.cc
@@ -47,7 +47,7 @@
     uintptr_t context;
     MojoResult rv = MojoReleaseMessageContext(handle, &context);
     DCHECK_EQ(MOJO_RESULT_OK, rv);
-    MojoFreeMessage(handle);
+    MojoDestroyMessage(handle);
     return base::WrapUnique(reinterpret_cast<T*>(context));
   }
 
@@ -144,7 +144,7 @@
 
 TEST_F(MessageTest, InvalidMessageObjects) {
   ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            MojoFreeMessage(MOJO_MESSAGE_HANDLE_INVALID));
+            MojoDestroyMessage(MOJO_MESSAGE_HANDLE_INVALID));
 
   ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
             MojoGetSerializedMessageContents(
@@ -186,15 +186,15 @@
   MojoClose(b);
 }
 
-TEST_F(MessageTest, FreeMessageWithContext) {
-  // Tests that |MojoFreeMessage()| destroys any attached context.
+TEST_F(MessageTest, DestroyMessageWithContext) {
+  // Tests that |MojoDestroyMessage()| destroys any attached context.
   bool was_deleted = false;
   auto message = base::MakeUnique<NeverSerializedMessage>(
       base::Bind([](bool* was_deleted) { *was_deleted = true; }, &was_deleted));
   MojoMessageHandle handle =
       TestMessageBase::MakeMessageHandle(std::move(message));
   EXPECT_FALSE(was_deleted);
-  EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(handle));
+  EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(handle));
   EXPECT_TRUE(was_deleted);
 }
 
@@ -367,7 +367,7 @@
                 MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE));
   EXPECT_FALSE(message_was_destroyed);
 
-  EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message_handle));
+  EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
   EXPECT_TRUE(message_was_destroyed);
 
   MojoClose(a);
@@ -400,7 +400,7 @@
   auto message_handle = TestMessageBase::MakeMessageHandle(std::move(message));
   EXPECT_EQ(MOJO_RESULT_OK, MojoSerializeMessage(message_handle));
   EXPECT_TRUE(message_was_destroyed);
-  EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message_handle));
+  EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
 
   // Serialize a message with a single handle. Freeing the message should close
   // the handle.
@@ -414,7 +414,7 @@
   message_handle = TestMessageBase::MakeMessageHandle(std::move(message));
   EXPECT_EQ(MOJO_RESULT_OK, MojoSerializeMessage(message_handle));
   EXPECT_TRUE(message_was_destroyed);
-  EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message_handle));
+  EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
   EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(pipe1.handle1.get().value(),
                                            MOJO_HANDLE_SIGNAL_PEER_CLOSED));
 
@@ -454,7 +454,7 @@
             WaitForSignals(extracted_handle, MOJO_HANDLE_SIGNAL_READABLE));
   EXPECT_EQ(kTestMessage, MojoTestBase::ReadMessage(extracted_handle));
 
-  EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message_handle));
+  EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
 }
 
 TEST_F(MessageTest, DoubleSerialize) {
@@ -486,7 +486,7 @@
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
             MojoSerializeMessage(message_handle));
 
-  EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message_handle));
+  EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
 }
 
 }  // namespace
diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
index 141acb5..b2e20f5 100644
--- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc
+++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
@@ -1375,7 +1375,7 @@
       EXPECT_EQ(MOJO_RESULT_OK,
                 MojoNotifyBadMessage(message, kFirstErrorMessage.data(),
                                      kFirstErrorMessage.size()));
-      EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
+      EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message));
 
       // Read a message from the pipe we sent to child2 and flag it as bad.
       ASSERT_EQ(MOJO_RESULT_OK, WaitForSignals(c, MOJO_HANDLE_SIGNAL_READABLE));
@@ -1384,7 +1384,7 @@
       EXPECT_EQ(MOJO_RESULT_OK,
                 MojoNotifyBadMessage(message, kSecondErrorMessage.data(),
                                      kSecondErrorMessage.size()));
-      EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
+      EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message));
 
       WriteMessage(child2, "bye");
     END_CHILD();
diff --git a/mojo/public/c/system/message_pipe.h b/mojo/public/c/system/message_pipe.h
index 58f224b..07967bf 100644
--- a/mojo/public/c/system/message_pipe.h
+++ b/mojo/public/c/system/message_pipe.h
@@ -135,7 +135,7 @@
 
   // Destroys the message object associated with |context|. This is called when
   // the message associated with |context| is either explicitly freed by
-  // |MojoFreeMessage()| or serialized for transmission across a process
+  // |MojoDestroyMessage()| or serialized for transmission across a process
   // boundary (after serialization is complete.)
   //
   // The implementation must use this to release any resources associated with
@@ -186,7 +186,7 @@
 
 // Reads the next message from a message pipe and returns a message as an opaque
 // message handle. The returned message must eventually be destroyed using
-// |MojoFreeMessage()|.
+// |MojoDestroyMessage()|.
 //
 // Message payload and handles can be accessed using
 // |MojoGetSerializedMessageContents()|.
@@ -273,7 +273,7 @@
 // Returns:
 //   |MOJO_RESULT_OK| if |message| was valid and has been freed.
 //   |MOJO_RESULT_INVALID_ARGUMENT| if |message| was not a valid message.
-MOJO_SYSTEM_EXPORT MojoResult MojoFreeMessage(MojoMessageHandle message);
+MOJO_SYSTEM_EXPORT MojoResult MojoDestroyMessage(MojoMessageHandle message);
 
 // Forces a message to be serialized in-place if not already serialized.
 //
diff --git a/mojo/public/c/system/tests/core_unittest.cc b/mojo/public/c/system/tests/core_unittest.cc
index bd8e989..170ebc9 100644
--- a/mojo/public/c/system/tests/core_unittest.cc
+++ b/mojo/public/c/system/tests/core_unittest.cc
@@ -120,7 +120,7 @@
             MojoReadMessage(h0, &message, MOJO_READ_MESSAGE_FLAG_NONE));
   uintptr_t context;
   EXPECT_EQ(MOJO_RESULT_OK, MojoReleaseMessageContext(message, &context));
-  EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
+  EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message));
   EXPECT_EQ(kTestMessageContext, context);
 
   // |h0| should no longer be readable.
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc
index 11713cc..7118bd4 100644
--- a/mojo/public/c/system/thunks.cc
+++ b/mojo/public/c/system/thunks.cc
@@ -179,9 +179,9 @@
   return g_thunks.CreateMessage(context, thunks, message);
 }
 
-MojoResult MojoFreeMessage(MojoMessageHandle message) {
-  assert(g_thunks.FreeMessage);
-  return g_thunks.FreeMessage(message);
+MojoResult MojoDestroyMessage(MojoMessageHandle message) {
+  assert(g_thunks.DestroyMessage);
+  return g_thunks.DestroyMessage(message);
 }
 
 MojoResult MojoSerializeMessage(MojoMessageHandle message) {
diff --git a/mojo/public/c/system/thunks.h b/mojo/public/c/system/thunks.h
index d17b09ec..c634888 100644
--- a/mojo/public/c/system/thunks.h
+++ b/mojo/public/c/system/thunks.h
@@ -88,7 +88,7 @@
   MojoResult (*CreateMessage)(uintptr_t context,
                               const struct MojoMessageOperationThunks* thunks,
                               MojoMessageHandle* message);
-  MojoResult (*FreeMessage)(MojoMessageHandle message);
+  MojoResult (*DestroyMessage)(MojoMessageHandle message);
   MojoResult (*SerializeMessage)(MojoMessageHandle message);
   MojoResult (*GetSerializedMessageContents)(
       MojoMessageHandle message,
diff --git a/mojo/public/cpp/system/message.h b/mojo/public/cpp/system/message.h
index ceb66cc..13d7f85 100644
--- a/mojo/public/cpp/system/message.h
+++ b/mojo/public/cpp/system/message.h
@@ -39,7 +39,7 @@
 
   void Close() {
     DCHECK(is_valid());
-    MojoResult result = MojoFreeMessage(value_);
+    MojoResult result = MojoDestroyMessage(value_);
     ALLOW_UNUSED_LOCAL(result);
     DCHECK_EQ(MOJO_RESULT_OK, result);
   }
diff --git a/mojo/public/cpp/test_support/lib/test_utils.cc b/mojo/public/cpp/test_support/lib/test_utils.cc
index e5eca0ae..d33bb954 100644
--- a/mojo/public/cpp/test_support/lib/test_utils.cc
+++ b/mojo/public/cpp/test_support/lib/test_utils.cc
@@ -50,7 +50,7 @@
       MojoReadMessage(handle.value(), &message, MOJO_READ_MESSAGE_FLAG_NONE);
   if (rv != MOJO_RESULT_OK)
     return false;
-  MojoFreeMessage(message);
+  MojoDestroyMessage(message);
   return true;
 }
 
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
index 009cdf3..c1922e8 100644
--- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
@@ -84,9 +84,15 @@
   }
 }
 
-TestWebWidgetClient* DefaultWebWidgetClient() {
-  DEFINE_STATIC_LOCAL(TestWebWidgetClient, client, ());
-  return &client;
+// Helper to create a default test client if the supplied client pointer is
+// null.
+template <typename T>
+std::unique_ptr<T> CreateDefaultClientIfNeeded(T*& client) {
+  if (client)
+    return nullptr;
+  auto owned_client = WTF::MakeUnique<T>();
+  client = owned_client.get();
+  return owned_client;
 }
 
 }  // namespace
@@ -142,82 +148,96 @@
   return result;
 }
 
-WebLocalFrameBase* CreateLocalChild(WebLocalFrame* parent,
+WebLocalFrameBase* CreateLocalChild(WebLocalFrame& parent,
                                     WebTreeScopeType scope,
                                     TestWebFrameClient* client) {
-  std::unique_ptr<TestWebFrameClient> owned_client;
-  if (!client) {
-    owned_client = WTF::MakeUnique<TestWebFrameClient>();
-    client = owned_client.get();
-  }
-  WebLocalFrameBase* frame = ToWebLocalFrameBase(parent->CreateLocalChild(
+  auto owned_client = CreateDefaultClientIfNeeded(client);
+  WebLocalFrameBase* frame = ToWebLocalFrameBase(parent.CreateLocalChild(
       scope, client, client->GetInterfaceProviderForTesting(), nullptr));
   client->Bind(frame, std::move(owned_client));
   return frame;
 }
 
 WebLocalFrameBase* CreateLocalChild(
-    WebLocalFrame* parent,
+    WebLocalFrame& parent,
     WebTreeScopeType scope,
     std::unique_ptr<TestWebFrameClient> self_owned) {
+  DCHECK(self_owned);
   TestWebFrameClient* client = self_owned.get();
-  WebLocalFrameBase* frame = ToWebLocalFrameBase(parent->CreateLocalChild(
+  WebLocalFrameBase* frame = ToWebLocalFrameBase(parent.CreateLocalChild(
       scope, client, self_owned->GetInterfaceProviderForTesting(), nullptr));
   client->Bind(frame, std::move(self_owned));
   return frame;
 }
 
-WebLocalFrameBase* CreateProvisional(TestWebFrameClient* client,
-                                     WebRemoteFrame* old_frame) {
-  std::unique_ptr<TestWebFrameClient> owned_client;
-  if (!client) {
-    owned_client = WTF::MakeUnique<TestWebFrameClient>();
-    client = owned_client.get();
-  }
+WebLocalFrameBase* CreateProvisional(WebRemoteFrame& old_frame,
+                                     TestWebFrameClient* client) {
+  auto owned_client = CreateDefaultClientIfNeeded(client);
   WebLocalFrameBase* frame =
       ToWebLocalFrameBase(WebLocalFrame::CreateProvisional(
-          client, client->GetInterfaceProviderForTesting(), nullptr, old_frame,
+          client, client->GetInterfaceProviderForTesting(), nullptr, &old_frame,
           WebSandboxFlags::kNone));
   client->Bind(frame, std::move(owned_client));
+  // Create a local root, if necessary.
+  std::unique_ptr<TestWebWidgetClient> owned_widget_client;
+  if (!frame->Parent()) {
+    // TODO(dcheng): The main frame widget currently has a special case.
+    // Eliminate this once WebView is no longer a WebWidget.
+    owned_widget_client = WTF::MakeUnique<TestWebViewWidgetClient>(
+        *static_cast<TestWebViewClient*>(frame->ViewImpl()->Client()));
+  } else if (frame->Parent()->IsWebRemoteFrame()) {
+    owned_widget_client = WTF::MakeUnique<TestWebWidgetClient>();
+  }
+  if (owned_widget_client) {
+    WebFrameWidget::Create(owned_widget_client.get(), frame);
+    client->BindWidgetClient(std::move(owned_widget_client));
+  }
+  return frame;
+}
+
+WebRemoteFrameImpl* CreateRemote(TestWebRemoteFrameClient* client) {
+  auto owned_client = CreateDefaultClientIfNeeded(client);
+  auto* frame = WebRemoteFrameImpl::Create(WebTreeScopeType::kDocument, client);
+  client->Bind(frame, std::move(owned_client));
   return frame;
 }
 
-WebLocalFrameBase* CreateLocalChild(WebRemoteFrame* parent,
+WebLocalFrameBase* CreateLocalChild(WebRemoteFrame& parent,
                                     const WebString& name,
-                                    TestWebFrameClient* client,
-                                    WebWidgetClient* widget_client,
+                                    const WebFrameOwnerProperties& properties,
                                     WebFrame* previous_sibling,
-                                    const WebFrameOwnerProperties& properties) {
-  std::unique_ptr<TestWebFrameClient> owned_client;
-  if (!client) {
-    owned_client = WTF::MakeUnique<TestWebFrameClient>();
-    client = owned_client.get();
-  }
-
-  WebLocalFrameBase* frame = ToWebLocalFrameBase(parent->CreateLocalChild(
+                                    TestWebFrameClient* client,
+                                    TestWebWidgetClient* widget_client) {
+  auto owned_client = CreateDefaultClientIfNeeded(client);
+  auto* frame = ToWebLocalFrameBase(parent.CreateLocalChild(
       WebTreeScopeType::kDocument, name, WebSandboxFlags::kNone, client,
       client->GetInterfaceProviderForTesting(), nullptr, previous_sibling,
       WebParsedFeaturePolicy(), properties, nullptr));
-
   client->Bind(frame, std::move(owned_client));
 
-  if (!widget_client)
-    widget_client = DefaultWebWidgetClient();
+  auto owned_widget_client = CreateDefaultClientIfNeeded(widget_client);
   WebFrameWidget::Create(widget_client, frame);
-
+  client->BindWidgetClient(std::move(owned_widget_client));
   return frame;
 }
 
-WebRemoteFrameImpl* CreateRemoteChild(WebRemoteFrame* parent,
-                                      TestWebRemoteFrameClient* client,
-                                      const WebString& name) {
-  return ToWebRemoteFrameImpl(parent->CreateRemoteChild(
+WebRemoteFrameImpl* CreateRemoteChild(WebRemoteFrame& parent,
+                                      const WebString& name,
+                                      RefPtr<SecurityOrigin> security_origin,
+                                      TestWebRemoteFrameClient* client) {
+  auto owned_client = CreateDefaultClientIfNeeded(client);
+  auto* frame = ToWebRemoteFrameImpl(parent.CreateRemoteChild(
       WebTreeScopeType::kDocument, name, WebSandboxFlags::kNone,
       WebParsedFeaturePolicy(), client, nullptr));
+  client->Bind(frame, std::move(owned_client));
+  if (!security_origin)
+    security_origin = SecurityOrigin::CreateUnique();
+  frame->GetFrame()->GetSecurityContext()->SetReplicatedOrigin(
+      std::move(security_origin));
+  return frame;
 }
 
-WebViewHelper::WebViewHelper(SettingOverrider* setting_overrider)
-    : web_view_(nullptr), setting_overrider_(setting_overrider) {}
+WebViewHelper::WebViewHelper() : web_view_(nullptr) {}
 
 WebViewHelper::~WebViewHelper() {
   Reset();
@@ -231,42 +251,27 @@
     void (*update_settings_func)(WebSettings*)) {
   Reset();
 
-  std::unique_ptr<TestWebFrameClient> owned_web_frame_client;
-  if (!web_frame_client) {
-    owned_web_frame_client = WTF::MakeUnique<TestWebFrameClient>();
-    web_frame_client = owned_web_frame_client.get();
-  }
-  if (!web_view_client) {
-    owned_test_web_view_client_ = WTF::MakeUnique<TestWebViewClient>();
-    web_view_client = owned_test_web_view_client_.get();
-  }
-  if (!web_widget_client)
-    web_widget_client = web_view_client->WidgetClient();
-  web_view_ = static_cast<WebViewBase*>(
-      WebView::Create(web_view_client, kWebPageVisibilityStateVisible));
-  web_view_->GetSettings()->SetJavaScriptEnabled(true);
-  web_view_->GetSettings()->SetPluginsEnabled(true);
-  // Enable (mocked) network loads of image URLs, as this simplifies
-  // the completion of resource loads upon test shutdown & helps avoid
-  // dormant loads trigger Resource leaks for image loads.
-  //
-  // Consequently, all external image resources must be mocked.
-  web_view_->GetSettings()->SetLoadsImagesAutomatically(true);
+  InitializeWebView(web_view_client);
   if (update_settings_func)
     update_settings_func(web_view_->GetSettings());
-  if (setting_overrider_)
-    setting_overrider_->OverrideSettings(web_view_->GetSettings());
-  web_view_->SetDeviceScaleFactor(
-      web_view_client->GetScreenInfo().device_scale_factor);
-  web_view_->SetDefaultPageScaleLimits(1, 4);
+
+  auto owned_web_frame_client = CreateDefaultClientIfNeeded(web_frame_client);
   WebLocalFrame* frame = WebLocalFrameBase::Create(
       WebTreeScopeType::kDocument, web_frame_client,
       web_frame_client->GetInterfaceProviderForTesting(), nullptr, opener);
   web_frame_client->Bind(frame, std::move(owned_web_frame_client));
   web_view_->SetMainFrame(frame);
-  blink::WebFrameWidget::Create(web_widget_client, frame);
 
-  test_web_view_client_ = web_view_client;
+  // TODO(dcheng): The main frame widget currently has a special case.
+  // Eliminate this once WebView is no longer a WebWidget.
+  std::unique_ptr<TestWebWidgetClient> owned_web_widget_client;
+  if (!web_widget_client) {
+    owned_web_widget_client =
+        WTF::MakeUnique<TestWebViewWidgetClient>(*test_web_view_client_);
+    web_widget_client = owned_web_widget_client.get();
+  }
+  blink::WebFrameWidget::Create(web_widget_client, frame);
+  web_frame_client->BindWidgetClient(std::move(owned_web_widget_client));
 
   return web_view_;
 }
@@ -294,10 +299,31 @@
   return WebView();
 }
 
+WebViewBase* WebViewHelper::InitializeRemote(
+    TestWebRemoteFrameClient* web_remote_frame_client,
+    RefPtr<SecurityOrigin> security_origin,
+    TestWebViewClient* web_view_client) {
+  Reset();
+
+  InitializeWebView(web_view_client);
+
+  auto owned_web_remote_frame_client =
+      CreateDefaultClientIfNeeded(web_remote_frame_client);
+  WebRemoteFrameImpl* frame = WebRemoteFrameImpl::Create(
+      WebTreeScopeType::kDocument, web_remote_frame_client);
+  web_remote_frame_client->Bind(frame,
+                                std::move(owned_web_remote_frame_client));
+  web_view_->SetMainFrame(frame);
+  if (!security_origin)
+    security_origin = SecurityOrigin::CreateUnique();
+  frame->GetFrame()->GetSecurityContext()->SetReplicatedOrigin(
+      std::move(security_origin));
+  return web_view_;
+}
+
 void WebViewHelper::Reset() {
   if (web_view_) {
     DCHECK(!TestWebFrameClient::IsLoading());
-    web_view_->WillCloseLayerTreeView();
     web_view_->Close();
     web_view_ = nullptr;
   }
@@ -318,6 +344,25 @@
   test_web_view_client_->ClearAnimationScheduled();
 }
 
+void WebViewHelper::InitializeWebView(TestWebViewClient* web_view_client) {
+  owned_test_web_view_client_ = CreateDefaultClientIfNeeded(web_view_client);
+  web_view_ = static_cast<WebViewBase*>(
+      WebView::Create(web_view_client, kWebPageVisibilityStateVisible));
+  web_view_->GetSettings()->SetJavaScriptEnabled(true);
+  web_view_->GetSettings()->SetPluginsEnabled(true);
+  // Enable (mocked) network loads of image URLs, as this simplifies
+  // the completion of resource loads upon test shutdown & helps avoid
+  // dormant loads trigger Resource leaks for image loads.
+  //
+  // Consequently, all external image resources must be mocked.
+  web_view_->GetSettings()->SetLoadsImagesAutomatically(true);
+  web_view_->SetDeviceScaleFactor(
+      web_view_client->GetScreenInfo().device_scale_factor);
+  web_view_->SetDefaultPageScaleLimits(1, 4);
+
+  test_web_view_client_ = web_view_client;
+}
+
 int TestWebFrameClient::loads_in_progress_ = 0;
 
 TestWebFrameClient::TestWebFrameClient() {}
@@ -330,10 +375,19 @@
   self_owned_ = std::move(self_owned);
 }
 
-void TestWebFrameClient::FrameDetached(WebLocalFrame* frame, DetachType type) {
-  if (frame_->FrameWidget())
-    frame_->FrameWidget()->Close();
+void TestWebFrameClient::BindWidgetClient(
+    std::unique_ptr<TestWebWidgetClient> client) {
+  DCHECK(!owned_widget_client_);
+  owned_widget_client_ = std::move(client);
+}
 
+void TestWebFrameClient::FrameDetached(WebLocalFrame* frame, DetachType type) {
+  if (frame_->FrameWidget()) {
+    frame_->FrameWidget()->WillCloseLayerTreeView();
+    frame_->FrameWidget()->Close();
+  }
+
+  owned_widget_client_.reset();
   frame_->Close();
   self_owned_.reset();
 }
@@ -346,7 +400,7 @@
     WebSandboxFlags sandbox_flags,
     const WebParsedFeaturePolicy& container_policy,
     const WebFrameOwnerProperties& frame_owner_properties) {
-  return CreateLocalChild(parent, scope);
+  return CreateLocalChild(*parent, scope);
 }
 
 void TestWebFrameClient::DidStartLoading(bool) {
@@ -358,22 +412,29 @@
   --loads_in_progress_;
 }
 
-TestWebRemoteFrameClient::TestWebRemoteFrameClient()
-    : frame_(WebRemoteFrameImpl::Create(WebTreeScopeType::kDocument,
-                                        this,
-                                        nullptr)) {}
+TestWebRemoteFrameClient::TestWebRemoteFrameClient() {}
+
+void TestWebRemoteFrameClient::Bind(
+    WebRemoteFrame* frame,
+    std::unique_ptr<TestWebRemoteFrameClient> self_owned) {
+  DCHECK(!frame_);
+  DCHECK(!self_owned || self_owned.get() == this);
+  frame_ = frame;
+  self_owned_ = std::move(self_owned);
+}
 
 void TestWebRemoteFrameClient::FrameDetached(DetachType type) {
   frame_->Close();
+  self_owned_.reset();
 }
 
 WebLayerTreeView* TestWebViewClient::InitializeLayerTreeView() {
-  layer_tree_view_ = WTF::WrapUnique(new WebLayerTreeViewImplForTesting);
+  layer_tree_view_ = WTF::MakeUnique<WebLayerTreeViewImplForTesting>();
   return layer_tree_view_.get();
 }
 
 WebLayerTreeView* TestWebViewWidgetClient::InitializeLayerTreeView() {
-  return test_web_view_client_->InitializeLayerTreeView();
+  return test_web_view_client_.InitializeLayerTreeView();
 }
 
 WebLayerTreeView* TestWebWidgetClient::InitializeLayerTreeView() {
@@ -382,12 +443,12 @@
 }
 
 void TestWebViewWidgetClient::ScheduleAnimation() {
-  test_web_view_client_->ScheduleAnimation();
+  test_web_view_client_.ScheduleAnimation();
 }
 
 void TestWebViewWidgetClient::DidMeaningfulLayout(
     WebMeaningfulLayout layout_type) {
-  test_web_view_client_->DidMeaningfulLayout(layout_type);
+  test_web_view_client_.DidMeaningfulLayout(layout_type);
 }
 
 }  // namespace FrameTestHelpers
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h
index 9d1c84a..a3adb6d 100644
--- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h
+++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h
@@ -92,41 +92,49 @@
                                const IntPoint&,
                                int modifiers);
 
-// Helper for creating a local child frame of a local parent frame. The supplied
-// TestWebFrameClient will not self-delete when the frame is detached.
-WebLocalFrameBase* CreateLocalChild(WebLocalFrame* parent,
+// Helpers for creating frames for test purposes. All methods that accept raw
+// pointer client arguments allow nullptr as a valid argument; if a client
+// pointer is null, the test framework will automatically create and manage the
+// lifetime of that client interface. Otherwise, the caller is responsible for
+// ensuring that non-null clients outlive the created frame.
+
+// Helper for creating a local child frame of a local parent frame.
+WebLocalFrameBase* CreateLocalChild(WebLocalFrame& parent,
                                     WebTreeScopeType,
                                     TestWebFrameClient* = nullptr);
 
-// Similar; however, ownership of the TestWebFrameClient is transferred to
-// itself; the TestWebFrameClient will self-delete when the frame is detached.
-WebLocalFrameBase* CreateLocalChild(WebLocalFrame* parent,
+// Similar, but unlike the overload which takes the client as a raw pointer,
+// ownership of the TestWebFrameClient is transferred to the test framework.
+// TestWebFrameClient may not be null.
+WebLocalFrameBase* CreateLocalChild(WebLocalFrame& parent,
                                     WebTreeScopeType,
                                     std::unique_ptr<TestWebFrameClient>);
 
-WebLocalFrameBase* CreateProvisional(TestWebFrameClient*,
-                                     WebRemoteFrame* old_frame);
+// Helper for creating a provisional local frame that can replace a remote
+// frame.
+WebLocalFrameBase* CreateProvisional(WebRemoteFrame& old_frame,
+                                     TestWebFrameClient* = nullptr);
 
-// Calls WebRemoteFrame::CreateLocalChild, but with some arguments prefilled
-// with default test values (i.e. with a default |client| or |properties| and/or
-// with a precalculated |uniqueName|).
+// Helper for creating a remote frame. Generally used when creating a remote
+// frame to swap into the frame tree.
+// TODO(dcheng): Consider allowing security origin to be passed here once the
+// frame tree moves back to core.
+WebRemoteFrameImpl* CreateRemote(TestWebRemoteFrameClient* = nullptr);
+
+// Helper for creating a local child frame of a remote parent frame.
 WebLocalFrameBase* CreateLocalChild(
-    WebRemoteFrame* parent,
+    WebRemoteFrame& parent,
     const WebString& name = WebString(),
-    TestWebFrameClient* = nullptr,
-    WebWidgetClient* = nullptr,
+    const WebFrameOwnerProperties& = WebFrameOwnerProperties(),
     WebFrame* previous_sibling = nullptr,
-    const WebFrameOwnerProperties& = WebFrameOwnerProperties());
-WebRemoteFrameImpl* CreateRemoteChild(WebRemoteFrame* parent,
-                                      TestWebRemoteFrameClient*,
-                                      const WebString& name = WebString());
+    TestWebFrameClient* = nullptr,
+    TestWebWidgetClient* = nullptr);
 
-// Helpers for unit tests with parameterized WebSettings overrides.
-typedef void (*SettingOverrideFunction)(WebSettings*);
-class SettingOverrider {
- public:
-  virtual void OverrideSettings(WebSettings*) = 0;
-};
+// Helper for creating a remote child frame of a remote parent frame.
+WebRemoteFrameImpl* CreateRemoteChild(WebRemoteFrame& parent,
+                                      const WebString& name = WebString(),
+                                      RefPtr<SecurityOrigin> = nullptr,
+                                      TestWebRemoteFrameClient* = nullptr);
 
 // Forces to use mocked overlay scrollbars instead of the default native theme
 // scrollbars to avoid crash in Chromium code when it tries to load UI
@@ -177,7 +185,7 @@
 
 class TestWebViewWidgetClient : public TestWebWidgetClient {
  public:
-  explicit TestWebViewWidgetClient(TestWebViewClient* test_web_view_client)
+  explicit TestWebViewWidgetClient(TestWebViewClient& test_web_view_client)
       : test_web_view_client_(test_web_view_client) {}
   virtual ~TestWebViewWidgetClient() {}
 
@@ -186,33 +194,25 @@
   void DidMeaningfulLayout(WebMeaningfulLayout) override;
 
  private:
-  TestWebViewClient* test_web_view_client_;
+  TestWebViewClient& test_web_view_client_;
 };
 
 class TestWebViewClient : public WebViewClient {
  public:
-  TestWebViewClient()
-      : test_web_widget_client_(this), animation_scheduled_(false) {}
-  virtual ~TestWebViewClient() {}
-  WebLayerTreeView* InitializeLayerTreeView() override;
+  ~TestWebViewClient() override {}
 
+  WebLayerTreeView* InitializeLayerTreeView() override;
   void ScheduleAnimation() override { animation_scheduled_ = true; }
   bool AnimationScheduled() { return animation_scheduled_; }
   void ClearAnimationScheduled() { animation_scheduled_ = false; }
   bool CanHandleGestureEvent() override { return true; }
   bool CanUpdateLayout() override { return true; }
 
-  // TODO(lfg): This is a temporary method to retrieve the WebWidgetClient,
-  // while we refactor WebView to not inherit from Webwidget.
-  // Returns the WebWidgetClient.
-  TestWebWidgetClient* WidgetClient() { return &test_web_widget_client_; }
-
  private:
   friend class TestWebViewWidgetClient;
 
-  TestWebViewWidgetClient test_web_widget_client_;
   std::unique_ptr<WebLayerTreeView> layer_tree_view_;
-  bool animation_scheduled_;
+  bool animation_scheduled_ = false;
 };
 
 // Convenience class for handling the lifetime of a WebView and its associated
@@ -221,12 +221,16 @@
   WTF_MAKE_NONCOPYABLE(WebViewHelper);
 
  public:
-  WebViewHelper(SettingOverrider* = 0);
+  WebViewHelper();
   ~WebViewHelper();
 
-  // Creates and initializes the WebView. Implicitly calls reset() first. If
-  // a WebFrameClient or a WebViewClient are passed in, they must outlive the
-  // WebViewHelper.
+  // Helpers for creating the main frame. All methods that accept raw
+  // pointer client arguments allow nullptr as a valid argument; if a client
+  // pointer is null, the test framework will automatically create and manage
+  // the lifetime of that client interface. Otherwise, the caller is responsible
+  // for ensuring that non-null clients outlive the created frame.
+
+  // Creates and initializes the WebView with a main WebLocalFrame.
   WebViewBase* InitializeWithOpener(
       WebFrame* opener,
       TestWebFrameClient* = nullptr,
@@ -234,20 +238,27 @@
       TestWebWidgetClient* = nullptr,
       void (*update_settings_func)(WebSettings*) = nullptr);
 
-  // Same as initializeWithOpener(), but always sets the opener to null.
+  // Same as InitializeWithOpener(), but always sets the opener to null.
   WebViewBase* Initialize(TestWebFrameClient* = nullptr,
                           TestWebViewClient* = nullptr,
                           TestWebWidgetClient* = nullptr,
                           void (*update_settings_func)(WebSettings*) = 0);
 
-  // Same as initialize() but also performs the initial load of the url. Only
+  // Same as Initialize() but also performs the initial load of the url. Only
   // returns once the load is complete.
   WebViewBase* InitializeAndLoad(
       const std::string& url,
       TestWebFrameClient* = nullptr,
       TestWebViewClient* = nullptr,
       TestWebWidgetClient* = nullptr,
-      void (*update_settings_func)(WebSettings*) = 0);
+      void (*update_settings_func)(WebSettings*) = nullptr);
+
+  // Creates and initializes the WebView with a main WebRemoteFrame. Passing
+  // nullptr as the SecurityOrigin results in a frame with a unique security
+  // origin.
+  WebViewBase* InitializeRemote(TestWebRemoteFrameClient* = nullptr,
+                                RefPtr<SecurityOrigin> = nullptr,
+                                TestWebViewClient* = nullptr);
 
   void Resize(WebSize);
 
@@ -259,8 +270,9 @@
   WebRemoteFrameBase* RemoteMainFrame();
 
  private:
+  void InitializeWebView(TestWebViewClient*);
+
   WebViewBase* web_view_;
-  SettingOverrider* setting_overrider_;
   UseMockScrollbarSettings mock_scrollbar_settings_;
   // Non-null if the WebViewHelper owns the TestWebViewClient.
   std::unique_ptr<TestWebViewClient> owned_test_web_view_client_;
@@ -279,6 +291,8 @@
   // TestWebFrameClient should delete itself on frame detach.
   void Bind(WebLocalFrame*,
             std::unique_ptr<TestWebFrameClient> self_owned = nullptr);
+  // Note: only needed for local roots.
+  void BindWidgetClient(std::unique_ptr<TestWebWidgetClient>);
 
   void FrameDetached(WebLocalFrame*, DetachType) override;
   WebLocalFrame* CreateChildFrame(WebLocalFrame* parent,
@@ -309,8 +323,11 @@
   // If set to a non-null value, self-deletes on frame detach.
   std::unique_ptr<TestWebFrameClient> self_owned_;
 
-  // This is null from when the client is created until it is initialized.
+  // This is null from when the client is created until it is initialized with
+  // Bind().
   WebLocalFrame* frame_ = nullptr;
+
+  std::unique_ptr<TestWebWidgetClient> owned_widget_client_;
 };
 
 // Minimal implementation of WebRemoteFrameClient needed for unit tests that
@@ -320,7 +337,11 @@
  public:
   TestWebRemoteFrameClient();
 
-  WebRemoteFrameImpl* GetFrame() const { return frame_; }
+  WebRemoteFrame* Frame() const { return frame_; }
+  // Pass ownership of the TestWebFrameClient to |self_owned| here if the
+  // TestWebRemoteFrameClient should delete itself on frame detach.
+  void Bind(WebRemoteFrame*,
+            std::unique_ptr<TestWebRemoteFrameClient> self_owned = nullptr);
 
   // WebRemoteFrameClient overrides:
   void FrameDetached(DetachType) override;
@@ -330,7 +351,12 @@
                           WebDOMMessageEvent) override {}
 
  private:
-  Persistent<WebRemoteFrameImpl> const frame_;
+  // If set to a non-null value, self-deletes on frame detach.
+  std::unique_ptr<TestWebRemoteFrameClient> self_owned_;
+
+  // This is null from when the client is created until it is initialized with
+  // Bind().
+  WebRemoteFrame* frame_ = nullptr;
 };
 
 }  // namespace FrameTestHelpers
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
index 838cb9e..105c9d6 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
@@ -38,6 +38,15 @@
 
 namespace blink {
 
+namespace {
+
+void RunEntriesCallback(EntriesCallback* callback,
+                        HeapVector<Member<Entry>>* entries) {
+  callback->handleEvent(*entries);
+}
+
+}  // namespace
+
 class DirectoryReader::EntriesCallbackHelper final : public EntriesCallback {
  public:
   explicit EntriesCallbackHelper(DirectoryReader* reader) : reader_(reader) {}
@@ -103,11 +112,11 @@
 
   if (!has_more_entries_ || !entries_.IsEmpty()) {
     if (entries_callback) {
+      auto entries = new HeapVector<Member<Entry>>(std::move(entries_));
       DOMFileSystem::ScheduleCallback(
           Filesystem()->GetExecutionContext(),
-          WTF::Bind(&EntriesCallback::handleEvent,
-                    WrapPersistent(entries_callback),
-                    PersistentHeapVector<Member<Entry>>(entries_)));
+          WTF::Bind(&RunEntriesCallback, WrapPersistent(entries_callback),
+                    WrapPersistent(entries)));
     }
     entries_.clear();
     return;
diff --git a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
index 16a688c..82986ecbc 100644
--- a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
+++ b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.cpp
@@ -131,9 +131,9 @@
 
 unsigned long NetworkInformation::rtt() const {
   if (!observing_)
-    return RoundRtt(GetNetworkStateNotifier().TransportRtt());
+    return RoundRtt(GetNetworkStateNotifier().HttpRtt());
 
-  return transport_rtt_msec_;
+  return http_rtt_msec_;
 }
 
 double NetworkInformation::downlink() const {
@@ -152,16 +152,15 @@
     const Optional<double>& downlink_mbps) {
   DCHECK(GetExecutionContext()->IsContextThread());
 
-  unsigned long new_transport_rtt_msec = RoundRtt(transport_rtt);
+  unsigned long new_http_rtt_msec = RoundRtt(http_rtt);
   double new_downlink_mbps = RoundMbps(downlink_mbps);
-  // TODO(tbansal): https://crbug.com/719108. Dispatch |change| event if the
-  // expected network quality has changed.
 
   // This can happen if the observer removes and then adds itself again
-  // during notification, or if |http_rtt| was the only metric that changed.
+  // during notification, or if |transport_rtt| was the only metric that
+  // changed.
   if (type_ == type && downlink_max_mbps_ == downlink_max_mbps &&
       effective_type_ == effective_type &&
-      transport_rtt_msec_ == new_transport_rtt_msec &&
+      http_rtt_msec_ == new_http_rtt_msec &&
       downlink_mbps_ == new_downlink_mbps) {
     return;
   }
@@ -169,7 +168,7 @@
   type_ = type;
   downlink_max_mbps_ = downlink_max_mbps;
   effective_type_ = effective_type;
-  transport_rtt_msec_ = new_transport_rtt_msec;
+  http_rtt_msec_ = new_http_rtt_msec;
   downlink_mbps_ = new_downlink_mbps;
   DispatchEvent(Event::Create(EventTypeNames::typechange));
 
@@ -244,7 +243,7 @@
       type_(GetNetworkStateNotifier().ConnectionType()),
       downlink_max_mbps_(GetNetworkStateNotifier().MaxBandwidth()),
       effective_type_(GetNetworkStateNotifier().EffectiveType()),
-      transport_rtt_msec_(RoundRtt(GetNetworkStateNotifier().TransportRtt())),
+      http_rtt_msec_(RoundRtt(GetNetworkStateNotifier().HttpRtt())),
       downlink_mbps_(
           RoundMbps(GetNetworkStateNotifier().DownlinkThroughputMbps())),
       observing_(false),
diff --git a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.h b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.h
index af476b7..3cff35f 100644
--- a/third_party/WebKit/Source/modules/netinfo/NetworkInformation.h
+++ b/third_party/WebKit/Source/modules/netinfo/NetworkInformation.h
@@ -83,9 +83,9 @@
   // network in use.
   WebEffectiveConnectionType effective_type_;
 
-  // Transport RTT estimate. Rounded off to the nearest 25 msec. Touched only on
+  // HTTP RTT estimate. Rounded off to the nearest 25 msec. Touched only on
   // context thread.
-  unsigned long transport_rtt_msec_;
+  unsigned long http_rtt_msec_;
 
   // Downlink throughput estimate. Rounded off to the nearest 25 kbps. Touched
   // only on context thread.
diff --git a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp
index baf8c9e..c56e36a 100644
--- a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp
+++ b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp
@@ -175,8 +175,7 @@
     override_.on_line_initialized = true;
     override_.connection_initialized = true;
     override_.effective_type = effective_type;
-    override_.transport_rtt =
-        base::TimeDelta::FromMilliseconds(transport_rtt_msec);
+    override_.http_rtt = base::TimeDelta::FromMilliseconds(transport_rtt_msec);
     override_.downlink_throughput_mbps = base::nullopt;
     if (downlink_throughput_mbps >= 0)
       override_.downlink_throughput_mbps = downlink_throughput_mbps;
diff --git a/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp b/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp
index 1797c84..6a1e1075 100644
--- a/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp
+++ b/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp
@@ -585,19 +585,19 @@
 
   notifier_.SetNetworkQualityInfoOverride(
       WebEffectiveConnectionType::kType3G,
-      kEthernetTransportRtt.value().InMilliseconds(),
+      kEthernetHttpRtt.value().InMilliseconds(),
       kEthernetThroughputMbps.value());
   RunPendingTasks();
   EXPECT_TRUE(VerifyObservations(
       observer, kWebConnectionTypeOther,
       NetworkStateNotifier::NetworkState::kInvalidMaxBandwidth,
-      WebEffectiveConnectionType::kType3G, kUnknownRtt, kEthernetTransportRtt,
+      WebEffectiveConnectionType::kType3G, kEthernetHttpRtt, kUnknownRtt,
       kEthernetThroughputMbps));
   EXPECT_TRUE(notifier_.OnLine());
   EXPECT_EQ(kWebConnectionTypeOther, notifier_.ConnectionType());
   EXPECT_EQ(-1, notifier_.MaxBandwidth());
   EXPECT_EQ(WebEffectiveConnectionType::kType3G, notifier_.EffectiveType());
-  EXPECT_EQ(kEthernetTransportRtt, notifier_.TransportRtt());
+  EXPECT_EQ(kEthernetHttpRtt, notifier_.HttpRtt());
   EXPECT_EQ(kEthernetThroughputMbps, notifier_.DownlinkThroughputMbps());
 
   // When override is active, calls to SetConnection are temporary ignored.
@@ -609,13 +609,13 @@
   EXPECT_TRUE(VerifyObservations(
       observer, kWebConnectionTypeOther,
       NetworkStateNotifier::NetworkState::kInvalidMaxBandwidth,
-      WebEffectiveConnectionType::kType3G, kUnknownRtt, kEthernetTransportRtt,
+      WebEffectiveConnectionType::kType3G, kEthernetHttpRtt, kUnknownRtt,
       kEthernetThroughputMbps));
   EXPECT_TRUE(notifier_.OnLine());
   EXPECT_EQ(kWebConnectionTypeOther, notifier_.ConnectionType());
   EXPECT_EQ(-1, notifier_.MaxBandwidth());
   EXPECT_EQ(WebEffectiveConnectionType::kType3G, notifier_.EffectiveType());
-  EXPECT_EQ(kEthernetTransportRtt, notifier_.TransportRtt());
+  EXPECT_EQ(kEthernetHttpRtt, notifier_.HttpRtt());
   EXPECT_EQ(kEthernetThroughputMbps, notifier_.DownlinkThroughputMbps());
 
   // Override the network connection info as well.
@@ -624,13 +624,13 @@
   RunPendingTasks();
   EXPECT_TRUE(VerifyObservations(
       observer, kWebConnectionTypeEthernet, kEthernetMaxBandwidthMbps,
-      WebEffectiveConnectionType::kType3G, kUnknownRtt, kEthernetTransportRtt,
+      WebEffectiveConnectionType::kType3G, kEthernetHttpRtt, kUnknownRtt,
       kEthernetThroughputMbps));
   EXPECT_TRUE(notifier_.OnLine());
   EXPECT_EQ(kWebConnectionTypeEthernet, notifier_.ConnectionType());
   EXPECT_EQ(kEthernetMaxBandwidthMbps, notifier_.MaxBandwidth());
   EXPECT_EQ(WebEffectiveConnectionType::kType3G, notifier_.EffectiveType());
-  EXPECT_EQ(kEthernetTransportRtt, notifier_.TransportRtt());
+  EXPECT_EQ(kEthernetHttpRtt, notifier_.HttpRtt());
   EXPECT_EQ(kEthernetThroughputMbps, notifier_.DownlinkThroughputMbps());
 
   // CLearing the override should cause the network state to be changed and
diff --git a/third_party/WebKit/Source/platform/wtf/AssertionsTest.cpp b/third_party/WebKit/Source/platform/wtf/AssertionsTest.cpp
index 3093f7c..3a7a4ebc 100644
--- a/third_party/WebKit/Source/platform/wtf/AssertionsTest.cpp
+++ b/third_party/WebKit/Source/platform/wtf/AssertionsTest.cpp
@@ -15,6 +15,11 @@
 #if DCHECK_IS_ON()
   EXPECT_DEATH_IF_SUPPORTED(DCHECK(false), "");
   EXPECT_DEATH_IF_SUPPORTED(NOTREACHED(), "");
+  EXPECT_DEATH_IF_SUPPORTED(DCHECK_AT(false, __FILE__, __LINE__), "");
+#else
+  DCHECK(false);
+  NOTREACHED();
+  DCHECK_AT(false, __FILE__, __LINE__);
 #endif
 
   CHECK(true);
@@ -23,6 +28,8 @@
   SECURITY_DCHECK(true);
 #if ENABLE(SECURITY_ASSERT)
   EXPECT_DEATH_IF_SUPPORTED(SECURITY_DCHECK(false), "");
+#else
+  SECURITY_DCHECK(false);
 #endif
 
   SECURITY_CHECK(true);
diff --git a/third_party/WebKit/Source/platform/wtf/Functional.h b/third_party/WebKit/Source/platform/wtf/Functional.h
index 28cc0d8..54c7d87 100644
--- a/third_party/WebKit/Source/platform/wtf/Functional.h
+++ b/third_party/WebKit/Source/platform/wtf/Functional.h
@@ -171,6 +171,8 @@
                 "WTF::Function. Wrap it with either wrapPersistent, "
                 "wrapWeakPersistent, wrapCrossThreadPersistent or "
                 "wrapCrossThreadWeakPersistent.");
+  static_assert(!WTF::IsGarbageCollectedType<T>::value,
+                "GCed type is forbidden as a bound parameters.");
 };
 
 template <typename T>
diff --git a/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp b/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp
index 93420f8..2b2a311 100644
--- a/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp
+++ b/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp
@@ -158,7 +158,7 @@
                                     WebSandboxFlags,
                                     const WebParsedFeaturePolicy&,
                                     const WebFrameOwnerProperties&) {
-      return CreateLocalChild(parent, scope, &child_client_);
+      return CreateLocalChild(*parent, scope, &child_client_);
     }
 
    private:
diff --git a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
index 0640019..f0ff4d05 100644
--- a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
@@ -645,16 +645,10 @@
 // Do a basic sanity check that setting as root scroller an iframe that's remote
 // doesn't crash or otherwise fail catastrophically.
 TEST_F(RootScrollerTest, RemoteIFrame) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client;
   Initialize("root-scroller-iframe.html");
 
   // Initialization: Replace the iframe with a remote frame.
-  {
-    WebRemoteFrame* remote_frame = WebRemoteFrame::Create(
-        WebTreeScopeType::kDocument, &remote_frame_client);
-    WebFrame* child_frame = MainWebFrame()->FirstChild();
-    child_frame->Swap(remote_frame);
-  }
+  MainWebFrame()->FirstChild()->Swap(FrameTestHelpers::CreateRemote());
 
   // Set the root scroller in the local main frame to the iframe (which is
   // remote).
@@ -664,9 +658,6 @@
     MainFrame()->GetDocument()->setRootScroller(iframe, non_throw);
     EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
   }
-
-  // Reset explicitly to prevent lifetime issues with the RemoteFrameClient.
-  helper_.Reset();
 }
 
 // Do a basic sanity check that the scrolling and root scroller machinery
@@ -680,22 +671,18 @@
 #define MAYBE_RemoteMainFrame RemoteMainFrame
 #endif
 TEST_F(RootScrollerTest, MAYBE_RemoteMainFrame) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  FrameTestHelpers::TestWebWidgetClient web_widget_client;
-  WebFrameWidget* widget;
   WebLocalFrameBase* local_frame;
+  WebFrameWidget* widget;
 
   Initialize("root-scroller-iframe.html");
 
   // Initialization: Set the main frame to be a RemoteFrame and add a local
   // child.
   {
-    GetWebView()->SetMainFrame(remote_client.GetFrame());
-    WebRemoteFrame* root = GetWebView()->MainFrame()->ToWebRemoteFrame();
-    root->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
-    WebFrameOwnerProperties properties;
-    local_frame = FrameTestHelpers::CreateLocalChild(
-        root, "frameName", nullptr, nullptr, nullptr, properties);
+    WebRemoteFrameImpl* remote_main_frame = FrameTestHelpers::CreateRemote();
+    helper_.LocalMainFrame()->Swap(remote_main_frame);
+    remote_main_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
+    local_frame = FrameTestHelpers::CreateLocalChild(*remote_main_frame);
 
     FrameTestHelpers::LoadFrame(local_frame,
                                 base_url_ + "root-scroller-child.html");
@@ -742,9 +729,6 @@
     // and should be updated.
     // EXPECT_EQ(200, container->scrollTop());
   }
-
-  // Reset explicitly to prevent lifetime issues with the RemoteFrameClient.
-  helper_.Reset();
 }
 
 // Tests that removing the root scroller element from the DOM resets the
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 7107a03..713eb28c 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -1988,19 +1988,14 @@
 }
 
 TEST_F(WebFrameTest, FrameOwnerPropertiesMargin) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->GetSettings()->SetJavaScriptEnabled(true);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* root = view->MainFrame()->ToWebRemoteFrame();
-  root->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
 
   WebFrameOwnerProperties properties;
   properties.margin_width = 11;
   properties.margin_height = 22;
   WebLocalFrameBase* local_frame = FrameTestHelpers::CreateLocalChild(
-      root, "frameName", nullptr, nullptr, nullptr, properties);
+      *helper.RemoteMainFrame(), "frameName", properties);
 
   RegisterMockedHttpURLLoad("frame_owner_properties.html");
   FrameTestHelpers::LoadFrame(local_frame,
@@ -2018,25 +2013,18 @@
   // Expect scrollbars to be enabled by default.
   EXPECT_NE(nullptr, frame_view->HorizontalScrollbar());
   EXPECT_NE(nullptr, frame_view->VerticalScrollbar());
-
-  view->Close();
 }
 
 TEST_F(WebFrameTest, FrameOwnerPropertiesScrolling) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->GetSettings()->SetJavaScriptEnabled(true);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* root = view->MainFrame()->ToWebRemoteFrame();
-  root->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
 
   WebFrameOwnerProperties properties;
   // Turn off scrolling in the subframe.
   properties.scrolling_mode =
       WebFrameOwnerProperties::ScrollingMode::kAlwaysOff;
   WebLocalFrameBase* local_frame = FrameTestHelpers::CreateLocalChild(
-      root, "frameName", nullptr, nullptr, nullptr, properties);
+      *helper.RemoteMainFrame(), "frameName", properties);
 
   RegisterMockedHttpURLLoad("frame_owner_properties.html");
   FrameTestHelpers::LoadFrame(local_frame,
@@ -2052,8 +2040,6 @@
       static_cast<WebLocalFrameBase*>(local_frame)->GetFrameView();
   EXPECT_EQ(nullptr, frame_view->HorizontalScrollbar());
   EXPECT_EQ(nullptr, frame_view->VerticalScrollbar());
-
-  view->Close();
 }
 
 TEST_P(ParameterizedWebFrameTest,
@@ -4458,7 +4444,7 @@
       WebSandboxFlags sandbox_flags,
       const WebParsedFeaturePolicy& container_policy,
       const WebFrameOwnerProperties&) override {
-    return CreateLocalChild(parent, scope,
+    return CreateLocalChild(*parent, scope,
                             WTF::MakeUnique<ContextLifetimeTestWebFrameClient>(
                                 create_notifications_, release_notifications_));
   }
@@ -7410,7 +7396,7 @@
       const WebParsedFeaturePolicy&,
       const WebFrameOwnerProperties& frame_owner_properties) override {
     child_clients_.emplace_back();
-    return CreateLocalChild(parent, scope, &child_clients_.back());
+    return CreateLocalChild(*parent, scope, &child_clients_.back());
   }
 
   void WillSendRequest(WebURLRequest& request) override {
@@ -7678,7 +7664,7 @@
                                   WebSandboxFlags,
                                   const WebParsedFeaturePolicy&,
                                   const WebFrameOwnerProperties&) {
-    return CreateLocalChild(parent, scope, &child_client_);
+    return CreateLocalChild(*parent, scope, &child_client_);
   }
 
   TestHistoryChildWebFrameClient& ChildClient() { return child_client_; }
@@ -8801,18 +8787,14 @@
 // Make sure that an embedder-triggered detach with a remote frame parent
 // doesn't leave behind dangling pointers.
 TEST_P(ParameterizedWebFrameTest, EmbedderTriggeredDetachWithRemoteMainFrame) {
-  // FIXME: Refactor some of this logic into WebViewHelper to make it easier to
-  // write tests with a top-level remote frame.
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(remote_client.GetFrame());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
   WebLocalFrame* child_frame =
-      FrameTestHelpers::CreateLocalChild(view->MainFrame()->ToWebRemoteFrame());
+      FrameTestHelpers::CreateLocalChild(*helper.RemoteMainFrame());
 
   // Purposely keep the LocalFrame alive so it's the last thing to be destroyed.
   Persistent<Frame> child_core_frame = WebFrame::ToCoreFrame(*child_frame);
-  view->Close();
+  helper.Reset();
   child_core_frame.Clear();
 }
 
@@ -8839,14 +8821,11 @@
 };
 
 TEST_F(WebFrameSwapTest, SwapMainFrame) {
-  WebRemoteFrame* remote_frame =
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, nullptr);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   MainFrame()->Swap(remote_frame);
 
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
-  FrameTestHelpers::TestWebWidgetClient web_widget_client;
-  WebFrameWidget::Create(&web_widget_client, local_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   remote_frame->Swap(local_frame);
 
   // Finally, make sure an embedder triggered load in the local frame swapped
@@ -8856,24 +8835,18 @@
   std::string content =
       WebFrameContentDumper::DumpWebViewAsText(WebView(), 1024).Utf8();
   EXPECT_EQ("hello", content);
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
-  remote_frame->Close();
 }
 
 TEST_F(WebFrameSwapTest, ValidateSizeOnRemoteToLocalMainFrameSwap) {
   WebSize size(111, 222);
 
-  WebRemoteFrame* remote_frame =
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, nullptr);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   MainFrame()->Swap(remote_frame);
 
   remote_frame->View()->Resize(size);
 
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   remote_frame->Swap(local_frame);
 
   // Verify that the size that was set with a remote main frame is correct
@@ -8884,11 +8857,6 @@
                    ->GetPage();
   EXPECT_EQ(size.width, page->GetVisualViewport().Size().Width());
   EXPECT_EQ(size.height, page->GetVisualViewport().Size().Height());
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
-  remote_frame->Close();
 }
 
 namespace {
@@ -8945,14 +8913,12 @@
 }
 
 TEST_F(WebFrameSwapTest, SwapFirstChild) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client;
-  WebRemoteFrame* remote_frame =
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, &remote_frame_client);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   SwapAndVerifyFirstChildConsistency("local->remote", MainFrame(),
                                      remote_frame);
 
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   SwapAndVerifyFirstChildConsistency("remote->local", MainFrame(), local_frame);
 
   // FIXME: This almost certainly fires more load events on the iframe element
@@ -8963,11 +8929,6 @@
   std::string content =
       WebFrameContentDumper::DumpWebViewAsText(WebView(), 1024).Utf8();
   EXPECT_EQ("  \n\nhello\n\nb \n\na\n\nc", content);
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
-  remote_frame->Close();
 }
 
 void WebFrameTest::SwapAndVerifyMiddleChildConsistency(
@@ -8987,14 +8948,12 @@
 }
 
 TEST_F(WebFrameSwapTest, SwapMiddleChild) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client;
-  WebRemoteFrame* remote_frame =
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, &remote_frame_client);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   SwapAndVerifyMiddleChildConsistency("local->remote", MainFrame(),
                                       remote_frame);
 
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   SwapAndVerifyMiddleChildConsistency("remote->local", MainFrame(),
                                       local_frame);
 
@@ -9006,11 +8965,6 @@
   std::string content =
       WebFrameContentDumper::DumpWebViewAsText(WebView(), 1024).Utf8();
   EXPECT_EQ("  \n\na\n\nhello\n\nc", content);
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
-  remote_frame->Close();
 }
 
 void WebFrameTest::SwapAndVerifyLastChildConsistency(const char* const message,
@@ -9026,13 +8980,11 @@
 }
 
 TEST_F(WebFrameSwapTest, SwapLastChild) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client;
-  WebRemoteFrame* remote_frame =
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, &remote_frame_client);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   SwapAndVerifyLastChildConsistency("local->remote", MainFrame(), remote_frame);
 
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   SwapAndVerifyLastChildConsistency("remote->local", MainFrame(), local_frame);
 
   // FIXME: This almost certainly fires more load events on the iframe element
@@ -9043,23 +8995,15 @@
   std::string content =
       WebFrameContentDumper::DumpWebViewAsText(WebView(), 1024).Utf8();
   EXPECT_EQ("  \n\na\n\nb \n\na\n\nhello", content);
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
-  remote_frame->Close();
 }
 
 TEST_F(WebFrameSwapTest, DetachProvisionalFrame) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client;
-  WebRemoteFrameImpl* remote_frame = WebRemoteFrameImpl::Create(
-      WebTreeScopeType::kDocument, &remote_frame_client);
+  WebRemoteFrameImpl* remote_frame = FrameTestHelpers::CreateRemote();
   SwapAndVerifyMiddleChildConsistency("local->remote", MainFrame(),
                                       remote_frame);
 
-  FrameTestHelpers::TestWebFrameClient client;
   WebLocalFrameBase* provisional_frame =
-      CreateProvisional(&client, remote_frame);
+      FrameTestHelpers::CreateProvisional(*remote_frame);
 
   // The provisional frame should have a local frame owner.
   FrameOwner* owner = provisional_frame->GetFrame()->Owner();
@@ -9076,10 +9020,6 @@
   // The owner should not be affected by detaching the provisional frame, so it
   // should still point to |remoteFrame|.
   EXPECT_EQ(remote_frame->GetFrame(), owner->ContentFrame());
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
 }
 
 void WebFrameTest::SwapAndVerifySubframeConsistency(const char* const message,
@@ -9095,9 +9035,7 @@
 }
 
 TEST_F(WebFrameSwapTest, SwapParentShouldDetachChildren) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client1;
-  WebRemoteFrame* remote_frame = WebRemoteFrame::Create(
-      WebTreeScopeType::kDocument, &remote_frame_client1);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   WebFrame* target_frame = MainFrame()->FirstChild()->NextSibling();
   EXPECT_TRUE(target_frame);
   SwapAndVerifySubframeConsistency("local->remote", target_frame, remote_frame);
@@ -9106,12 +9044,10 @@
   EXPECT_TRUE(target_frame);
 
   // Create child frames in the target frame before testing the swap.
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client2;
-  WebRemoteFrame* child_remote_frame =
-      FrameTestHelpers::CreateRemoteChild(remote_frame, &remote_frame_client2);
+  FrameTestHelpers::CreateRemoteChild(*remote_frame);
 
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   SwapAndVerifySubframeConsistency("remote->local", target_frame, local_frame);
 
   // FIXME: This almost certainly fires more load events on the iframe element
@@ -9122,12 +9058,6 @@
   std::string content =
       WebFrameContentDumper::DumpWebViewAsText(WebView(), 1024).Utf8();
   EXPECT_EQ("  \n\na\n\nhello\n\nc", content);
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
-  remote_frame->Close();
-  child_remote_frame->Close();
 }
 
 TEST_F(WebFrameSwapTest, SwapPreservesGlobalContext) {
@@ -9141,11 +9071,9 @@
   ASSERT_TRUE(original_window->IsObject());
 
   // Make sure window reference stays the same when swapping to a remote frame.
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   WebFrame* target_frame = MainFrame()->FirstChild()->NextSibling();
   target_frame->Swap(remote_frame);
-  remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
   v8::Local<v8::Value> remote_window = MainFrame()->ExecuteScriptAndReturnValue(
       WebScriptSource("document.querySelector('#frame2').contentWindow;"));
   EXPECT_TRUE(original_window->StrictEquals(remote_window));
@@ -9157,8 +9085,8 @@
 
   // Now check that remote -> local works too, since it goes through a different
   // code path.
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   remote_frame->Swap(local_frame);
   v8::Local<v8::Value> local_window = MainFrame()->ExecuteScriptAndReturnValue(
       WebScriptSource("document.querySelector('#frame2').contentWindow;"));
@@ -9167,10 +9095,6 @@
       MainFrame()->ExecuteScriptAndReturnValue(WebScriptSource(
           "document.querySelector('#frame2').contentWindow.top;"));
   EXPECT_TRUE(window_top->StrictEquals(local_window_top));
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // TestWebFrameClient.
-  Reset();
 }
 
 TEST_F(WebFrameSwapTest, SetTimeoutAfterSwap) {
@@ -9180,8 +9104,7 @@
       WebScriptSource("savedSetTimeout = window[0].setTimeout"));
 
   // Swap the frame to a remote frame.
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   WebFrame* target_frame = MainFrame()->FirstChild();
   target_frame->Swap(remote_frame);
   remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
@@ -9202,8 +9125,6 @@
                                         ->GetContext())
                          .ToLocalChecked()));
   }
-
-  Reset();
 }
 
 TEST_F(WebFrameSwapTest, SwapInitializesGlobal) {
@@ -9217,33 +9138,27 @@
       WebScriptSource("saved = window[2]"));
   ASSERT_TRUE(last_child->IsObject());
 
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   WebFrameTest::LastChild(MainFrame())->Swap(remote_frame);
-  remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
   v8::Local<v8::Value> remote_window_top =
       MainFrame()->ExecuteScriptAndReturnValue(WebScriptSource("saved.top"));
   EXPECT_TRUE(remote_window_top->IsObject());
   EXPECT_TRUE(window_top->StrictEquals(remote_window_top));
 
-  FrameTestHelpers::TestWebFrameClient client;
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   remote_frame->Swap(local_frame);
   v8::Local<v8::Value> local_window_top =
       MainFrame()->ExecuteScriptAndReturnValue(WebScriptSource("saved.top"));
   EXPECT_TRUE(local_window_top->IsObject());
   EXPECT_TRUE(window_top->StrictEquals(local_window_top));
-
-  Reset();
 }
 
 TEST_F(WebFrameSwapTest, RemoteFramesAreIndexable) {
   v8::HandleScope scope(v8::Isolate::GetCurrent());
 
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   LastChild(MainFrame())->Swap(remote_frame);
-  remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
   v8::Local<v8::Value> remote_window =
       MainFrame()->ExecuteScriptAndReturnValue(WebScriptSource("window[2]"));
   EXPECT_TRUE(remote_window->IsObject());
@@ -9251,58 +9166,45 @@
       WebScriptSource("window.length"));
   ASSERT_TRUE(window_length->IsInt32());
   EXPECT_EQ(3, window_length.As<v8::Int32>()->Value());
-
-  Reset();
 }
 
 TEST_F(WebFrameSwapTest, RemoteFrameLengthAccess) {
   v8::HandleScope scope(v8::Isolate::GetCurrent());
 
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   LastChild(MainFrame())->Swap(remote_frame);
-  remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
   v8::Local<v8::Value> remote_window_length =
       MainFrame()->ExecuteScriptAndReturnValue(
           WebScriptSource("window[2].length"));
   ASSERT_TRUE(remote_window_length->IsInt32());
   EXPECT_EQ(0, remote_window_length.As<v8::Int32>()->Value());
-
-  Reset();
 }
 
 TEST_F(WebFrameSwapTest, RemoteWindowNamedAccess) {
   v8::HandleScope scope(v8::Isolate::GetCurrent());
 
-  // FIXME: Once OOPIF unit test infrastructure is in place, test that named
-  // window access on a remote window works. For now, just test that accessing
-  // a named property doesn't crash.
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  // TODO(dcheng): Once OOPIF unit test infrastructure is in place, test that
+  // named window access on a remote window works. For now, just test that
+  // accessing a named property doesn't crash.
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   LastChild(MainFrame())->Swap(remote_frame);
   remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
   v8::Local<v8::Value> remote_window_property =
       MainFrame()->ExecuteScriptAndReturnValue(
           WebScriptSource("window[2].foo"));
   EXPECT_TRUE(remote_window_property.IsEmpty());
-
-  Reset();
 }
 
 TEST_F(WebFrameSwapTest, RemoteWindowToString) {
   v8::HandleScope scope(v8::Isolate::GetCurrent());
 
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   LastChild(MainFrame())->Swap(remote_frame);
-  remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
   v8::Local<v8::Value> to_string_result =
       MainFrame()->ExecuteScriptAndReturnValue(
           WebScriptSource("Object.prototype.toString.call(window[2])"));
   ASSERT_FALSE(to_string_result.IsEmpty());
   EXPECT_STREQ("[object Object]", *v8::String::Utf8Value(to_string_result));
-
-  Reset();
 }
 
 // TODO(alexmos, dcheng): This test and some other OOPIF tests use
@@ -9311,13 +9213,12 @@
 TEST_F(WebFrameSwapTest, FramesOfRemoteParentAreIndexable) {
   v8::HandleScope scope(v8::Isolate::GetCurrent());
 
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_parent_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_parent_frame = FrameTestHelpers::CreateRemote();
   MainFrame()->Swap(remote_parent_frame);
   remote_parent_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
 
   WebLocalFrame* child_frame =
-      FrameTestHelpers::CreateLocalChild(remote_parent_frame);
+      FrameTestHelpers::CreateLocalChild(*remote_parent_frame);
   FrameTestHelpers::LoadFrame(child_frame, base_url_ + "subframe-hello.html");
 
   v8::Local<v8::Value> window =
@@ -9332,10 +9233,6 @@
       WebScriptSource("parent.frames.length"));
   ASSERT_TRUE(window_length->IsInt32());
   EXPECT_EQ(1, window_length.As<v8::Int32>()->Value());
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // clients.
-  Reset();
 }
 
 // Check that frames with a remote parent don't crash while accessing
@@ -9343,13 +9240,12 @@
 TEST_F(WebFrameSwapTest, FrameElementInFramesWithRemoteParent) {
   v8::HandleScope scope(v8::Isolate::GetCurrent());
 
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_parent_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_parent_frame = FrameTestHelpers::CreateRemote();
   MainFrame()->Swap(remote_parent_frame);
   remote_parent_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
 
   WebLocalFrame* child_frame =
-      FrameTestHelpers::CreateLocalChild(remote_parent_frame);
+      FrameTestHelpers::CreateLocalChild(*remote_parent_frame);
   FrameTestHelpers::LoadFrame(child_frame, base_url_ + "subframe-hello.html");
 
   v8::Local<v8::Value> frame_element = child_frame->ExecuteScriptAndReturnValue(
@@ -9357,10 +9253,6 @@
   // frameElement should be null if cross-origin.
   ASSERT_FALSE(frame_element.IsEmpty());
   EXPECT_TRUE(frame_element->IsNull());
-
-  // Manually reset to break WebViewHelper's dependency on the stack allocated
-  // clients.
-  Reset();
 }
 
 class RemoteToLocalSwapWebFrameClient
@@ -9390,9 +9282,7 @@
 // exists in the same process, such that we create the RemoteFrame before the
 // first navigation occurs.
 TEST_F(WebFrameSwapTest, HistoryCommitTypeAfterNewRemoteToLocalSwap) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client;
-  WebRemoteFrame* remote_frame =
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, &remote_frame_client);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   WebFrame* target_frame = MainFrame()->FirstChild();
   ASSERT_TRUE(target_frame);
   target_frame->Swap(remote_frame);
@@ -9400,23 +9290,21 @@
   ASSERT_EQ(MainFrame()->FirstChild(), remote_frame);
 
   RemoteToLocalSwapWebFrameClient client(remote_frame);
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame, &client);
   FrameTestHelpers::LoadFrame(local_frame, base_url_ + "subframe-hello.html");
   EXPECT_EQ(kWebInitialCommitInChildFrame, client.HistoryCommitType());
 
   // Manually reset to break WebViewHelper's dependency on the stack allocated
   // TestWebFrameClient.
   Reset();
-  remote_frame->Close();
 }
 
 // The commit type should be Standard if we are swapping a RemoteFrame to a
 // LocalFrame after commits have already happened in the frame.  The browser
 // process will inform us via setCommittedFirstRealLoad.
 TEST_F(WebFrameSwapTest, HistoryCommitTypeAfterExistingRemoteToLocalSwap) {
-  FrameTestHelpers::TestWebRemoteFrameClient remote_frame_client;
-  WebRemoteFrame* remote_frame =
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, &remote_frame_client);
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   WebFrame* target_frame = MainFrame()->FirstChild();
   ASSERT_TRUE(target_frame);
   target_frame->Swap(remote_frame);
@@ -9424,7 +9312,8 @@
   ASSERT_EQ(MainFrame()->FirstChild(), remote_frame);
 
   RemoteToLocalSwapWebFrameClient client(remote_frame);
-  WebLocalFrame* local_frame = CreateProvisional(&client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame, &client);
   local_frame->SetCommittedFirstRealLoad();
   FrameTestHelpers::LoadFrame(local_frame, base_url_ + "subframe-hello.html");
   EXPECT_EQ(kWebStandardCommit, client.HistoryCommitType());
@@ -9432,7 +9321,6 @@
   // Manually reset to break WebViewHelper's dependency on the stack allocated
   // TestWebFrameClient.
   Reset();
-  remote_frame->Close();
 }
 
 class RemoteNavigationClient
@@ -9451,7 +9339,7 @@
 
 TEST_F(WebFrameSwapTest, NavigateRemoteFrameViaLocation) {
   RemoteNavigationClient client;
-  WebRemoteFrame* remote_frame = client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote(&client);
   WebFrame* target_frame = MainFrame()->FirstChild();
   ASSERT_TRUE(target_frame);
   target_frame->Swap(remote_frame);
@@ -9473,10 +9361,9 @@
 
 TEST_F(WebFrameSwapTest, WindowOpenOnRemoteFrame) {
   RemoteNavigationClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
+  WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote(&remote_client);
   MainFrame()->FirstChild()->Swap(remote_frame);
-  remote_frame->SetReplicatedOrigin(
-      WebSecurityOrigin::CreateFromString("http://127.0.0.1"));
+  remote_frame->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
 
   ASSERT_TRUE(MainFrame()->FirstChild()->IsWebRemoteFrame());
   LocalDOMWindow* main_window =
@@ -9517,18 +9404,12 @@
 
   // Create a remote window that will be closed later in the test.
   RemoteWindowCloseClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient frame_client;
-  WebRemoteFrameImpl* web_remote_frame = frame_client.GetFrame();
+  FrameTestHelpers::WebViewHelper popup;
+  popup.InitializeRemote(nullptr, nullptr, &view_client);
+  popup.RemoteMainFrame()->SetOpener(main_web_view.LocalMainFrame());
 
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(web_remote_frame);
-  view->MainFrame()->SetOpener(main_web_view.WebView()->MainFrame());
-  web_remote_frame->SetReplicatedOrigin(
-      WebSecurityOrigin::CreateFromString("http://127.0.0.1"));
-
-  LocalFrame* local_frame = ToLocalFrame(
-      WebFrame::ToCoreFrame(*main_web_view.WebView()->MainFrame()));
-  RemoteFrame* remote_frame = web_remote_frame->GetFrame();
+  LocalFrame* local_frame = main_web_view.LocalMainFrame()->GetFrame();
+  RemoteFrame* remote_frame = popup.RemoteMainFrame()->GetFrame();
 
   // Attempt to close the window, which should fail as it isn't opened
   // by a script.
@@ -9539,60 +9420,47 @@
   remote_frame->GetPage()->SetOpenedByDOM();
   remote_frame->DomWindow()->close(local_frame->GetDocument());
   EXPECT_TRUE(view_client.Closed());
-
-  view->Close();
 }
 
 TEST_F(WebFrameTest, NavigateRemoteToLocalWithOpener) {
   FrameTestHelpers::WebViewHelper main_web_view;
   main_web_view.Initialize();
-  WebFrame* main_frame = main_web_view.WebView()->MainFrame();
+  WebLocalFrame* main_frame = main_web_view.LocalMainFrame();
 
   // Create a popup with a remote frame and set its opener to the main frame.
-  FrameTestHelpers::TestWebViewClient popup_view_client;
-  WebView* popup_view =
-      WebView::Create(&popup_view_client, kWebPageVisibilityStateVisible);
-  FrameTestHelpers::TestWebRemoteFrameClient popup_remote_client;
-  WebRemoteFrame* popup_remote_frame = popup_remote_client.GetFrame();
-  popup_view->SetMainFrame(popup_remote_frame);
+  FrameTestHelpers::WebViewHelper popup_helper;
+  popup_helper.InitializeRemote(
+      nullptr, SecurityOrigin::CreateFromString("http://foo.com"));
+  WebRemoteFrame* popup_remote_frame = popup_helper.RemoteMainFrame();
   popup_remote_frame->SetOpener(main_frame);
-  popup_remote_frame->SetReplicatedOrigin(
-      WebSecurityOrigin::CreateFromString("http://foo.com"));
   EXPECT_FALSE(main_frame->GetSecurityOrigin().CanAccess(
-      popup_view->MainFrame()->GetSecurityOrigin()));
+      popup_remote_frame->GetSecurityOrigin()));
 
   // Do a remote-to-local swap in the popup.
-  FrameTestHelpers::TestWebFrameClient popup_local_client;
   WebLocalFrame* popup_local_frame =
-      CreateProvisional(&popup_local_client, popup_remote_frame);
+      FrameTestHelpers::CreateProvisional(*popup_remote_frame);
   popup_remote_frame->Swap(popup_local_frame);
 
   // The initial document created during the remote-to-local swap should have
   // inherited its opener's SecurityOrigin.
   EXPECT_TRUE(main_frame->GetSecurityOrigin().CanAccess(
-      popup_view->MainFrame()->GetSecurityOrigin()));
-
-  popup_view->Close();
+      popup_helper.LocalMainFrame()->GetSecurityOrigin()));
 }
 
 TEST_F(WebFrameTest, SwapWithOpenerCycle) {
   // First, create a remote main frame with itself as the opener.
-  FrameTestHelpers::TestWebViewClient view_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebRemoteFrame* remote_frame = remote_client.GetFrame();
-  view->SetMainFrame(remote_frame);
-  remote_frame->SetOpener(remote_frame);
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
+  WebRemoteFrame* remote_frame = helper.RemoteMainFrame();
+  helper.RemoteMainFrame()->SetOpener(remote_frame);
 
   // Now swap in a local frame. It shouldn't crash.
-  FrameTestHelpers::TestWebFrameClient local_client;
-  WebLocalFrame* local_frame = CreateProvisional(&local_client, remote_frame);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateProvisional(*remote_frame);
   remote_frame->Swap(local_frame);
 
   // And the opener cycle should still be preserved.
   EXPECT_EQ(local_frame, local_frame->Opener());
-
-  view->Close();
 }
 
 class CommitTypeWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
@@ -9615,23 +9483,22 @@
 };
 
 TEST_P(ParameterizedWebFrameTest, RemoteFrameInitialCommitType) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(remote_client.GetFrame());
-  remote_client.GetFrame()->SetReplicatedOrigin(
-      WebSecurityOrigin::CreateFromString(WebString::FromUTF8(base_url_)));
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote(nullptr, SecurityOrigin::CreateFromString(
+                                       WebString::FromUTF8(base_url_)));
 
   // If an iframe has a remote main frame, ensure the inital commit is correctly
   // identified as WebInitialCommitInChildFrame.
   CommitTypeWebFrameClient child_frame_client;
   WebLocalFrame* child_frame = FrameTestHelpers::CreateLocalChild(
-      view->MainFrame()->ToWebRemoteFrame(), "frameName", &child_frame_client);
+      *helper.RemoteMainFrame(), "frameName", WebFrameOwnerProperties(),
+      nullptr, &child_frame_client);
   RegisterMockedHttpURLLoad("foo.html");
   FrameTestHelpers::LoadFrame(child_frame, base_url_ + "foo.html");
   EXPECT_EQ(kWebInitialCommitInChildFrame,
             child_frame_client.HistoryCommitType());
-  view->Close();
+
+  helper.Reset();
 }
 
 class GestureEventTestWebWidgetClient
@@ -9649,23 +9516,20 @@
 };
 
 TEST_P(ParameterizedWebFrameTest, FrameWidgetTest) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  view->SetMainFrame(remote_client.GetFrame());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
 
   GestureEventTestWebWidgetClient child_widget_client;
   WebLocalFrame* child_frame = FrameTestHelpers::CreateLocalChild(
-      view->MainFrame()->ToWebRemoteFrame(), WebString(), nullptr,
-      &child_widget_client);
+      *helper.RemoteMainFrame(), WebString(), WebFrameOwnerProperties(),
+      nullptr, nullptr, &child_widget_client);
 
-  view->Resize(WebSize(1000, 1000));
+  helper.WebView()->Resize(WebSize(1000, 1000));
 
   child_frame->FrameWidget()->HandleInputEvent(FatTap(20, 20));
   EXPECT_TRUE(child_widget_client.DidHandleGestureEvent());
 
-  view->Close();
+  helper.Reset();
 }
 
 class MockDocumentThreadableLoaderClient
@@ -9718,16 +9582,11 @@
 }
 
 TEST_P(ParameterizedWebFrameTest, DetachRemoteFrame) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(remote_client.GetFrame());
-  FrameTestHelpers::TestWebRemoteFrameClient child_frame_client;
-  WebRemoteFrame* child_frame = FrameTestHelpers::CreateRemoteChild(
-      view->MainFrame()->ToWebRemoteFrame(), &child_frame_client);
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
+  WebRemoteFrame* child_frame =
+      FrameTestHelpers::CreateRemoteChild(*helper.RemoteMainFrame());
   child_frame->Detach();
-  view->Close();
-  child_frame->Close();
 }
 
 class TestConsoleMessageWebFrameClient
@@ -9900,20 +9759,18 @@
 }
 
 TEST_P(ParameterizedWebFrameTest, CreateLocalChildWithPreviousSibling) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* parent = view->MainFrame()->ToWebRemoteFrame();
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
+  WebRemoteFrame* parent = helper.RemoteMainFrame();
 
   WebLocalFrame* second_frame(
-      FrameTestHelpers::CreateLocalChild(parent, "name2"));
+      FrameTestHelpers::CreateLocalChild(*parent, "name2"));
   WebLocalFrame* fourth_frame(FrameTestHelpers::CreateLocalChild(
-      parent, "name4", nullptr, nullptr, second_frame));
+      *parent, "name4", WebFrameOwnerProperties(), second_frame));
   WebLocalFrame* third_frame(FrameTestHelpers::CreateLocalChild(
-      parent, "name3", nullptr, nullptr, second_frame));
+      *parent, "name3", WebFrameOwnerProperties(), second_frame));
   WebLocalFrame* first_frame(
-      FrameTestHelpers::CreateLocalChild(parent, "name1"));
+      FrameTestHelpers::CreateLocalChild(*parent, "name1"));
 
   EXPECT_EQ(first_frame, parent->FirstChild());
   EXPECT_EQ(nullptr, PreviousSibling(first_frame));
@@ -9933,40 +9790,30 @@
   EXPECT_EQ(parent, second_frame->Parent());
   EXPECT_EQ(parent, third_frame->Parent());
   EXPECT_EQ(parent, fourth_frame->Parent());
-
-  view->Close();
 }
 
 TEST_P(ParameterizedWebFrameTest, SendBeaconFromChildWithRemoteMainFrame) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->GetSettings()->SetJavaScriptEnabled(true);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* root = view->MainFrame()->ToWebRemoteFrame();
-  root->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
 
-  WebLocalFrame* local_frame = FrameTestHelpers::CreateLocalChild(root);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateLocalChild(*helper.RemoteMainFrame());
 
   // Finally, make sure an embedder triggered load in the local frame swapped
   // back in works.
   RegisterMockedHttpURLLoad("send_beacon.html");
   RegisterMockedHttpURLLoad("reload_post.html");  // url param to sendBeacon()
   FrameTestHelpers::LoadFrame(local_frame, base_url_ + "send_beacon.html");
-
-  view->Close();
 }
 
 TEST_P(ParameterizedWebFrameTest,
        FirstPartyForCookiesFromChildWithRemoteMainFrame) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* root = view->MainFrame()->ToWebRemoteFrame();
-  root->SetReplicatedOrigin(SecurityOrigin::Create(ToKURL(not_base_url_)));
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote(nullptr,
+                          SecurityOrigin::Create(ToKURL(not_base_url_)));
 
-  WebLocalFrame* local_frame = FrameTestHelpers::CreateLocalChild(root);
+  WebLocalFrame* local_frame =
+      FrameTestHelpers::CreateLocalChild(*helper.RemoteMainFrame());
 
   RegisterMockedHttpURLLoad("foo.html");
   FrameTestHelpers::LoadFrame(local_frame, base_url_ + "foo.html");
@@ -9977,51 +9824,37 @@
   EXPECT_EQ(WebURL(ToKURL(not_base_url_)),
             local_frame->GetDocument().FirstPartyForCookies());
   SchemeRegistry::RemoveURLSchemeAsFirstPartyWhenTopLevel("http");
-
-  view->Close();
 }
 
 // See https://crbug.com/525285.
 TEST_P(ParameterizedWebFrameTest,
        RemoteToLocalSwapOnMainFrameInitializesCoreFrame) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* remote_root = view->MainFrame()->ToWebRemoteFrame();
-  remote_root->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
 
-  FrameTestHelpers::CreateLocalChild(remote_root);
+  FrameTestHelpers::CreateLocalChild(*helper.RemoteMainFrame());
 
   // Do a remote-to-local swap of the top frame.
-  FrameTestHelpers::TestWebFrameClient local_client;
-  WebLocalFrame* local_root = CreateProvisional(&local_client, remote_root);
-  FrameTestHelpers::TestWebWidgetClient web_widget_client;
-  WebFrameWidget::Create(&web_widget_client, local_root);
-  remote_root->Swap(local_root);
+  WebLocalFrame* local_root =
+      FrameTestHelpers::CreateProvisional(*helper.RemoteMainFrame());
+  helper.RemoteMainFrame()->Swap(local_root);
 
   // Load a page with a child frame in the new root to make sure this doesn't
   // crash when the child frame invokes setCoreFrame.
   RegisterMockedHttpURLLoad("single_iframe.html");
   RegisterMockedHttpURLLoad("visible_iframe.html");
   FrameTestHelpers::LoadFrame(local_root, base_url_ + "single_iframe.html");
-
-  view->Close();
 }
 
 // See https://crbug.com/628942.
 TEST_P(ParameterizedWebFrameTest, SuspendedPageLoadWithRemoteMainFrame) {
-  // Prepare a page with a remote main frame.
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* remote_root = view->MainFrame()->ToWebRemoteFrame();
-  remote_root->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
+  WebRemoteFrameBase* remote_root = helper.RemoteMainFrame();
 
   // Check that ScopedPageSuspender properly triggers deferred loading for
   // the current Page.
-  Page* page = WebFrame::ToCoreFrame(*remote_root)->GetPage();
+  Page* page = remote_root->GetFrame()->GetPage();
   EXPECT_FALSE(page->Suspended());
   {
     ScopedPageSuspender suspender;
@@ -10031,11 +9864,11 @@
 
   // Repeat this for a page with a local child frame, and ensure that the
   // child frame's loads are also suspended.
-  WebLocalFrame* web_local_child =
-      FrameTestHelpers::CreateLocalChild(remote_root);
+  WebLocalFrameBase* web_local_child =
+      FrameTestHelpers::CreateLocalChild(*remote_root);
   RegisterMockedHttpURLLoad("foo.html");
   FrameTestHelpers::LoadFrame(web_local_child, base_url_ + "foo.html");
-  LocalFrame* local_child = ToWebLocalFrameBase(web_local_child)->GetFrame();
+  LocalFrame* local_child = web_local_child->GetFrame();
   EXPECT_FALSE(page->Suspended());
   EXPECT_FALSE(
       local_child->GetDocument()->Fetcher()->Context().DefersLoading());
@@ -10048,8 +9881,6 @@
   EXPECT_FALSE(page->Suspended());
   EXPECT_FALSE(
       local_child->GetDocument()->Fetcher()->Context().DefersLoading());
-
-  view->Close();
 }
 
 class OverscrollWebViewClient : public FrameTestHelpers::TestWebViewClient {
@@ -10465,7 +10296,7 @@
     frame_ =
         web_view_helper_.InitializeAndLoad(base_url_ + "single_iframe.html")
             ->MainFrameImpl();
-    web_remote_frame_ = RemoteFrameClient()->GetFrame();
+    web_remote_frame_ = FrameTestHelpers::CreateRemote(&remote_frame_client_);
   }
 
   ~WebFrameVisibilityChangeTest() {}
@@ -10478,11 +10309,10 @@
 
   void SwapLocalFrameToRemoteFrame() {
     LastChild(MainFrame())->Swap(RemoteFrame());
-    RemoteFrame()->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
   }
 
   WebLocalFrame* MainFrame() { return frame_; }
-  WebRemoteFrameImpl* RemoteFrame() { return web_remote_frame_; }
+  WebRemoteFrameBase* RemoteFrame() { return web_remote_frame_; }
   TestWebRemoteFrameClientForVisibility* RemoteFrameClient() {
     return &remote_frame_client_;
   }
@@ -10491,7 +10321,7 @@
   TestWebRemoteFrameClientForVisibility remote_frame_client_;
   FrameTestHelpers::WebViewHelper web_view_helper_;
   WebLocalFrame* frame_;
-  Persistent<WebRemoteFrameImpl> web_remote_frame_;
+  Persistent<WebRemoteFrameBase> web_remote_frame_;
 };
 
 TEST_F(WebFrameVisibilityChangeTest, RemoteFrameVisibilityChange) {
@@ -11951,7 +11781,7 @@
         WebSandboxFlags sandbox_flags,
         const WebParsedFeaturePolicy& container_policy,
         const WebFrameOwnerProperties&) override {
-      return CreateLocalChild(parent, scope, &child_client_);
+      return CreateLocalChild(*parent, scope, &child_client_);
     }
 
     LoadingObserverFrameClient& ChildClient() { return child_client_; }
@@ -12007,17 +11837,12 @@
 
 TEST_F(WebFrameTest, ShowVirtualKeyboardOnElementFocus) {
   FrameTestHelpers::WebViewHelper web_view_helper;
-  WebViewBase* web_view = web_view_helper.Initialize();
-  WebRemoteFrameImpl* remote_frame = static_cast<WebRemoteFrameImpl*>(
-      WebRemoteFrame::Create(WebTreeScopeType::kDocument, nullptr));
-  web_view->SetMainFrame(remote_frame);
-  RefPtr<SecurityOrigin> unique_origin = SecurityOrigin::CreateUnique();
-  remote_frame->GetFrame()->GetSecurityContext()->SetSecurityOrigin(
-      unique_origin);
+  web_view_helper.InitializeRemote();
 
   ShowVirtualKeyboardObserverWidgetClient web_widget_client;
   WebLocalFrameBase* local_frame = FrameTestHelpers::CreateLocalChild(
-      remote_frame, "child", nullptr, &web_widget_client);
+      *web_view_helper.RemoteMainFrame(), "child", WebFrameOwnerProperties(),
+      nullptr, nullptr, &web_widget_client);
 
   RegisterMockedHttpURLLoad("input_field_default.html");
   FrameTestHelpers::LoadFrame(local_frame,
@@ -12033,7 +11858,6 @@
   // Verify that the right WebWidgetClient has been notified.
   EXPECT_TRUE(web_widget_client.DidShowVirtualKeyboard());
 
-  remote_frame->Close();
   web_view_helper.Reset();
 }
 
@@ -12116,22 +11940,16 @@
 }
 
 TEST_F(WebFrameTest, LocalFrameWithRemoteParentIsTransparent) {
-  FrameTestHelpers::TestWebViewClient view_client;
-  FrameTestHelpers::TestWebRemoteFrameClient remote_client;
-  WebView* view = WebView::Create(&view_client, kWebPageVisibilityStateVisible);
-  view->GetSettings()->SetJavaScriptEnabled(true);
-  view->SetMainFrame(remote_client.GetFrame());
-  WebRemoteFrame* root = view->MainFrame()->ToWebRemoteFrame();
-  root->SetReplicatedOrigin(SecurityOrigin::CreateUnique());
+  FrameTestHelpers::WebViewHelper helper;
+  helper.InitializeRemote();
 
-  WebLocalFrameBase* local_frame = FrameTestHelpers::CreateLocalChild(root);
+  WebLocalFrameBase* local_frame =
+      FrameTestHelpers::CreateLocalChild(*helper.RemoteMainFrame());
   FrameTestHelpers::LoadFrame(local_frame, "data:text/html,some page");
 
   // Local frame with remote parent should have transparent baseBackgroundColor.
   Color color = local_frame->GetFrameView()->BaseBackgroundColor();
   EXPECT_EQ(Color::kTransparent, color);
-
-  view->Close();
 }
 
 class TestFallbackWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
@@ -12151,7 +11969,7 @@
       const WebParsedFeaturePolicy& container_policy,
       const WebFrameOwnerProperties& frameOwnerProperties) override {
     DCHECK(child_client_);
-    return CreateLocalChild(parent, scope, child_client_);
+    return CreateLocalChild(*parent, scope, child_client_);
   }
 
   WebNavigationPolicy DecidePolicyForNavigation(
diff --git a/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp b/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp
index eeea020..774217e 100644
--- a/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp
@@ -54,8 +54,8 @@
     testing::RunPendingTasks();
   }
 
-  FrameTestHelpers::WebViewHelper helper_;
   WebHelperPluginFrameClient frame_client_;
+  FrameTestHelpers::WebViewHelper helper_;
   WebHelperPluginUniquePtr plugin_;
 };
 
@@ -65,7 +65,6 @@
   EXPECT_TRUE(plugin_);
   EXPECT_TRUE(plugin_->GetPlugin());
 
-  helper_.Reset();
   DestroyHelperPlugin();
 }
 
@@ -76,7 +75,6 @@
   EXPECT_TRUE(plugin_->GetPlugin());
 
   DestroyHelperPlugin();
-  helper_.Reset();
 }
 
 TEST_F(WebHelperPluginTest, CreateFailsWithPlaceholder) {
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
index 81092e6..38be0df0 100644
--- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -142,7 +142,7 @@
       WebSandboxFlags sandbox_flags,
       const WebParsedFeaturePolicy& container_policy,
       const WebFrameOwnerProperties&) {
-    return CreateLocalChild(parent, scope,
+    return CreateLocalChild(*parent, scope,
                             WTF::MakeUnique<TestPluginWebFrameClient>());
   }