diff --git a/DEPS b/DEPS
index cd0d480..1ad950f 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': 'a640c49b7ecf667696542143edec96d10a940592',
+  'skia_revision': 'db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9',
   # 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': 'a3ef78d95b65ad153b14a9d3a7cc1baf35c18660',
+  'v8_revision': 'ec37390b2ba2b4051f46f153a8cc179ed4656f5d',
   # 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.
@@ -52,7 +52,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '9d815378191a5c99cd0bbca2ef9fb2e154944b79',
+  'angle_revision': '9df395c86494d760fb4caf20177ad7b6d1ca2b3f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '8ac74971a33520afb73a8ca6628da1a0a78c85a8',
+  'pdfium_revision': '5b2092a1ec59077b430bd2cab91554cad2eb5128',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -72,7 +72,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': '6881ec04656ce1829136b3412afbf5f84287f476',
+  'boringssl_revision': '683ffbbe57de2163b24993e0d03650cf393bc640',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '7370e9da6e0c2cc11d817dd7bbaeee0a5410f97c',
+  'catapult_revision': '49fbcfa16b5d148a595cc50036d5e8354739f13f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -151,7 +151,7 @@
     Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
 
   'src/third_party/crc32c/src':
-    Var('chromium_git') + '/external/github.com/google/crc32c.git' + '@' + 'db73a3f73581c6d5cbc290e8d92bdcfe653c8099',
+    Var('chromium_git') + '/external/github.com/google/crc32c.git' + '@' + '9bc7a0cada31f3224779b7ba7f56cc7382758e54',
 
   'src/third_party/depot_tools':
     Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b2e961b1171d9f27278461a0a3286ab89161368c',
@@ -271,7 +271,7 @@
     Var('chromium_git') + '/chromium/deps/mesa.git' + '@' + 'ef811c6bd4de74e13e7035ca882cc77f85793fef',
 
   'src/third_party/ced/src':
-    Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + '910cca22d881b02cbc8950fa02ccbcdcfb782456',
+    Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + '94c367a1fe3a13207f4b22604fcfd1d9f9ddf6d9',
 
   'src/third_party/swiftshader':
     Var('swiftshader_git') + '/SwiftShader.git' + '@' +  Var('swiftshader_revision'),
diff --git a/ash/system/network/network_icon.cc b/ash/system/network/network_icon.cc
index ad1d270..5bbce5e 100644
--- a/ash/system/network/network_icon.cc
+++ b/ash/system/network/network_icon.cc
@@ -890,6 +890,13 @@
 
   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
 
+  // Never show messages if the list of Cellular networks is non-empty.
+  NetworkStateHandler::NetworkStateList cellular_networks;
+  handler->GetVisibleNetworkListByType(chromeos::NetworkTypePattern::Cellular(),
+                                       &cellular_networks);
+  if (!cellular_networks.empty())
+    return 0;
+
   if (handler->GetTechnologyState(NetworkTypePattern::Cellular()) ==
       NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) {
     s_uninitialized_msg = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR;
diff --git a/ash/system/network/network_icon_unittest.cc b/ash/system/network/network_icon_unittest.cc
index f87f225..3a036ae9 100644
--- a/ash/system/network/network_icon_unittest.cc
+++ b/ash/system/network/network_icon_unittest.cc
@@ -175,14 +175,16 @@
   EXPECT_EQ(0, GetCellularUninitializedMsg());
 }
 
-TEST_F(NetworkIconTest, GetCellularUninitializedMsg_CellularUninitialized) {
+TEST_F(NetworkIconTest,
+       GetCellularUninitializedMsg_CellularUninitialized_NoMobileNetworks) {
   SetCellularUninitialized();
 
   EXPECT_EQ(IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR,
             GetCellularUninitializedMsg());
 }
 
-TEST_F(NetworkIconTest, GetCellularUninitializedMsg_CellularScanning) {
+TEST_F(NetworkIconTest,
+       GetCellularUninitializedMsg_CellularScanning_NoMobileNetworks) {
   SetCellularUninitialized();
 
   test_manager_client()->AddTechnology(shill::kTypeCellular, true);
diff --git a/ash/wm/cursor_manager_chromeos.cc b/ash/wm/cursor_manager_chromeos.cc
index 04ccd8a..914d8fff 100644
--- a/ash/wm/cursor_manager_chromeos.cc
+++ b/ash/wm/cursor_manager_chromeos.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/logging.h"
+#include "ui/aura/env.h"
 #include "ui/events/event.h"
 #include "ui/keyboard/keyboard_util.h"
 #include "ui/wm/core/cursor_manager.h"
@@ -25,6 +26,10 @@
   if (event.type() != ui::ET_KEY_PRESSED)
     return false;
 
+  // Do not hide cursor when clicking the key with mouse button pressed.
+  if (aura::Env::GetInstance()->IsMouseButtonDown())
+    return false;
+
   // Clicking on a key when the accessibility virtual keyboard is enabled should
   // not hide the cursor.
   if (keyboard::GetAccessibilityKeyboardEnabled())
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc
index 7410f28..e31ce7e8 100644
--- a/ash/wm/overview/window_selector_unittest.cc
+++ b/ash/wm/overview/window_selector_unittest.cc
@@ -173,10 +173,6 @@
     return window_selector_controller()->window_selector_.get();
   }
 
-  SplitViewController* split_view_controller() {
-    return Shell::Get()->split_view_controller();
-  }
-
   void ToggleOverview() { window_selector_controller()->ToggleOverview(); }
 
   aura::Window* GetOverviewWindowForMinimizedState(int index,
@@ -337,14 +333,6 @@
     return window_selector()->text_filter_widget_.get();
   }
 
-  gfx::Rect GetSplitViewLeftWindowBounds(aura::Window* window) {
-    return split_view_controller()->GetLeftWindowBoundsInScreen(window);
-  }
-
-  gfx::Rect GetSplitViewRightWindowBounds(aura::Window* window) {
-    return split_view_controller()->GetRightWindowBoundsInScreen(window);
-  }
-
   gfx::Rect GetGridBounds() {
     if (window_selector())
       return window_selector()->grid_list_[0]->bounds_;
@@ -1929,14 +1917,47 @@
   resizer->RevertDrag();
 }
 
+class SplitViewWindowSelectorTest : public WindowSelectorTest {
+ public:
+  SplitViewWindowSelectorTest() = default;
+  ~SplitViewWindowSelectorTest() override = default;
+
+  void SetUp() override {
+    WindowSelectorTest::SetUp();
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        switches::kAshEnableTabletSplitView);
+    Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
+  }
+
+  void TearDown() override {
+    // TODO(sammiequon|xdai): There is a memory leak if we tear down while
+    // overview mode is active. Investigate.
+    if (window_selector_controller()->IsSelecting())
+      ToggleOverview();
+    WindowSelectorTest::TearDown();
+  }
+
+  SplitViewController* split_view_controller() {
+    return Shell::Get()->split_view_controller();
+  }
+
+ protected:
+  gfx::Rect GetSplitViewLeftWindowBounds(aura::Window* window) {
+    return split_view_controller()->GetLeftWindowBoundsInScreen(window);
+  }
+
+  gfx::Rect GetSplitViewRightWindowBounds(aura::Window* window) {
+    return split_view_controller()->GetRightWindowBoundsInScreen(window);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SplitViewWindowSelectorTest);
+};
+
 // Tests that dragging a overview window selector item to the edge of the screen
 // snaps the window. If two windows are snapped to left and right side of the
 // screen, exit the overview mode.
-TEST_F(WindowSelectorTest, DragOverviewWindowToSnap) {
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshEnableTabletSplitView);
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
-
+TEST_F(SplitViewWindowSelectorTest, DragOverviewWindowToSnap) {
   const gfx::Rect bounds(0, 0, 400, 400);
   std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
   std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
@@ -1944,7 +1965,7 @@
 
   ToggleOverview();
   EXPECT_TRUE(window_selector_controller()->IsSelecting());
-  EXPECT_EQ(split_view_controller()->IsSplitViewModeActive(), false);
+  EXPECT_FALSE(split_view_controller()->IsSplitViewModeActive());
 
   // Drag |window1| selector item to snap to left.
   const int grid_index = 0;
@@ -1958,7 +1979,7 @@
   window_selector()->Drag(selector_item1, end_location1);
   window_selector()->CompleteDrag(selector_item1);
 
-  EXPECT_EQ(split_view_controller()->IsSplitViewModeActive(), true);
+  EXPECT_TRUE(split_view_controller()->IsSplitViewModeActive());
   EXPECT_EQ(split_view_controller()->state(),
             SplitViewController::LEFT_SNAPPED);
   EXPECT_EQ(split_view_controller()->left_window(), window1.get());
@@ -1999,13 +2020,8 @@
 
 // Verify the window grid size changes as expected when dragging items around in
 // overview mode when split view is enabled.
-TEST_F(WindowSelectorTest, WindowGridSizeWhileDraggingWithSplitView) {
-  // Enable split view, enter maximize mode, add some windows and enter overview
-  // mode.
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshEnableTabletSplitView);
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
-
+TEST_F(SplitViewWindowSelectorTest, WindowGridSizeWhileDraggingWithSplitView) {
+  // Add three windows and enter overview mode.
   const gfx::Rect bounds(0, 0, 400, 400);
   std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
   std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
@@ -2069,18 +2085,10 @@
   EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds());
   window_selector()->Drag(selector_item, center);
   EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds());
-
-  ToggleOverview();
 }
 
 // Tests dragging a unsnappable window.
-TEST_F(WindowSelectorTest, DraggingNonSnapableAppWithSplitView) {
-  // Enable split view, enter maximize mode, add a unsnappable window and enter
-  // overview mode.
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshEnableTabletSplitView);
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
-
+TEST_F(SplitViewWindowSelectorTest, DraggingNonSnapableAppWithSplitView) {
   const gfx::Rect bounds(0, 0, 400, 400);
   std::unique_ptr<aura::Window> unsnappable_window(CreateWindow(bounds));
   unsnappable_window->SetProperty(aura::client::kResizeBehaviorKey,
@@ -2111,17 +2119,12 @@
   window_selector()->Drag(selector_item,
                           gfx::Point(root_window_bounds.right() / 2, 0));
   EXPECT_EQ(expected_grid_bounds, GetGridBounds());
-
-  ToggleOverview();
 }
 
 // Tests that if there is only one window in the MRU window list in the overview
 // mode, snapping the window to one side of the screen will end the overview
 // mode since there is no more window left in the overview window grid.
-TEST_F(WindowSelectorTest, EmptyWindowsListExitOverview) {
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshEnableTabletSplitView);
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
+TEST_F(SplitViewWindowSelectorTest, EmptyWindowsListExitOverview) {
   const gfx::Rect bounds(0, 0, 400, 400);
   std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
 
@@ -2147,11 +2150,7 @@
 }
 
 // Verify that the split view overview overlay is shown when expected.
-TEST_F(WindowSelectorTest, SplitViewOverviewOverlayVisibility) {
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshEnableTabletSplitView);
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
-
+TEST_F(SplitViewWindowSelectorTest, SplitViewOverviewOverlayVisibility) {
   const gfx::Rect bounds(0, 0, 400, 400);
   std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
   std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
@@ -2187,11 +2186,7 @@
 
 // Verify that the split view overview overlays widget reparents when starting a
 // drag on a different display.
-TEST_F(WindowSelectorTest, SplitViewOverviewOverlayWidgetReparenting) {
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshEnableTabletSplitView);
-  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
-
+TEST_F(SplitViewWindowSelectorTest, SplitViewOverviewOverlayWidgetReparenting) {
   // Add two displays and one window on each display.
   UpdateDisplay("600x600,600x600");
   auto root_windows = Shell::Get()->GetAllRootWindows();
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h
index d2f8a63..6ac22f88 100644
--- a/ash/wm/splitview/split_view_controller.h
+++ b/ash/wm/splitview/split_view_controller.h
@@ -22,7 +22,7 @@
 
 class SplitViewControllerTest;
 class SplitViewDivider;
-class WindowSelectorTest;
+class SplitViewWindowSelectorTest;
 
 // The controller for the split view. It snaps a window to left/right side of
 // the screen. It also observes the two snapped windows and decides when to exit
@@ -107,7 +107,7 @@
 
  private:
   friend class SplitViewControllerTest;
-  friend class WindowSelectorTest;
+  friend class SplitViewWindowSelectorTest;
 
   // Ends the split view mode.
   void EndSplitView();
diff --git a/ash/wm/splitview/split_view_overview_overlay.h b/ash/wm/splitview/split_view_overview_overlay.h
index f4f0965c..beaaa86 100644
--- a/ash/wm/splitview/split_view_overview_overlay.h
+++ b/ash/wm/splitview/split_view_overview_overlay.h
@@ -32,7 +32,7 @@
   bool visible() const;
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(WindowSelectorTest,
+  FRIEND_TEST_ALL_PREFIXES(SplitViewWindowSelectorTest,
                            SplitViewOverviewOverlayWidgetReparenting);
   class SplitViewOverviewOverlayView;
 
diff --git a/ash/wm/window_manager_unittest.cc b/ash/wm/window_manager_unittest.cc
index 4553c66..8a7b31a 100644
--- a/ash/wm/window_manager_unittest.cc
+++ b/ash/wm/window_manager_unittest.cc
@@ -772,7 +772,7 @@
   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
 }
 
-// Cursor is hidden on keypress.
+// Tests cursor visibility on key pressed event.
 TEST_F(WindowManagerTest, UpdateCursorVisibilityOnKeyEvent) {
   // TODO: mash doesn't support CursorManager. http://crbug.com/631103.
   if (Shell::GetAshConfig() == Config::MASH)
@@ -794,6 +794,14 @@
   generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE);
   EXPECT_TRUE(cursor_manager->IsCursorVisible());
   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+  // Pressing a key with mouse button pressed does not hide the cursor and does
+  // not disable mouse events.
+  generator.PressLeftButton();
+  generator.PressKey(ui::VKEY_A, ui::EF_NONE);
+  generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE);
+  generator.ReleaseLeftButton();
+  EXPECT_TRUE(cursor_manager->IsCursorVisible());
+  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
 }
 
 // Test that pressing an accelerator does not hide the cursor.
diff --git a/base/location.cc b/base/location.cc
index e14b375..51a9d933 100644
--- a/base/location.cc
+++ b/base/location.cc
@@ -2,15 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "build/build_config.h"
+#include "base/location.h"
 
 #if defined(COMPILER_MSVC)
 #include <intrin.h>
 #endif
 
-#include "base/location.h"
+#include "base/compiler_specific.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
+#include "build/build_config.h"
 
 namespace base {
 
@@ -77,18 +78,30 @@
 
 LocationSnapshot::~LocationSnapshot() = default;
 
-//------------------------------------------------------------------------------
 #if defined(COMPILER_MSVC)
-__declspec(noinline)
-#endif
-BASE_EXPORT const void* GetProgramCounter() {
-#if defined(COMPILER_MSVC)
-  return _ReturnAddress();
+#define RETURN_ADDRESS() _ReturnAddress()
 #elif defined(COMPILER_GCC) && !defined(OS_NACL)
-  return __builtin_extract_return_addr(__builtin_return_address(0));
+#define RETURN_ADDRESS() \
+  __builtin_extract_return_addr(__builtin_return_address(0))
 #else
-  return nullptr;
+#define RETURN_ADDRESS() nullptr
 #endif
+
+// static
+NOINLINE Location Location::CreateFromHere(const char* file_name) {
+  return Location(file_name, RETURN_ADDRESS());
+}
+
+// static
+NOINLINE Location Location::CreateFromHere(const char* function_name,
+                                           const char* file_name,
+                                           int line_number) {
+  return Location(function_name, file_name, line_number, RETURN_ADDRESS());
+}
+
+//------------------------------------------------------------------------------
+NOINLINE const void* GetProgramCounter() {
+  return RETURN_ADDRESS();
 }
 
 }  // namespace base
diff --git a/base/location.h b/base/location.h
index bfe421d0..5337792a 100644
--- a/base/location.h
+++ b/base/location.h
@@ -77,6 +77,11 @@
   void Write(bool display_filename, bool display_function_name,
              std::string* output) const;
 
+  static Location CreateFromHere(const char* file_name);
+  static Location CreateFromHere(const char* function_name,
+                                 const char* file_name,
+                                 int line_number);
+
  private:
   const char* function_name_ = nullptr;
   const char* file_name_ = nullptr;
@@ -105,15 +110,14 @@
 // Full source information should be included.
 #define FROM_HERE FROM_HERE_WITH_EXPLICIT_FUNCTION(__func__)
 #define FROM_HERE_WITH_EXPLICIT_FUNCTION(function_name) \
-  ::base::Location(function_name, __FILE__, __LINE__,   \
-                   ::base::GetProgramCounter())
+  ::base::Location::CreateFromHere(function_name, __FILE__, __LINE__)
 
 #else
 
 // TODO(http://crbug.com/760702) remove the __FILE__ argument from these calls.
-#define FROM_HERE ::base::Location(__FILE__, ::base::GetProgramCounter())
+#define FROM_HERE ::base::Location::CreateFromHere(__FILE__)
 #define FROM_HERE_WITH_EXPLICIT_FUNCTION(function_name) \
-  ::base::Location(function_name, __FILE__, -1, ::base::GetProgramCounter())
+  ::base::Location::CreateFromHere(function_name, __FILE__, -1)
 
 #endif
 
diff --git a/base/message_loop/incoming_task_queue.cc b/base/message_loop/incoming_task_queue.cc
index c9045d8..a3df077 100644
--- a/base/message_loop/incoming_task_queue.cc
+++ b/base/message_loop/incoming_task_queue.cc
@@ -114,8 +114,14 @@
 }
 
 void IncomingTaskQueue::WillDestroyCurrentMessageLoop() {
-  base::subtle::AutoWriteLock lock(message_loop_lock_);
-  message_loop_ = NULL;
+  {
+    AutoLock auto_lock(incoming_queue_lock_);
+    accept_new_tasks_ = false;
+  }
+  {
+    AutoLock auto_lock(message_loop_lock_);
+    message_loop_ = nullptr;
+  }
 }
 
 void IncomingTaskQueue::StartScheduling() {
@@ -149,56 +155,70 @@
   // Warning: Don't try to short-circuit, and handle this thread's tasks more
   // directly, as it could starve handling of foreign threads.  Put every task
   // into this queue.
+  bool accept_new_tasks;
+  bool schedule_work = false;
+  {
+    AutoLock auto_lock(incoming_queue_lock_);
+    accept_new_tasks = accept_new_tasks_;
+    if (accept_new_tasks)
+      schedule_work = PostPendingTaskLockRequired(pending_task);
+  }
 
-  // Ensures |message_loop_| isn't destroyed while running.
-  base::subtle::AutoReadLock hold_message_loop(message_loop_lock_);
-
-  if (!message_loop_) {
+  if (!accept_new_tasks) {
+    // Clear the pending task outside of |incoming_queue_lock_| to prevent any
+    // chance of self-deadlock if destroying a task also posts a task to this
+    // queue.
+    DCHECK(!schedule_work);
     pending_task->task.Reset();
     return false;
   }
 
-  bool schedule_work = false;
-  {
-    AutoLock hold(incoming_queue_lock_);
-
-#if defined(OS_WIN)
-    if (pending_task->is_high_res)
-      ++high_res_task_count_;
-#endif
-
-    // Initialize the sequence number. The sequence number is used for delayed
-    // tasks (to facilitate FIFO sorting when two tasks have the same
-    // delayed_run_time value) and for identifying the task in about:tracing.
-    pending_task->sequence_num = next_sequence_num_++;
-
-    task_annotator_.DidQueueTask("MessageLoop::PostTask", *pending_task);
-
-    bool was_empty = incoming_queue_.empty();
-    incoming_queue_.push(std::move(*pending_task));
-
-    if (is_ready_for_scheduling_ &&
-        (always_schedule_work_ || (!message_loop_scheduled_ && was_empty))) {
-      schedule_work = true;
-      // After we've scheduled the message loop, we do not need to do so again
-      // until we know it has processed all of the work in our queue and is
-      // waiting for more work again. The message loop will always attempt to
-      // reload from the incoming queue before waiting again so we clear this
-      // flag in ReloadWorkQueue().
-      message_loop_scheduled_ = true;
-    }
+  // Wake up the message loop and schedule work. This is done outside
+  // |incoming_queue_lock_| to allow for multiple post tasks to occur while
+  // ScheduleWork() is running. For platforms (e.g. Android) that require one
+  // call to ScheduleWork() for each task, all pending tasks may serialize
+  // within the ScheduleWork() call. As a result, holding a lock to maintain the
+  // lifetime of |message_loop_| is less of a concern.
+  if (schedule_work) {
+    // Ensures |message_loop_| isn't destroyed while running.
+    AutoLock auto_lock(message_loop_lock_);
+    if (message_loop_)
+      message_loop_->ScheduleWork();
   }
 
-  // Wake up the message loop and schedule work. This is done outside
-  // |incoming_queue_lock_| because signaling the message loop may cause this
-  // thread to be switched. If |incoming_queue_lock_| is held, any other thread
-  // that wants to post a task will be blocked until this thread switches back
-  // in and releases |incoming_queue_lock_|.
-  if (schedule_work)
-    message_loop_->ScheduleWork();
-
   return true;
 }
 
+bool IncomingTaskQueue::PostPendingTaskLockRequired(PendingTask* pending_task) {
+  incoming_queue_lock_.AssertAcquired();
+
+#if defined(OS_WIN)
+  if (pending_task->is_high_res)
+    ++high_res_task_count_;
+#endif
+
+  // Initialize the sequence number. The sequence number is used for delayed
+  // tasks (to facilitate FIFO sorting when two tasks have the same
+  // delayed_run_time value) and for identifying the task in about:tracing.
+  pending_task->sequence_num = next_sequence_num_++;
+
+  task_annotator_.DidQueueTask("MessageLoop::PostTask", *pending_task);
+
+  bool was_empty = incoming_queue_.empty();
+  incoming_queue_.push(std::move(*pending_task));
+
+  if (is_ready_for_scheduling_ &&
+      (always_schedule_work_ || (!message_loop_scheduled_ && was_empty))) {
+    // After we've scheduled the message loop, we do not need to do so again
+    // until we know it has processed all of the work in our queue and is
+    // waiting for more work again. The message loop will always attempt to
+    // reload from the incoming queue before waiting again so we clear this
+    // flag in ReloadWorkQueue().
+    message_loop_scheduled_ = true;
+    return true;
+  }
+  return false;
+}
+
 }  // namespace internal
 }  // namespace base
diff --git a/base/message_loop/incoming_task_queue.h b/base/message_loop/incoming_task_queue.h
index 35e1c31..aac120d7d 100644
--- a/base/message_loop/incoming_task_queue.h
+++ b/base/message_loop/incoming_task_queue.h
@@ -13,7 +13,6 @@
 #include "base/pending_task.h"
 #include "base/sequence_checker.h"
 #include "base/synchronization/lock.h"
-#include "base/synchronization/read_write_lock.h"
 #include "base/time/time.h"
 
 namespace base {
@@ -70,6 +69,10 @@
   // does not retain |pending_task->task| beyond this function call.
   bool PostPendingTask(PendingTask* pending_task);
 
+  // Does the real work of posting a pending task. Returns true if the caller
+  // should call ScheduleWork() on the message loop.
+  bool PostPendingTaskLockRequired(PendingTask* pending_task);
+
   // Wakes up the message loop and schedules work.
   void ScheduleWork();
 
@@ -83,9 +86,9 @@
   // |message_loop_|.
   base::Lock incoming_queue_lock_;
 
-  // Lock that protects |message_loop_| to prevent it from being deleted while a
-  // task is being posted.
-  base::subtle::ReadWriteLock message_loop_lock_;
+  // Lock that protects |message_loop_| to prevent it from being deleted while
+  // a request is made to schedule work.
+  base::Lock message_loop_lock_;
 
   // An incoming queue of tasks that are acquired under a mutex for processing
   // on this instance's thread. These tasks have not yet been been pushed to
@@ -95,6 +98,9 @@
   // Points to the message loop that owns |this|.
   MessageLoop* message_loop_;
 
+  // True if new tasks should be accepted.
+  bool accept_new_tasks_ = true;
+
   // The next sequence number to use for delayed tasks.
   int next_sequence_num_;
 
diff --git a/base/trace_event/memory_infra_background_whitelist.cc b/base/trace_event/memory_infra_background_whitelist.cc
index 8b753338..2c7fdb79 100644
--- a/base/trace_event/memory_infra_background_whitelist.cc
+++ b/base/trace_event/memory_infra_background_whitelist.cc
@@ -235,6 +235,9 @@
     "tab_restore/service_helper_0x?/entries",
     "tab_restore/service_helper_0x?/entries/tab_0x?",
     "tab_restore/service_helper_0x?/entries/window_0x?",
+    "tracing/heap_profiler_blink_gc/AllocationRegister",
+    "tracing/heap_profiler_malloc/AllocationRegister",
+    "tracing/heap_profiler_partition_alloc/AllocationRegister",
     nullptr  // End of list marker.
 };
 
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index a154baf..1c9d3e6 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -573,17 +573,10 @@
       }
     }
 
-    // Update event filters.
-    if (modes_to_enable & FILTERING_MODE) {
-      DCHECK(!trace_config.event_filters().empty())
-          << "Attempting to enable filtering without any filters";
-      DCHECK(enabled_event_filters_.empty()) << "Attempting to re-enable "
-                                                "filtering when filters are "
-                                                "already enabled.";
-
-      // Use the given event filters only if filtering was not enabled.
-      if (enabled_event_filters_.empty())
-        enabled_event_filters_ = trace_config.event_filters();
+    // Update event filters only if filtering was not enabled.
+    if (modes_to_enable & FILTERING_MODE && enabled_event_filters_.empty()) {
+      DCHECK(!trace_config.event_filters().empty());
+      enabled_event_filters_ = trace_config.event_filters();
     }
     // Keep the |trace_config_| updated with only enabled filters in case anyone
     // tries to read it using |GetCurrentTraceConfig| (even if filters are
diff --git a/build/fuchsia/runner_common.py b/build/fuchsia/runner_common.py
index 48e8fda2..ae4081a6 100755
--- a/build/fuchsia/runner_common.py
+++ b/build/fuchsia/runner_common.py
@@ -342,6 +342,26 @@
   return map(lambda entry: symbolized[entry['frame_id']], backtrace)
 
 
+def _EnsureTunTap(dry_run):
+  """Make sure the tun/tap device is configured. This cannot be done
+  automatically because it requires sudo, unfortunately, so we just print out
+  instructions.
+  """
+  with open(os.devnull, 'w') as nul:
+    p = subprocess.Popen(
+        ['tunctl', '-b', '-u', os.environ.get('USER'), '-t', 'qemu'],
+        stdout=subprocess.PIPE, stderr=nul)
+    output = p.communicate()[0].strip()
+  if output != 'qemu':
+    print 'Configuration of tun/tap device required:'
+    if not os.path.isfile('/usr/sbin/tunctl'):
+      print 'sudo apt-get install uml-utilities'
+    print 'sudo tunctl -u $USER -t qemu'
+    print 'sudo ifconfig qemu up'
+    return False
+  return True
+
+
 def RunFuchsia(bootfs_data, use_device, dry_run, test_launcher_summary_output):
   kernel_path = os.path.join(SDK_ROOT, 'kernel', 'magenta.bin')
 
@@ -353,6 +373,9 @@
                           bootfs_data.bootfs]
     return _RunAndCheck(dry_run, bootserver_command)
 
+  if not _EnsureTunTap(dry_run):
+    return 1
+
   qemu_path = os.path.join(SDK_ROOT, 'qemu', 'bin', 'qemu-system-x86_64')
   qemu_command = [qemu_path,
       '-m', '2048',
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 86d05b6..c4b120c4 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2016,9 +2016,7 @@
   // Adjust the viewport layers by shrinking/expanding the container to account
   // for changes in the size (e.g. browser controls) since the last resize from
   // Blink.
-  gfx::Vector2dF amount_to_expand(
-      0.f,
-      delta_from_top_controls * active_tree_->painted_device_scale_factor());
+  gfx::Vector2dF amount_to_expand(0.f, delta_from_top_controls);
   inner_container->SetViewportBoundsDelta(amount_to_expand);
 
   if (outer_container && !outer_container->BoundsForScrolling().IsEmpty()) {
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index a25d09d..05ed957 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -5092,40 +5092,6 @@
   ASSERT_EQ(0, host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
 }
 
-TEST_F(LayerTreeHostImplBrowserControlsTest, ViewportBoundsUseZoomForDSF) {
-  SetupBrowserControlsAndScrollLayerWithVirtualViewport(
-      gfx::Size(50, 50), gfx::Size(100, 100), gfx::Size(100, 100));
-  DrawFrame();
-
-  LayerImpl* inner_container =
-      host_impl_->active_tree()->InnerViewportContainerLayer();
-
-  gfx::Vector2dF scroll_delta(0.f, 10.f);
-  EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
-            host_impl_
-                ->ScrollBegin(BeginState(gfx::Point()).get(),
-                              InputHandler::TOUCHSCREEN)
-                .thread);
-  host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
-
-  gfx::Vector2dF bounds_delta = inner_container->ViewportBoundsDelta();
-  host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f);
-  host_impl_->ScrollEnd(EndState().get());
-
-  float device_scale = 3.5f;
-  host_impl_->active_tree()->set_painted_device_scale_factor(device_scale);
-
-  EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
-            host_impl_
-                ->ScrollBegin(BeginState(gfx::Point()).get(),
-                              InputHandler::TOUCHSCREEN)
-                .thread);
-  host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
-
-  bounds_delta.Scale(device_scale);
-  EXPECT_EQ(bounds_delta, inner_container->ViewportBoundsDelta());
-}
-
 // Test that if only the browser controls are scrolled, we shouldn't request a
 // commit.
 TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsDontTriggerCommit) {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index baaee3e..7713514 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1133,7 +1133,7 @@
     "sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java",
     "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java",
     "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java",
-    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java",
     "sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java",
     "sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java",
   ]
@@ -1152,8 +1152,10 @@
     "//components/sync/android:sync_java",
     "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
+    "//third_party/android_support_test_runner:rules_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/android_tools:android_support_v7_appcompat_java",
+    "//third_party/junit",
     "//ui/android:ui_java",
   ]
   proguard_enabled = !is_java_debug
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java
index 942b76f..715b3d3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java
@@ -47,7 +47,14 @@
      * Stop the foreground service that is running.
      */
     public void stopDownloadForegroundService(boolean isCancelled) {
-        stopForeground(isCancelled /* kill notification if cancelled */);
+        // If it's not cancelled, just detach the notification from the service, if possible.
+        if (!isCancelled && Build.VERSION.SDK_INT >= 24) {
+            stopForeground(STOP_FOREGROUND_DETACH);
+            return;
+        }
+
+        // Otherwise, just stop the foreground and correct it elsewhere.
+        stopForeground(true);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java
index b4783fa6..7d24bfea 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java
@@ -197,28 +197,38 @@
             // This does not happen for API >= 24.
             if (mPinnedNotificationId != INVALID_NOTIFICATION_ID
                     && mPinnedNotificationId != notificationId && Build.VERSION.SDK_INT < 24) {
-                NotificationManager notificationManager =
-                        (NotificationManager) ContextUtils.getApplicationContext().getSystemService(
-                                Context.NOTIFICATION_SERVICE);
-                notificationManager.notify(mPinnedNotificationId,
-                        mDownloadUpdateQueue.get(mPinnedNotificationId).mNotification);
+                relaunchPinnedNotification();
             }
 
             mPinnedNotificationId = notificationId;
         }
     }
 
+    private void relaunchPinnedNotification() {
+        NotificationManager notificationManager =
+                (NotificationManager) ContextUtils.getApplicationContext().getSystemService(
+                        Context.NOTIFICATION_SERVICE);
+        notificationManager.notify(mPinnedNotificationId,
+                mDownloadUpdateQueue.get(mPinnedNotificationId).mNotification);
+    }
+
     /** Helper code to stop and unbind service. */
 
     @VisibleForTesting
     void stopAndUnbindService(boolean isCancelled) {
         mIsServiceBound = false;
-        mPinnedNotificationId = INVALID_NOTIFICATION_ID;
 
         if (mBoundService != null) {
             stopAndUnbindServiceInternal(isCancelled);
             mBoundService = null;
         }
+
+        // If the download isn't cancelled,  need to relaunch the notification so it is no longer
+        // pinned to the foreground service.
+        if (!isCancelled && Build.VERSION.SDK_INT < 24) {
+            relaunchPinnedNotification();
+        }
+        mPinnedNotificationId = INVALID_NOTIFICATION_ID;
     }
 
     @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService2.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService2.java
index 7f626b0..0f7cc660 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService2.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService2.java
@@ -320,16 +320,16 @@
         Notification notification = DownloadNotificationFactory.buildNotification(
                 context, DownloadNotificationFactory.DownloadStatus.PAUSED, downloadUpdate);
 
-        updateNotification(notificationId, notification, id,
-                new DownloadSharedPreferenceEntry(id, notificationId, isOffTheRecord,
-                        canDownloadWhileMetered, fileName, isAutoResumable, isTransient));
-
         // If called from DownloadBroadcastManager, only update notification, not tracking.
         if (hasUserGesture) {
             updateNotification(notificationId, notification);
             return;
         }
 
+        updateNotification(notificationId, notification, id,
+                new DownloadSharedPreferenceEntry(id, notificationId, isOffTheRecord,
+                        canDownloadWhileMetered, fileName, isAutoResumable, isTransient));
+
         mDownloadForegroundServiceManager.updateDownloadStatus(context,
                 DownloadForegroundServiceManager.DownloadStatus.PAUSE, notificationId,
                 notification);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
index c63de9fb..de90b31 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
@@ -391,6 +391,8 @@
         intent.putExtra(Browser.EXTRA_APPLICATION_ID, packageName);
         if (params.isOpenInNewTab()) intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        // Ensure intents re-target potential caller activity when we run in Herb/CCT mode.
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         mDelegate.maybeSetWindowId(intent);
         mDelegate.maybeRecordAppHandlersInIntent(intent, resolvingInfos);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index 42fd4f9..154b5fb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -280,7 +280,8 @@
             if (preferLightweightFre) {
                 if (!FirstRunStatus.shouldSkipWelcomePage()
                         && !FirstRunStatus.getLightweightFirstRunFlowComplete()) {
-                    return createLightweightFirstRunIntent(context, fromChromeIcon);
+                    return createFirstRunIntent(
+                            context, LightweightFirstRunActivity.class.getName(), fromChromeIcon);
                 }
             } else {
                 return createGenericFirstRunIntent(context, fromChromeIcon);
@@ -291,21 +292,25 @@
         return null;
     }
 
-    private static Intent createLightweightFirstRunIntent(Context context, boolean fromChromeIcon) {
-        Intent intent = new Intent();
-        intent.setClassName(context, LightweightFirstRunActivity.class.getName());
-        intent.putExtra(FirstRunActivity.EXTRA_COMING_FROM_CHROME_ICON, fromChromeIcon);
-        return intent;
-    }
-
     /**
      * @return A generic intent to show the First Run Activity.
      * @param context        The context.
      * @param fromChromeIcon Whether Chrome is opened via the Chrome icon.
-    */
+     */
     public static Intent createGenericFirstRunIntent(Context context, boolean fromChromeIcon) {
+        return createFirstRunIntent(context, FirstRunActivity.class.getName(), fromChromeIcon);
+    }
+
+    /**
+     * @return An intent to show the First Run Activity.
+     * @param context                   The context.
+     * @param firstRunActivityClassName The class name of the first run activity to start.
+     * @param fromChromeIcon            Whether Chrome is opened via the Chrome icon.
+     */
+    public static Intent createFirstRunIntent(
+            Context context, String firstRunActivityClassName, boolean fromChromeIcon) {
         Intent intent = new Intent();
-        intent.setClassName(context, FirstRunActivity.class.getName());
+        intent.setClassName(context, firstRunActivityClassName);
         intent.putExtra(FirstRunActivity.EXTRA_COMING_FROM_CHROME_ICON, fromChromeIcon);
         intent.putExtra(FirstRunActivity.EXTRA_USE_FRE_FLOW_SEQUENCER, true);
         return intent;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
index ecbf83d4..5f9bea9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.firstrun;
 
+import android.os.Bundle;
 import android.text.method.LinkMovementMethod;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -11,9 +12,7 @@
 import android.widget.Button;
 import android.widget.TextView;
 
-import org.chromium.base.CommandLine;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.ui.base.LocalizationUtils;
 import org.chromium.ui.text.NoUnderlineClickableSpan;
@@ -24,43 +23,81 @@
 * Lightweight FirstRunActivity. It shows ToS dialog only.
 */
 public class LightweightFirstRunActivity extends FirstRunActivityBase {
+    private FirstRunFlowSequencer mFirstRunFlowSequencer;
+    private Bundle mFreProperties;
     private Button mOkButton;
     private boolean mNativeInitialized;
     private boolean mTriggerAcceptAfterNativeInit;
 
     @Override
     public void setContentView() {
-        if (CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)) {
-            completeFirstRunExperience();
+        Bundle savedInstanceState = getSavedInstanceState();
+        if (savedInstanceState != null) {
+            mFreProperties = savedInstanceState;
+        } else if (getIntent() != null) {
+            mFreProperties = getIntent().getExtras();
+        } else {
+            mFreProperties = new Bundle();
         }
 
         setFinishOnTouchOutside(true);
 
+        mFirstRunFlowSequencer = new FirstRunFlowSequencer(this, mFreProperties) {
+            @Override
+            public void onFlowIsKnown(Bundle freProperties) {
+                if (freProperties == null) {
+                    completeFirstRunExperience();
+                    return;
+                }
+
+                mFreProperties = freProperties;
+                onChildAccountKnown(
+                        mFreProperties.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
+            }
+        };
+        mFirstRunFlowSequencer.start();
+    }
+
+    /** Called once it is known whether the device has a child account. */
+    public void onChildAccountKnown(boolean hasChildAccount) {
         setContentView(LayoutInflater.from(LightweightFirstRunActivity.this)
                                .inflate(R.layout.lightweight_fre_tos, null));
 
         NoUnderlineClickableSpan clickableTermsSpan = new NoUnderlineClickableSpan() {
             @Override
             public void onClick(View widget) {
-                CustomTabActivity.showInfoPage(LightweightFirstRunActivity.this,
-                        LocalizationUtils.substituteLocalePlaceholder(
-                                getString(R.string.chrome_terms_of_service_url)));
+                showInfoPage(R.string.chrome_terms_of_service_url);
             }
         };
         NoUnderlineClickableSpan clickablePrivacySpan = new NoUnderlineClickableSpan() {
             @Override
             public void onClick(View widget) {
-                CustomTabActivity.showInfoPage(LightweightFirstRunActivity.this,
-                        LocalizationUtils.substituteLocalePlaceholder(
-                                getString(R.string.chrome_privacy_notice_url)));
+                showInfoPage(R.string.chrome_privacy_notice_url);
             }
         };
-        ((TextView) findViewById(R.id.lightweight_fre_tos_and_privacy))
-                .setText(SpanApplier.applySpans(getString(R.string.lightweight_fre_tos_and_privacy),
-                        new SpanInfo("<LINK1>", "</LINK1>", clickableTermsSpan),
-                        new SpanInfo("<LINK2>", "</LINK2>", clickablePrivacySpan)));
-        ((TextView) findViewById(R.id.lightweight_fre_tos_and_privacy))
-                .setMovementMethod(LinkMovementMethod.getInstance());
+        NoUnderlineClickableSpan clickableFamilyLinkPrivacySpan = new NoUnderlineClickableSpan() {
+            @Override
+            public void onClick(View widget) {
+                showInfoPage(R.string.family_link_privacy_policy_url);
+            }
+        };
+        final CharSequence tosAndPrivacyText;
+        if (hasChildAccount) {
+            tosAndPrivacyText = SpanApplier.applySpans(
+                    getString(R.string.lightweight_fre_tos_and_privacy_child_account),
+                    new SpanInfo("<LINK1>", "</LINK1>", clickableTermsSpan),
+                    new SpanInfo("<LINK2>", "</LINK2>", clickablePrivacySpan),
+                    new SpanInfo("<LINK3>", "</LINK3>", clickableFamilyLinkPrivacySpan));
+        } else {
+            tosAndPrivacyText =
+                    SpanApplier.applySpans(getString(R.string.lightweight_fre_tos_and_privacy),
+                            new SpanInfo("<LINK1>", "</LINK1>", clickableTermsSpan),
+                            new SpanInfo("<LINK2>", "</LINK2>", clickablePrivacySpan));
+        }
+        TextView tosAndPrivacyTextView =
+                (TextView) findViewById(R.id.lightweight_fre_tos_and_privacy);
+        tosAndPrivacyTextView.setText(tosAndPrivacyText);
+        tosAndPrivacyTextView.setMovementMethod(LinkMovementMethod.getInstance());
 
         mOkButton = (Button) findViewById(R.id.lightweight_fre_terms_accept);
         mOkButton.setOnClickListener(new OnClickListener() {
@@ -89,6 +126,12 @@
     }
 
     @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putAll(mFreProperties);
+    }
+
+    @Override
     public void onBackPressed() {
         abortFirstRunExperience();
     }
@@ -116,4 +159,13 @@
         FirstRunUtils.acceptTermsOfService(false);
         completeFirstRunExperience();
     }
+
+    /**
+     * Show an informational web page. The page doesn't show navigation control.
+     * @param url Resource id for the URL of the web page.
+     */
+    public void showInfoPage(int url) {
+        CustomTabActivity.showInfoPage(
+                this, LocalizationUtils.substituteLocalePlaceholder(getString(url)));
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
index a06540c..4572dc22 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
@@ -86,7 +86,7 @@
                 .setShowWhen(false)
                 .setAutoCancel(false)
                 .setOngoing(true)
-                .setPriority(Notification.PRIORITY_LOW)
+                .setPriority(Notification.PRIORITY_MIN)
                 .setContentIntent(focusIntent)
                 .addAction(R.drawable.ic_share_white_24dp,
                         mWebappActivity.getResources().getString(R.string.share), shareIntent)
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index c145a3ea..40c08b0 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2224,6 +2224,9 @@
       <message name="IDS_LIGHTWEIGHT_FRE_TOS_AND_PRIVACY" desc="Message explaining that use of Chrome is governed by Chrome's terms of service and privacy notice.">
         By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1">&lt;LINK1&gt;</ph>Terms of Service<ph name="END_LINK1">&lt;/LINK1&gt;</ph> and <ph name="BEGIN_LINK2">&lt;LINK2&gt;</ph>Privacy Notice<ph name="END_LINK2">&lt;/LINK2&gt;</ph>.
       </message>
+      <message name="IDS_LIGHTWEIGHT_FRE_TOS_AND_PRIVACY_CHILD_ACCOUNT" desc="Message explaining that use of Chrome is governed by Chrome's terms of service and privacy notice, and Family Link's privacy notice for children.">
+        By continuing, you agree to Chrome's <ph name="BEGIN_LINK1">&lt;LINK1&gt;</ph>Terms of Service<ph name="END_LINK1">&lt;/LINK1&gt;</ph> and <ph name="BEGIN_LINK2">&lt;LINK2&gt;</ph>Privacy Notice<ph name="END_LINK2">&lt;/LINK2&gt;</ph>, and the <ph name="BEGIN_LINK3">&lt;LINK3&gt;</ph>Privacy Notice for Google Accounts Created in Family Link<ph name="END_LINK3">&lt;/LINK3&gt;</ph>.
+      </message>
       <message name="IDS_FRE_SEND_REPORT_CHECK" desc="Text for asking the user to allow sending stats and crash reports">
         Help make Chrome better by sending usage statistics and crash reports to Google.
       </message>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
index 7a22b73..9dde2d2f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -11,6 +11,7 @@
 import android.graphics.Point;
 import android.os.Debug;
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
@@ -18,6 +19,13 @@
 import android.util.Log;
 import android.view.View;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.test.util.CallbackHelper;
@@ -52,7 +60,9 @@
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
 import org.chromium.chrome.browser.tabmodel.TabbedModeTabPersistencePolicy;
 import org.chromium.chrome.browser.toolbar.ToolbarPhone;
-import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ApplicationTestUtils;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.MenuUtils;
@@ -63,6 +73,7 @@
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.DOMUtils;
 import org.chromium.content.browser.test.util.JavaScriptUtils;
+import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content.browser.test.util.UiUtils;
 import org.chromium.content.common.ContentSwitches;
 import org.chromium.content_public.browser.WebContents;
@@ -80,7 +91,14 @@
 /**
  * General Tab tests.
  */
-public class TabsTest extends ChromeTabbedActivityTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+public class TabsTest {
+    @Rule
+    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
 
     private static final String TEST_FILE_PATH =
             "/chrome/test/data/android/tabstest/tabs_test.html";
@@ -122,12 +140,33 @@
             + "  <div id=\"test\">No resize event has been received yet.</div>"
             + "</body></html>");
 
-    @Override
-    protected void tearDown() throws Exception {
+    @Before
+    public void setUp() throws InterruptedException {
+        float dpToPx = InstrumentationRegistry.getInstrumentation()
+                               .getContext()
+                               .getResources()
+                               .getDisplayMetrics()
+                               .density;
+        mPxToDp = 1.0f / dpToPx;
+
+        // Exclude the tests that can launch directly to a page other than the NTP.
+        if (mActivityTestRule.getName().equals("testOpenAndCloseNewTabButton")
+                || mActivityTestRule.getName().equals("testSwitchToTabThatDoesNotHaveThumbnail")
+                || mActivityTestRule.getName().equals("testCloseTabPortrait")
+                || mActivityTestRule.getName().equals("testCloseTabLandscape")
+                || mActivityTestRule.getName().equals("testTabsAreDestroyedOnModelDestruction")
+                || mActivityTestRule.getName().equals("testIncognitoTabsNotRestoredAfterSwipe")) {
+            return;
+        }
+        mActivityTestRule.startMainActivityFromLauncher();
+    }
+
+
+    @After
+    public void tearDown() throws Exception {
         if (mTestServer != null) {
             mTestServer.stopAndDestroyServer();
         }
-        super.tearDown();
     }
 
     /**
@@ -135,17 +174,19 @@
      * @throws InterruptedException
      * @throws TimeoutException
      */
+    @Test
     @LargeTest
     @Feature({"Navigation"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @CommandLineFlags.Add(ContentSwitches.DISABLE_POPUP_BLOCKING)
     @RetryOnFailure
     public void testSpawnPopupOnBackgroundTab() throws InterruptedException, TimeoutException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        loadUrl(mTestServer.getURL(TEST_FILE_PATH));
-        final Tab tab = getActivity().getActivityTab();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_FILE_PATH));
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
-        newIncognitoTabFromMenu();
+        mActivityTestRule.newIncognitoTabFromMenu();
 
         ThreadUtils.runOnUiThreadBlocking(() -> tab.getWebContents().evaluateJavaScriptForTests(
                 "(function() {"
@@ -154,16 +195,21 @@
                 null));
 
         CriteriaHelper.pollUiThread(Criteria.equals(2,
-                () -> getActivity().getTabModelSelector().getModel(false).getCount()));
+                () -> mActivityTestRule.getActivity()
+                                   .getTabModelSelector()
+                                   .getModel(false)
+                                   .getCount()));
     }
 
+    @Test
     @MediumTest
     @RetryOnFailure
     public void testAlertDialogDoesNotChangeActiveModel() throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        newIncognitoTabFromMenu();
-        loadUrl(mTestServer.getURL(TEST_FILE_PATH));
-        final Tab tab = getActivity().getActivityTab();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.newIncognitoTabFromMenu();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_FILE_PATH));
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
         ThreadUtils.runOnUiThreadBlocking(() -> tab.getWebContents().evaluateJavaScriptForTests(
                 "(function() {"
                         + "  alert('hi');"
@@ -194,8 +240,8 @@
             }
         });
 
-        assertTrue("Incognito model was not selected",
-                getActivity().getTabModelSelector().isIncognitoSelected());
+        Assert.assertTrue("Incognito model was not selected",
+                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
     }
 
     /**
@@ -207,44 +253,51 @@
      * @Feature({"Android-TabSwitcher"})
      * @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
      */
+    @Test
     @DisabledTest
     public void testOpenAndCloseNewTabButton() throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        startMainActivityWithURL(mTestServer.getURL(TEST_FILE_PATH));
-        getInstrumentation().runOnMainSync(() -> {
-            String title = getActivity().getCurrentTabModel().getTabAt(0).getTitle();
-            assertEquals("Data file for TabsTest", title);
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(TEST_FILE_PATH));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            String title =
+                    mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getTitle();
+            Assert.assertEquals("Data file for TabsTest", title);
         });
-        final int tabCount = getActivity().getCurrentTabModel().getCount();
+        final int tabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
         OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher(
-                getActivity().getLayoutManager(), true, false);
-        View tabSwitcherButton = getActivity().findViewById(R.id.tab_switcher_button);
-        assertNotNull("'tab_switcher_button' view is not found", tabSwitcherButton);
-        singleClickView(tabSwitcherButton);
+                mActivityTestRule.getActivity().getLayoutManager(), true, false);
+        View tabSwitcherButton =
+                mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button);
+        Assert.assertNotNull("'tab_switcher_button' view is not found", tabSwitcherButton);
+        TouchCommon.singleClickView(tabSwitcherButton);
         overviewModeWatcher.waitForBehavior();
         overviewModeWatcher = new OverviewModeBehaviorWatcher(
-                getActivity().getLayoutManager(), false, true);
-        View newTabButton = getActivity().findViewById(R.id.new_tab_button);
-        assertNotNull("'new_tab_button' view is not found", newTabButton);
-        singleClickView(newTabButton);
+                mActivityTestRule.getActivity().getLayoutManager(), false, true);
+        View newTabButton = mActivityTestRule.getActivity().findViewById(R.id.new_tab_button);
+        Assert.assertNotNull("'new_tab_button' view is not found", newTabButton);
+        TouchCommon.singleClickView(newTabButton);
         overviewModeWatcher.waitForBehavior();
 
-        getInstrumentation().runOnMainSync(() -> assertEquals("The tab count is wrong",
-                tabCount + 1, getActivity().getCurrentTabModel().getCount()));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> Assert.assertEquals("The tab count is wrong", tabCount + 1,
+                                mActivityTestRule.getActivity().getCurrentTabModel().getCount()));
 
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                Tab tab = getActivity().getCurrentTabModel().getTabAt(1);
+                Tab tab = mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(1);
                 String title = tab.getTitle().toLowerCase(Locale.US);
                 String expectedTitle = "new tab";
                 return title.startsWith(expectedTitle);
             }
         });
 
-        ChromeTabUtils.closeCurrentTab(getInstrumentation(), getActivity());
-        getInstrumentation().runOnMainSync(
-                () -> assertEquals(tabCount, getActivity().getCurrentTabModel().getCount()));
+        ChromeTabUtils.closeCurrentTab(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> Assert.assertEquals(tabCount,
+                                mActivityTestRule.getActivity().getCurrentTabModel().getCount()));
     }
 
     private void assertWaitForKeyboardStatus(final boolean show) throws InterruptedException {
@@ -254,7 +307,8 @@
                 updateFailureReason("expected keyboard show: " + show);
                 return show
                         == org.chromium.ui.UiUtils.isKeyboardShowing(
-                                   getActivity(), getActivity().getTabsView());
+                                   mActivityTestRule.getActivity(),
+                                   mActivityTestRule.getActivity().getTabsView());
             }
         });
     }
@@ -263,62 +317,73 @@
      * Verify that opening a new tab, switching to an existing tab and closing current tab hide
      * keyboard.
      */
+    @Test
     @LargeTest
     @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testHideKeyboard() throws Exception {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
 
         // Open a new tab(The 1st tab) and click node.
-        ChromeTabUtils.fullyLoadUrlInNewTab(
-                getInstrumentation(), getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
-        assertEquals("Failed to click node.", true,
+        ChromeTabUtils.fullyLoadUrlInNewTab(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
+        Assert.assertEquals("Failed to click node.", true,
                 DOMUtils.clickNode(
-                        getActivity().getActivityTab().getContentViewCore(), "input_text"));
+                        mActivityTestRule.getActivity().getActivityTab().getContentViewCore(),
+                        "input_text"));
         assertWaitForKeyboardStatus(true);
 
         // Open a new tab(the 2nd tab).
-        ChromeTabUtils.fullyLoadUrlInNewTab(
-                getInstrumentation(), getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
+        ChromeTabUtils.fullyLoadUrlInNewTab(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
         assertWaitForKeyboardStatus(false);
 
         // Click node in the 2nd tab.
-        DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "input_text");
+        DOMUtils.clickNode(mActivityTestRule.getActivity().getActivityTab().getContentViewCore(),
+                "input_text");
         assertWaitForKeyboardStatus(true);
 
         // Switch to the 1st tab.
-        ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 1);
+        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 1);
         assertWaitForKeyboardStatus(false);
 
         // Click node in the 1st tab.
-        DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "input_text");
+        DOMUtils.clickNode(mActivityTestRule.getActivity().getActivityTab().getContentViewCore(),
+                "input_text");
         assertWaitForKeyboardStatus(true);
 
         // Close current tab(the 1st tab).
-        ChromeTabUtils.closeCurrentTab(getInstrumentation(), getActivity());
+        ChromeTabUtils.closeCurrentTab(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
         assertWaitForKeyboardStatus(false);
     }
 
     /**
      * Verify that opening a new window hides keyboard.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testHideKeyboardWhenOpeningWindow() throws Exception {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         // Open a new tab and click an editable node.
-        ChromeTabUtils.fullyLoadUrlInNewTab(
-                getInstrumentation(), getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
-        assertEquals("Failed to click textarea.", true,
+        ChromeTabUtils.fullyLoadUrlInNewTab(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
+        Assert.assertEquals("Failed to click textarea.", true,
                 DOMUtils.clickNode(
-                        getActivity().getActivityTab().getContentViewCore(), "textarea"));
+                        mActivityTestRule.getActivity().getActivityTab().getContentViewCore(),
+                        "textarea"));
         assertWaitForKeyboardStatus(true);
 
         // Click the button to open a new window.
-        assertEquals("Failed to click button.", true,
-                DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "button"));
+        Assert.assertEquals("Failed to click button.", true,
+                DOMUtils.clickNode(
+                        mActivityTestRule.getActivity().getActivityTab().getContentViewCore(),
+                        "button"));
         assertWaitForKeyboardStatus(false);
     }
 
@@ -326,8 +391,10 @@
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                final String actualText =
-                        getActivity().getActivityTab().getContentViewCore().getSelectedText();
+                final String actualText = mActivityTestRule.getActivity()
+                                                  .getActivityTab()
+                                                  .getContentViewCore()
+                                                  .getSelectedText();
                 updateFailureReason(
                         "expected selected text: [" + text + "], but got: [" + actualText + "]");
                 return text.equals(actualText);
@@ -341,15 +408,16 @@
      */
     private void fling(float startX, float startY, float endX, float endY, int stepCount) {
         Point size = new Point();
-        getActivity().getWindowManager().getDefaultDisplay().getSize(size);
+        mActivityTestRule.getActivity().getWindowManager().getDefaultDisplay().getSize(size);
         float dragStartX = size.x * startX;
         float dragEndX = size.x * endX;
         float dragStartY = size.y * startY;
         float dragEndY = size.y * endY;
         long downTime = SystemClock.uptimeMillis();
-        dragStart(dragStartX, dragStartY, downTime);
-        dragTo(dragStartX, dragEndX, dragStartY, dragEndY, stepCount, downTime);
-        dragEnd(dragEndX, dragEndY, downTime);
+        TouchCommon.dragStart(mActivityTestRule.getActivity(), dragStartX, dragStartY, downTime);
+        TouchCommon.dragTo(mActivityTestRule.getActivity(), dragStartX, dragEndX, dragStartY,
+                dragEndY, stepCount, downTime);
+        TouchCommon.dragEnd(mActivityTestRule.getActivity(), dragEndX, dragEndY, downTime);
     }
 
     private void scrollDown() {
@@ -360,15 +428,18 @@
      * Verify that the selection is collapsed when switching to the tab-switcher mode then switching
      * back. https://crbug.com/697756
      */
+    @Test
     @MediumTest
     @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testTabSwitcherCollapseSelection() throws Exception {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        ChromeTabUtils.fullyLoadUrlInNewTab(
-                getInstrumentation(), getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
-        DOMUtils.longPressNode(getActivity().getActivityTab().getContentViewCore(), "textarea");
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        ChromeTabUtils.fullyLoadUrlInNewTab(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), mTestServer.getURL(TEST_FILE_PATH), false);
+        DOMUtils.longPressNode(
+                mActivityTestRule.getActivity().getActivityTab().getContentViewCore(), "textarea");
         assertWaitForSelectedText("helloworld");
 
         // Switch to tab-switcher mode, switch back, and scroll page.
@@ -384,37 +455,39 @@
      * @throws InterruptedException
      * @throws TimeoutException
      */
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNewTabSetsContentViewSize() throws InterruptedException, TimeoutException {
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        getInstrumentation().waitForIdleSync();
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // Make sure we're on the NTP
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         NewTabPageTestUtils.waitForNtpLoaded(tab);
 
-        loadUrl(INITIAL_SIZE_TEST_URL);
+        mActivityTestRule.loadUrl(INITIAL_SIZE_TEST_URL);
 
         final WebContents webContents = tab.getWebContents();
         String innerText = JavaScriptUtils.executeJavaScriptAndWaitForResult(
                 webContents, "document.body.innerText").replace("\"", "");
 
-        DisplayMetrics metrics = getActivity().getResources().getDisplayMetrics();
+        DisplayMetrics metrics = mActivityTestRule.getActivity().getResources().getDisplayMetrics();
 
         // For non-integer pixel ratios like the N7v1 (1.333...), the layout system will actually
         // ceil the width.
         int expectedWidth = (int) Math.ceil(metrics.widthPixels / metrics.density);
 
         String[] nums = innerText.split(",");
-        assertTrue(nums.length == 2);
+        Assert.assertTrue(nums.length == 2);
         int innerWidth = Integer.parseInt(nums[0]);
         int innerHeight = Integer.parseInt(nums[1]);
 
-        assertEquals(expectedWidth, innerWidth);
+        Assert.assertEquals(expectedWidth, innerWidth);
 
         // Height can be affected by browser controls so just make sure it's non-0.
-        assertTrue("innerHeight was not set by page load time", innerHeight > 0);
+        Assert.assertTrue("innerHeight was not set by page load time", innerHeight > 0);
     }
 
     static class SimulateClickOnMainThread implements Runnable {
@@ -462,27 +535,30 @@
      */
     private void checkCloseTabAtPosition(final float x, final float y)
             throws InterruptedException {
-        getActivity();
+        mActivityTestRule.getActivity();
 
-        int initialTabCount = getActivity().getCurrentTabModel().getCount();
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        getInstrumentation().waitForIdleSync();
-        View button = getActivity().findViewById(R.id.tab_switcher_button);
+        int initialTabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        View button = mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button);
         OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher(
-                getActivity().getLayoutManager(), true, false);
-        singleClickView(button);
+                mActivityTestRule.getActivity().getLayoutManager(), true, false);
+        TouchCommon.singleClickView(button);
         overviewModeWatcher.waitForBehavior();
-        assertTrue("Expected: " + (initialTabCount + 1) + " tab Got: "
-                + getActivity().getCurrentTabModel().getCount(),
-                (initialTabCount + 1) == getActivity().getCurrentTabModel().getCount());
-        getInstrumentation().waitForIdleSync();
+        Assert.assertTrue("Expected: " + (initialTabCount + 1) + " tab Got: "
+                        + mActivityTestRule.getActivity().getCurrentTabModel().getCount(),
+                (initialTabCount + 1)
+                        == mActivityTestRule.getActivity().getCurrentTabModel().getCount());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
         final LayoutManagerChrome layoutManager = updateTabsViewSize();
-        ChromeTabUtils.closeTabWithAction(getInstrumentation(), getActivity(),
-                () -> getInstrumentation().runOnMainSync(
-                        new SimulateClickOnMainThread(layoutManager, x, y)));
-        assertTrue("Expected: " + initialTabCount + " tab Got: "
-                + getActivity().getCurrentTabModel().getCount(),
-                initialTabCount == getActivity().getCurrentTabModel().getCount());
+        ChromeTabUtils.closeTabWithAction(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(),
+                () -> InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                                new SimulateClickOnMainThread(layoutManager, x, y)));
+        Assert.assertTrue("Expected: " + initialTabCount + " tab Got: "
+                        + mActivityTestRule.getActivity().getCurrentTabModel().getCount(),
+                initialTabCount == mActivityTestRule.getActivity().getCurrentTabModel().getCount());
     }
 
     /**
@@ -490,14 +566,17 @@
      * This code does not handle properly different screen densities.
      * @throws InterruptedException
      */
+    @Test
     @LargeTest
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testTabSwitcherPortraitCloseButton() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        int portraitWidth = Math.min(getActivity().getResources().getDisplayMetrics().widthPixels,
-                getActivity().getResources().getDisplayMetrics().heightPixels);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        int portraitWidth = Math.min(
+                mActivityTestRule.getActivity().getResources().getDisplayMetrics().widthPixels,
+                mActivityTestRule.getActivity().getResources().getDisplayMetrics().heightPixels);
         // Hard-coded coordinates of the close button on the top right of the screen.
         // If the coordinates need to be updated, the easiest is to take a screenshot and measure.
         // Note that starting from the right of the screen should cover any screen size.
@@ -512,9 +591,11 @@
      * @LargeTest
      * @Feature({"Android-TabSwitcher"})
      */
+    @Test
     @FlakyTest(message = "crbug.com/170179")
     public void testTabSwitcherLandscapeCloseButton() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
         // Hard-coded coordinates of the close button on the bottom left of the screen.
         // If the coordinates need to be updated, the easiest is to take a screenshot and measure.
         checkCloseTabAtPosition(31 * mPxToDp, 31 * mPxToDp);
@@ -532,13 +613,16 @@
      * @Feature({"Android-TabSwitcher"})
      * Bug crbug.com/166208
      */
+    @Test
     @DisabledTest
     public void testOpenManyTabsSlowly() throws InterruptedException {
-        int startCount = getActivity().getCurrentTabModel().getCount();
+        int startCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
         for (int i = 1; i <= STRESSFUL_TAB_COUNT; ++i) {
-            ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-            getInstrumentation().waitForIdleSync();
-            assertEquals(startCount + i, getActivity().getCurrentTabModel().getCount());
+            ChromeTabUtils.newTabFromMenu(
+                    InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+            Assert.assertEquals(startCount + i,
+                    mActivityTestRule.getActivity().getCurrentTabModel().getCount());
         }
     }
 
@@ -551,13 +635,15 @@
      * @Feature({"Android-TabSwitcher"})
      *
      */
+    @Test
     @FlakyTest
     public void testOpenManyTabsQuickly() {
-        int startCount = getActivity().getCurrentTabModel().getCount();
+        int startCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
         for (int i = 1; i <= STRESSFUL_TAB_COUNT; ++i) {
-            MenuUtils.invokeCustomMenuActionSync(getInstrumentation(), getActivity(),
-                    R.id.new_tab_menu_id);
-            assertEquals(startCount + i, getActivity().getCurrentTabModel().getCount());
+            MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                    mActivityTestRule.getActivity(), R.id.new_tab_menu_id);
+            Assert.assertEquals(startCount + i,
+                    mActivityTestRule.getActivity().getCurrentTabModel().getCount());
         }
     }
 
@@ -569,15 +655,18 @@
      * @TimeoutScale(30)
      * @Feature({"Navigation"})
      */
+    @Test
     @FlakyTest
     public void testOpenManyTabsInBursts() throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         final int burstSize = 5;
         final String url = mTestServer.getURL(TEST_PAGE_FILE_PATH);
-        final int startCount = getActivity().getCurrentTabModel().getCount();
+        final int startCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
         for (int tabCount = startCount; tabCount < STRESSFUL_TAB_COUNT; tabCount += burstSize)  {
-            loadUrlInManyNewTabs(url, burstSize);
-            assertEquals(tabCount + burstSize, getActivity().getCurrentTabModel().getCount());
+            mActivityTestRule.loadUrlInManyNewTabs(url, burstSize);
+            Assert.assertEquals(tabCount + burstSize,
+                    mActivityTestRule.getActivity().getCurrentTabModel().getCount());
         }
     }
 
@@ -589,6 +678,7 @@
      * @TimeoutScale(30)
      * @Feature({"Navigation"})
      */
+    @Test
     @FlakyTest(message = "crbug.com/223110")
     public void testOpenManyTabsAtOnce10() throws InterruptedException {
         openAndVerifyManyTestTabs(10);
@@ -599,12 +689,13 @@
      * tab loads when selected.
      */
     private void openAndVerifyManyTestTabs(final int num) throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         final String url = mTestServer.getURL(TEST_PAGE_FILE_PATH);
-        int startCount = getActivity().getCurrentTabModel().getCount();
-        loadUrlInManyNewTabs(url, num);
-        assertEquals(startCount + num,
-                     getActivity().getCurrentTabModel().getCount());
+        int startCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        mActivityTestRule.loadUrlInManyNewTabs(url, num);
+        Assert.assertEquals(
+                startCount + num, mActivityTestRule.getActivity().getCurrentTabModel().getCount());
     }
 
     class ClickOptionButtonOnMainThread implements Runnable {
@@ -612,11 +703,12 @@
         public void run() {
             // This is equivalent to clickById(R.id.tab_switcher_button) but does not rely on the
             // event pipeline.
-            View button = getActivity().findViewById(R.id.tab_switcher_button);
-            assertNotNull("Could not find view R.id.tab_switcher_button", button);
-            View toolbar = getActivity().findViewById(R.id.toolbar);
-            assertNotNull("Could not find view R.id.toolbar", toolbar);
-            assertTrue("R.id.toolbar is not a ToolbarPhone", toolbar instanceof ToolbarPhone);
+            View button = mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button);
+            Assert.assertNotNull("Could not find view R.id.tab_switcher_button", button);
+            View toolbar = mActivityTestRule.getActivity().findViewById(R.id.toolbar);
+            Assert.assertNotNull("Could not find view R.id.toolbar", toolbar);
+            Assert.assertTrue(
+                    "R.id.toolbar is not a ToolbarPhone", toolbar instanceof ToolbarPhone);
             ((ToolbarPhone) toolbar).onClick(button);
         }
     }
@@ -626,10 +718,11 @@
      */
     private void showOverviewAndWaitForAnimation() throws InterruptedException {
         OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher(
-                getActivity().getLayoutManager(), true, false);
+                mActivityTestRule.getActivity().getLayoutManager(), true, false);
         // For some unknown reasons calling clickById(R.id.tab_switcher_button) sometimes hang.
         // The following is verbose but more reliable.
-        getInstrumentation().runOnMainSync(new ClickOptionButtonOnMainThread());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new ClickOptionButtonOnMainThread());
         overviewModeWatcher.waitForBehavior();
     }
 
@@ -638,8 +731,9 @@
      */
     private void hideOverviewAndWaitForAnimation() throws InterruptedException {
         OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher(
-                getActivity().getLayoutManager(), false, true);
-        getInstrumentation().runOnMainSync(new ClickOptionButtonOnMainThread());
+                mActivityTestRule.getActivity().getLayoutManager(), false, true);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new ClickOptionButtonOnMainThread());
         overviewModeWatcher.waitForBehavior();
     }
 
@@ -651,13 +745,15 @@
      * @throws InterruptedException
      */
     private int openTabs(final int targetTabCount, boolean waitToLoad) throws InterruptedException {
-        int tabCount = getActivity().getCurrentTabModel().getCount();
+        int tabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
         while (tabCount < targetTabCount) {
-            ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
+            ChromeTabUtils.newTabFromMenu(
+                    InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
             tabCount++;
-            assertEquals("The tab count is wrong",
-                    tabCount, getActivity().getCurrentTabModel().getCount());
-            Tab tab = TabModelUtils.getCurrentTab(getActivity().getCurrentTabModel());
+            Assert.assertEquals("The tab count is wrong", tabCount,
+                    mActivityTestRule.getActivity().getCurrentTabModel().getCount());
+            Tab tab = TabModelUtils.getCurrentTab(
+                    mActivityTestRule.getActivity().getCurrentTabModel());
             while (waitToLoad && tab.isLoading()) {
                 Thread.yield();
             }
@@ -673,6 +769,7 @@
        @LargeTest
        @Feature({"Android-TabSwitcher"})
     */
+    @Test
     @DisabledTest(message = "crbug.com/156746")
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testTabsCulling() throws InterruptedException {
@@ -683,10 +780,10 @@
 
         // Check counts.
         LayoutManagerChromePhone layoutManager =
-                (LayoutManagerChromePhone) getActivity().getLayoutManager();
+                (LayoutManagerChromePhone) mActivityTestRule.getActivity().getLayoutManager();
         int drawnCount = layoutManager.getOverviewLayout().getLayoutTabsToRender().length;
         int drawnExpected = Math.min(tabCount, maxTabsDrawn);
-        assertEquals("The number of drawn tab is wrong", drawnExpected, drawnCount);
+        Assert.assertEquals("The number of drawn tab is wrong", drawnExpected, drawnCount);
     }
 
     /**
@@ -694,18 +791,20 @@
      * @throws InterruptedException
      */
     private void checkTabsStacking() throws InterruptedException {
-        final int count = getActivity().getCurrentTabModel().getCount();
-        assertEquals("The number of tab in the stack should match the number of tabs in the model",
+        final int count = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        Assert.assertEquals(
+                "The number of tab in the stack should match the number of tabs in the model",
                 count, getLayoutTabInStackCount(false));
 
-        assertTrue("The selected tab should always be visible",
-                stackTabIsVisible(false, getActivity().getCurrentTabModel().index()));
+        Assert.assertTrue("The selected tab should always be visible",
+                stackTabIsVisible(
+                        false, mActivityTestRule.getActivity().getCurrentTabModel().index()));
         for (int i = 0; i < Stack.MAX_NUMBER_OF_STACKED_TABS_TOP && i < count; i++) {
-            assertTrue("The stacked tab " + i + " from the top should always be visible",
+            Assert.assertTrue("The stacked tab " + i + " from the top should always be visible",
                     stackTabIsVisible(false, i));
         }
         for (int i = 0; i < Stack.MAX_NUMBER_OF_STACKED_TABS_BOTTOM && i < count; i++) {
-            assertTrue("The stacked tab " + i + " from the bottom should always be visible",
+            Assert.assertTrue("The stacked tab " + i + " from the bottom should always be visible",
                     stackTabIsVisible(false, count - 1 - i));
         }
     }
@@ -717,21 +816,23 @@
      * @LargeTest
      * @Feature({"Android-TabSwitcher"})
      */
+    @Test
     @FlakyTest(message = "crbug.com/170179")
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testTabsStacking() throws InterruptedException {
         final int count = openTabs(12, false);
 
         // Selecting the first tab to scroll all the way to the top.
-        getInstrumentation().runOnMainSync(
-                () -> TabModelUtils.setIndex(getActivity().getCurrentTabModel(), 0));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> TabModelUtils.setIndex(
+                                mActivityTestRule.getActivity().getCurrentTabModel(), 0));
         showOverviewAndWaitForAnimation();
         checkTabsStacking();
 
         // Selecting the last tab to scroll all the way to the bottom.
         hideOverviewAndWaitForAnimation();
-        getInstrumentation().runOnMainSync(
-                () -> TabModelUtils.setIndex(getActivity().getCurrentTabModel(), count - 1));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> TabModelUtils.setIndex(
+                                mActivityTestRule.getActivity().getCurrentTabModel(), count - 1));
         showOverviewAndWaitForAnimation();
         checkTabsStacking();
     }
@@ -762,8 +863,9 @@
             }
             tries++;
         }
-        assertTrue("Could not have a stable read on native allocated size even after "
-                + tries + " gc.", tries < maxTries);
+        Assert.assertTrue("Could not have a stable read on native allocated size even after "
+                        + tries + " gc.",
+                tries < maxTries);
         return currentAllocatedSize;
     }
 
@@ -774,6 +876,7 @@
      * @LargeTest
      * @Feature({"Android-TabSwitcher"})
      */
+    @Test
     @FlakyTest(message = "crbug.com/303319")
     @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     public void testTabSwitcherMemoryLeak() throws InterruptedException {
@@ -796,13 +899,15 @@
             tries++;
         }
 
-        assertTrue("Native heap allocated size keeps increasing even after "
-                + tries + " iterations", tries < maxTries);
+        Assert.assertTrue(
+                "Native heap allocated size keeps increasing even after " + tries + " iterations",
+                tries < maxTries);
     }
 
     /**
      * Verify that switching back and forth stay stable. This test last for at least 8 seconds.
      */
+    @Test
     @LargeTest
     @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Android-TabSwitcher"})
@@ -814,20 +919,24 @@
         final long fastestUserInput = 20; // ms
         for (int i = 0; i < 200; i++) {
             // Show overview
-            getInstrumentation().runOnMainSync(new ClickOptionButtonOnMainThread());
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                    new ClickOptionButtonOnMainThread());
             Thread.sleep(fastestUserInput);
 
             // hide overview
-            getInstrumentation().runOnMainSync(new ClickOptionButtonOnMainThread());
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                    new ClickOptionButtonOnMainThread());
             Thread.sleep(fastestUserInput);
         }
     }
 
+    @Test
     @LargeTest
     @Feature({"Android-TabSwitcher"})
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testTabSelectionPortrait() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
         checkTabSelection(2, 0, false);
 
         // Ensure all tabs following the selected tab are off the screen when the animation is
@@ -835,10 +944,10 @@
         final int count = getLayoutTabInStackCount(false);
         for (int i = 1; i < count; i++) {
             float y = getLayoutTabInStackXY(false, i)[1];
-            assertTrue(
+            Assert.assertTrue(
                     String.format(Locale.US,
-                            "Tab %d's final draw Y, %f, should exceed the view height, %f.",
-                            i, y, mTabsViewHeightDp),
+                            "Tab %d's final draw Y, %f, should exceed the view height, %f.", i, y,
+                            mTabsViewHeightDp),
                     y >= mTabsViewHeightDp);
         }
     }
@@ -847,10 +956,12 @@
      * @LargeTest
      * @Feature({"Android-TabSwitcher"})
      */
+    @Test
     @FlakyTest(message = "crbug.com/170179")
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testTabSelectionLandscape() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
         checkTabSelection(2, 0, true);
 
         // Ensure all tabs following the selected tab are off the screen when the animation is
@@ -858,10 +969,10 @@
         final int count = getLayoutTabInStackCount(false);
         for (int i = 1; i < count; i++) {
             float x = getLayoutTabInStackXY(false, i)[0];
-            assertTrue(
+            Assert.assertTrue(
                     String.format(Locale.US,
-                            "Tab %d's final draw X, %f, should exceed the view width, %f.",
-                            i, x, mTabsViewWidthDp),
+                            "Tab %d's final draw X, %f, should exceed the view width, %f.", i, x,
+                            mTabsViewWidthDp),
                     x >= mTabsViewWidthDp);
         }
     }
@@ -869,28 +980,30 @@
     /**
      * Verify that we don't crash and show the overview mode after closing the last tab.
      */
+    @Test
     @SmallTest
     @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testCloseLastTabFromMain() throws InterruptedException {
         OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher(
-                getActivity().getLayoutManager(), true, false);
-        ChromeTabUtils.closeCurrentTab(getInstrumentation(), getActivity());
-        getInstrumentation().waitForIdleSync();
+                mActivityTestRule.getActivity().getLayoutManager(), true, false);
+        ChromeTabUtils.closeCurrentTab(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
         overviewModeWatcher.waitForBehavior();
     }
 
     private LayoutManagerChrome updateTabsViewSize() {
-        View tabsView = getActivity().getTabsView();
+        View tabsView = mActivityTestRule.getActivity().getTabsView();
         mTabsViewHeightDp = tabsView.getHeight() * mPxToDp;
         mTabsViewWidthDp = tabsView.getWidth() * mPxToDp;
-        return getActivity().getLayoutManager();
+        return mActivityTestRule.getActivity().getLayoutManager();
     }
 
     private Stack getStack(final LayoutManagerChrome layoutManager, boolean isIncognito) {
-        assertTrue("getStack must be executed on the ui thread",
-                ThreadUtils.runningOnUiThread());
+        Assert.assertTrue(
+                "getStack must be executed on the ui thread", ThreadUtils.runningOnUiThread());
         LayoutManagerChromePhone layoutManagerPhone = (LayoutManagerChromePhone) layoutManager;
         StackLayout layout = (StackLayout) layoutManagerPhone.getOverviewLayout();
         return (layout).getTabStack(isIncognito);
@@ -967,10 +1080,11 @@
     private void checkTabSelection(int additionalTabsToOpen, int tabIndexToSelect,
             boolean isLandscape) throws InterruptedException {
         for (int i = 0; i < additionalTabsToOpen; i++) {
-            ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
+            ChromeTabUtils.newTabFromMenu(
+                    InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
         }
-        assertEquals("Number of open tabs does not match",
-                additionalTabsToOpen + 1 , getActivity().getCurrentTabModel().getCount());
+        Assert.assertEquals("Number of open tabs does not match", additionalTabsToOpen + 1,
+                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
         showOverviewAndWaitForAnimation();
 
         float[] coordinates = getStackTabClickTarget(tabIndexToSelect, false, isLandscape);
@@ -978,16 +1092,16 @@
         float clickY = coordinates[1];
 
         OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher(
-                getActivity().getLayoutManager(), false, true);
+                mActivityTestRule.getActivity().getLayoutManager(), false, true);
 
         final LayoutManagerChrome layoutManager = updateTabsViewSize();
-        getInstrumentation().runOnMainSync(new SimulateClickOnMainThread(layoutManager,
-                (int) clickX, (int) clickY));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new SimulateClickOnMainThread(layoutManager, (int) clickX, (int) clickY));
         overviewModeWatcher.waitForBehavior();
 
         // Make sure we did not accidentally close a tab.
-        assertEquals("Number of open tabs does not match",
-                additionalTabsToOpen + 1 , getActivity().getCurrentTabModel().getCount());
+        Assert.assertEquals("Number of open tabs does not match", additionalTabsToOpen + 1,
+                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
     }
 
     public void swipeToCloseTab(final int tabIndexToClose, final boolean isLandscape,
@@ -998,20 +1112,24 @@
         final float clickY = coordinates[1];
         Log.v("ChromeTest", String.format("clickX %f clickY %f", clickX, clickY));
 
-        ChromeTabUtils.closeTabWithAction(getInstrumentation(), getActivity(), () -> {
-            if (isLandscape) {
-                getInstrumentation().runOnMainSync(new SimulateTabSwipeOnMainThread(
-                        layoutManager, clickX, clickY, 0, swipeDirection * mTabsViewWidthDp));
-            } else {
-                getInstrumentation().runOnMainSync(new SimulateTabSwipeOnMainThread(
-                        layoutManager, clickX, clickY, swipeDirection * mTabsViewHeightDp, 0));
-            }
-        });
+        ChromeTabUtils.closeTabWithAction(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), () -> {
+                    if (isLandscape) {
+                        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                                new SimulateTabSwipeOnMainThread(layoutManager, clickX, clickY, 0,
+                                        swipeDirection * mTabsViewWidthDp));
+                    } else {
+                        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                                new SimulateTabSwipeOnMainThread(layoutManager, clickX, clickY,
+                                        swipeDirection * mTabsViewHeightDp, 0));
+                    }
+                });
 
         CriteriaHelper.pollUiThread(new Criteria("Did not finish animation") {
             @Override
             public boolean isSatisfied() {
-                Layout layout = getActivity().getLayoutManager().getActiveLayout();
+                Layout layout =
+                        mActivityTestRule.getActivity().getLayoutManager().getActiveLayout();
                 return !layout.isLayoutAnimating();
             }
         });
@@ -1029,84 +1147,98 @@
     /**
      * Test closing few tabs by swiping them in Overview portrait mode.
      */
+    @Test
     @MediumTest
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"Android-TabSwitcher", "Main"})
     @RetryOnFailure
     public void testCloseTabPortrait() throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        startMainActivityWithURL(mTestServer.getURL("/chrome/test/data/android/test.html"));
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.startMainActivityWithURL(
+                mTestServer.getURL("/chrome/test/data/android/test.html"));
 
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 
-        int tabCount = getActivity().getCurrentTabModel().getCount();
-        ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 3);
-        assertEquals("wrong count after new tabs", tabCount + 3,
-                getActivity().getCurrentTabModel().getCount());
+        int tabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        ChromeTabUtils.newTabsFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 3);
+        Assert.assertEquals("wrong count after new tabs", tabCount + 3,
+                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
 
         showOverviewAndWaitForAnimation();
         swipeToCloseNTabs(3, false, false, SWIPE_TO_LEFT_DIRECTION);
 
-        assertEquals("Wrong tab counts after closing a few of them",
-                tabCount, getActivity().getCurrentTabModel().getCount());
+        Assert.assertEquals("Wrong tab counts after closing a few of them", tabCount,
+                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
     }
 
     /**
      * Test closing few tabs by swiping them in Overview landscape mode.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher", "Main"})
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @RetryOnFailure
     public void testCloseTabLandscape() throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        startMainActivityWithURL(mTestServer.getURL("/chrome/test/data/android/test.html"));
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.startMainActivityWithURL(
+                mTestServer.getURL("/chrome/test/data/android/test.html"));
 
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
 
-        int tabCount = getActivity().getCurrentTabModel().getCount();
-        ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 3);
-        assertEquals("wrong count after new tabs", tabCount + 3,
-                getActivity().getCurrentTabModel().getCount());
+        int tabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        ChromeTabUtils.newTabsFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 3);
+        Assert.assertEquals("wrong count after new tabs", tabCount + 3,
+                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
 
         showOverviewAndWaitForAnimation();
         swipeToCloseTab(0, true, false, SWIPE_TO_LEFT_DIRECTION);
         swipeToCloseTab(0, true, false, SWIPE_TO_LEFT_DIRECTION);
         swipeToCloseTab(0, true, false, SWIPE_TO_LEFT_DIRECTION);
 
-        assertEquals("Wrong tab counts after closing a few of them",
-                tabCount, getActivity().getCurrentTabModel().getCount());
+        Assert.assertEquals("Wrong tab counts after closing a few of them", tabCount,
+                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
     }
 
     /**
      * Test close Incognito tab by swiping in Overview Portrait mode.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @RetryOnFailure
     public void testCloseIncognitoTabPortrait() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        newIncognitoTabsFromMenu(2);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        mActivityTestRule.newIncognitoTabsFromMenu(2);
 
         showOverviewAndWaitForAnimation();
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
         swipeToCloseNTabs(2, false, true, SWIPE_TO_LEFT_DIRECTION);
     }
 
     /**
      * Test close 5 Incognito tabs by swiping in Overview Portrait mode.
      */
+    @Test
     @Feature({"Android-TabSwitcher"})
     @MediumTest
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @RetryOnFailure
     public void testCloseFiveIncognitoTabPortrait() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        newIncognitoTabsFromMenu(5);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        mActivityTestRule.newIncognitoTabsFromMenu(5);
 
         showOverviewAndWaitForAnimation();
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
         swipeToCloseNTabs(5, false, true, SWIPE_TO_LEFT_DIRECTION);
     }
 
@@ -1114,41 +1246,48 @@
      * Simple swipe gesture should not close tabs when two Tabstacks are open in Overview mode.
      * Test in Portrait Mode.
      */
+    @Test
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     public void testSwitchTabStackWithoutClosingTabsInPortrait() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        newIncognitoTabFromMenu();
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        mActivityTestRule.newIncognitoTabFromMenu();
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
 
         showOverviewAndWaitForAnimation();
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
         final int normalTabCount = getLayoutTabInStackCount(false);
         final int incognitoTabCount = getLayoutTabInStackCount(true);
 
         LayoutManagerChrome layoutManager = updateTabsViewSize();
 
         // Swipe to Incognito Tabs.
-        getInstrumentation().runOnMainSync(new SimulateTabSwipeOnMainThread(layoutManager,
-                mTabsViewWidthDp - 20 , mTabsViewHeightDp / 2 ,
-                SWIPE_TO_LEFT_DIRECTION * mTabsViewWidthDp, 0));
-        UiUtils.settleDownUI(getInstrumentation());
-        assertTrue("Tabs Stack should have been changed to incognito.",
-                getActivity().getCurrentTabModel().isIncognito());
-        assertEquals("Normal tabs count should be unchanged while switching to incognito tabs.",
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new SimulateTabSwipeOnMainThread(layoutManager, mTabsViewWidthDp - 20,
+                        mTabsViewHeightDp / 2, SWIPE_TO_LEFT_DIRECTION * mTabsViewWidthDp, 0));
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertTrue("Tabs Stack should have been changed to incognito.",
+                mActivityTestRule.getActivity().getCurrentTabModel().isIncognito());
+        Assert.assertEquals(
+                "Normal tabs count should be unchanged while switching to incognito tabs.",
                 normalTabCount, getLayoutTabInStackCount(false));
 
         // Swipe to regular Tabs.
-        getInstrumentation().runOnMainSync(new SimulateTabSwipeOnMainThread(layoutManager,
-                20, mTabsViewHeightDp / 2,
-                SWIPE_TO_RIGHT_DIRECTION * mTabsViewWidthDp, 0));
-        UiUtils.settleDownUI(getInstrumentation());
-        assertEquals("Incognito tabs count should be unchanged while switching back to normal "
-                + "tab stack.", incognitoTabCount, getLayoutTabInStackCount(true));
-        assertFalse("Tabs Stack should have been changed to regular tabs.",
-                getActivity().getCurrentTabModel().isIncognito());
-        assertEquals("Normal tabs count should be unchanged while switching back to normal tabs.",
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new SimulateTabSwipeOnMainThread(layoutManager, 20, mTabsViewHeightDp / 2,
+                        SWIPE_TO_RIGHT_DIRECTION * mTabsViewWidthDp, 0));
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertEquals(
+                "Incognito tabs count should be unchanged while switching back to normal "
+                        + "tab stack.",
+                incognitoTabCount, getLayoutTabInStackCount(true));
+        Assert.assertFalse("Tabs Stack should have been changed to regular tabs.",
+                mActivityTestRule.getActivity().getCurrentTabModel().isIncognito());
+        Assert.assertEquals(
+                "Normal tabs count should be unchanged while switching back to normal tabs.",
                 normalTabCount, getLayoutTabInStackCount(false));
     }
 
@@ -1160,90 +1299,105 @@
         @MediumTest
         @Feature({"Android-TabSwitcher"})
      */
+    @Test
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @DisabledTest(message = "crbug.com/157259")
     public void testSwitchTabStackWithoutClosingTabsInLandscape() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        newIncognitoTabFromMenu();
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.newIncognitoTabFromMenu();
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
 
         showOverviewAndWaitForAnimation();
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
         final int normalTabCount = getLayoutTabInStackCount(false);
         final int incognitoTabCount = getLayoutTabInStackCount(true);
 
         LayoutManagerChrome layoutManager = updateTabsViewSize();
 
         // Swipe to Incognito Tabs.
-        getInstrumentation().runOnMainSync(new SimulateTabSwipeOnMainThread(layoutManager,
-                mTabsViewWidthDp / 2 , mTabsViewHeightDp - 20 ,
-                0, SWIPE_TO_LEFT_DIRECTION * mTabsViewWidthDp));
-        UiUtils.settleDownUI(getInstrumentation());
-        assertTrue("Tabs Stack should have been changed to incognito.",
-                getActivity().getCurrentTabModel().isIncognito());
-        assertEquals("Normal tabs count should be unchanged while switching to incognito tabs.",
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new SimulateTabSwipeOnMainThread(layoutManager, mTabsViewWidthDp / 2,
+                        mTabsViewHeightDp - 20, 0, SWIPE_TO_LEFT_DIRECTION * mTabsViewWidthDp));
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertTrue("Tabs Stack should have been changed to incognito.",
+                mActivityTestRule.getActivity().getCurrentTabModel().isIncognito());
+        Assert.assertEquals(
+                "Normal tabs count should be unchanged while switching to incognito tabs.",
                 normalTabCount, getLayoutTabInStackCount(false));
 
         // Swipe to regular Tabs.
-        getInstrumentation().runOnMainSync(new SimulateTabSwipeOnMainThread(layoutManager,
-                mTabsViewWidthDp / 2, 20,
-                0, SWIPE_TO_RIGHT_DIRECTION * mTabsViewWidthDp));
-        UiUtils.settleDownUI(getInstrumentation());
-        assertEquals("Incognito tabs count should be unchanged while switching back to normal "
-                + "tab stack.", incognitoTabCount, getLayoutTabInStackCount(true));
-        assertFalse("Tabs Stack should have been changed to regular tabs.",
-                getActivity().getCurrentTabModel().isIncognito());
-        assertEquals("Normal tabs count should be unchanged while switching back to normal tabs.",
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new SimulateTabSwipeOnMainThread(layoutManager, mTabsViewWidthDp / 2, 20, 0,
+                        SWIPE_TO_RIGHT_DIRECTION * mTabsViewWidthDp));
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertEquals(
+                "Incognito tabs count should be unchanged while switching back to normal "
+                        + "tab stack.",
+                incognitoTabCount, getLayoutTabInStackCount(true));
+        Assert.assertFalse("Tabs Stack should have been changed to regular tabs.",
+                mActivityTestRule.getActivity().getCurrentTabModel().isIncognito());
+        Assert.assertEquals(
+                "Normal tabs count should be unchanged while switching back to normal tabs.",
                 normalTabCount, getLayoutTabInStackCount(false));
     }
 
     /**
      * Test close Incognito tab by swiping in Overview Landscape mode.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @RetryOnFailure
     public void testCloseIncognitoTabLandscape() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        newIncognitoTabFromMenu();
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.newIncognitoTabFromMenu();
 
         showOverviewAndWaitForAnimation();
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
         swipeToCloseTab(0, true, true, SWIPE_TO_LEFT_DIRECTION);
     }
 
     /**
      * Test close 5 Incognito tabs by swiping in Overview Landscape mode.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @RetryOnFailure
     public void testCloseFiveIncognitoTabLandscape() throws InterruptedException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        newIncognitoTabsFromMenu(5);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.newIncognitoTabsFromMenu(5);
 
         showOverviewAndWaitForAnimation();
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
         swipeToCloseNTabs(5, true, true, SWIPE_TO_LEFT_DIRECTION);
     }
 
     /**
      * Test that we can safely close a tab during a fling (http://b/issue?id=5364043)
      */
+    @Test
     @SmallTest
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testCloseTabDuringFling() throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        loadUrlInNewTab(mTestServer.getURL(
-                "/chrome/test/data/android/tabstest/text_page.html"));
-        getInstrumentation().runOnMainSync(() -> {
-            ContentViewCore view = getActivity().getActivityTab().getContentViewCore();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.loadUrlInNewTab(
+                mTestServer.getURL("/chrome/test/data/android/tabstest/text_page.html"));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            ContentViewCore view =
+                    mActivityTestRule.getActivity().getActivityTab().getContentViewCore();
             view.flingViewport(SystemClock.uptimeMillis(), 0, -2000, false);
         });
-        ChromeTabUtils.closeCurrentTab(getInstrumentation(), getActivity());
+        ChromeTabUtils.closeCurrentTab(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
     }
 
     /**
@@ -1252,188 +1406,219 @@
      * @MediumTest
      * @Feature({"Android-TabSwitcher"})
      */
+    @Test
     @FlakyTest
     public void testQuickSwitchBetweenTabAndSwitcherMode() throws InterruptedException {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         final String[] urls = {
                 mTestServer.getURL("/chrome/test/data/android/navigate/one.html"),
                 mTestServer.getURL("/chrome/test/data/android/navigate/two.html"),
                 mTestServer.getURL("/chrome/test/data/android/navigate/three.html")};
 
         for (String url : urls) {
-            loadUrlInNewTab(url);
+            mActivityTestRule.loadUrlInNewTab(url);
         }
 
         int lastUrlIndex = urls.length - 1;
 
-        View button = getActivity().findViewById(R.id.tab_switcher_button);
-        assertNotNull("Could not find 'tab_switcher_button'", button);
+        View button = mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button);
+        Assert.assertNotNull("Could not find 'tab_switcher_button'", button);
 
         for (int i = 0; i < 15; i++) {
-            singleClickView(button);
+            TouchCommon.singleClickView(button);
             // Switch back to the tab view from the tab-switcher mode.
-            singleClickView(button);
+            TouchCommon.singleClickView(button);
 
-            assertEquals("URL mismatch after switching back to the tab from tab-switch mode",
-                    urls[lastUrlIndex], getActivity().getActivityTab().getUrl());
+            Assert.assertEquals("URL mismatch after switching back to the tab from tab-switch mode",
+                    urls[lastUrlIndex], mActivityTestRule.getActivity().getActivityTab().getUrl());
         }
     }
 
     /**
      * Open an incognito tab from menu and verify its property.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testOpenIncognitoTab() throws InterruptedException {
-        newIncognitoTabFromMenu();
+        mActivityTestRule.newIncognitoTabFromMenu();
 
-        assertTrue("Current Tab should be an incognito tab.",
-                getActivity().getActivityTab().isIncognito());
+        Assert.assertTrue("Current Tab should be an incognito tab.",
+                mActivityTestRule.getActivity().getActivityTab().isIncognito());
     }
 
     /**
      * Test NewTab button on the browser toolbar.
      * Restricted to phones due crbug.com/429671.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     @RetryOnFailure
     public void testNewTabButton() throws InterruptedException {
-        MenuUtils.invokeCustomMenuActionSync(getInstrumentation(), getActivity(),
-                R.id.close_all_tabs_menu_id);
-        UiUtils.settleDownUI(getInstrumentation());
+        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), R.id.close_all_tabs_menu_id);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
         CriteriaHelper.pollInstrumentationThread(new Criteria("Should be in overview mode") {
             @Override
             public boolean isSatisfied() {
-                return getActivity().isInOverviewMode();
+                return mActivityTestRule.getActivity().isInOverviewMode();
             }
         });
 
-        int initialTabCount = getActivity().getCurrentTabModel().getCount();
-        assertEquals("Tab count is expected to be 0 after closing all the tabs",
-                0, initialTabCount);
+        int initialTabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        Assert.assertEquals(
+                "Tab count is expected to be 0 after closing all the tabs", 0, initialTabCount);
 
-        ChromeTabUtils.clickNewTabButton(getInstrumentation(), getActivity());
 
-        int newTabCount = getActivity().getCurrentTabModel().getCount();
-        assertEquals("Tab count is expected to be 1 after clicking Newtab button",
-                1, newTabCount);
+        ChromeTabUtils.clickNewTabButton(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+
+        int newTabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        Assert.assertEquals(
+                "Tab count is expected to be 1 after clicking Newtab button", 1, newTabCount);
+        // This helps to teardown the test, if tabs are not closed here, the tab activity would
+        // be forced to close by MonitoringInstrumentationRunner which cause exception because
+        // tab activity is no longer attached to window
+        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), R.id.close_all_tabs_menu_id);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testToolbarSwipeOnlyTab() throws InterruptedException {
-        final TabModel tabModel = getActivity().getTabModelSelector().getModel(false);
+        final TabModel tabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
 
-        assertEquals("Incorrect starting index", 0, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 0, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0, false);
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 0, false);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testToolbarSwipePrevTab() throws InterruptedException {
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        UiUtils.settleDownUI(getInstrumentation());
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        final TabModel tabModel = getActivity().getTabModelSelector().getModel(false);
+        final TabModel tabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
 
-        assertEquals("Incorrect starting index", 1, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 1, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0, true);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testToolbarSwipeNextTab() throws InterruptedException {
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0);
-        UiUtils.settleDownUI(getInstrumentation());
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        final TabModel tabModel = getActivity().getTabModelSelector().getModel(false);
+        final TabModel tabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
 
-        assertEquals("Incorrect starting index", 0, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 0, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1, true);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testToolbarSwipePrevTabNone() throws InterruptedException {
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0);
-        UiUtils.settleDownUI(getInstrumentation());
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        final TabModel tabModel = getActivity().getTabModelSelector().getModel(false);
+        final TabModel tabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
 
-        assertEquals("Incorrect starting index", 0, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 0, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0, false);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testToolbarSwipeNextTabNone() throws InterruptedException {
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        UiUtils.settleDownUI(getInstrumentation());
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        final TabModel tabModel = getActivity().getTabModelSelector().getModel(false);
+        final TabModel tabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
 
-        assertEquals("Incorrect starting index", 1, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 1, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1, false);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testToolbarSwipeNextThenPrevTab() throws InterruptedException {
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0);
-        UiUtils.settleDownUI(getInstrumentation());
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        final TabModel tabModel = getActivity().getTabModelSelector().getModel(false);
+        final TabModel tabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
 
-        assertEquals("Incorrect starting index", 0, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 0, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1, true);
 
-        assertEquals("Incorrect starting index", 1, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 1, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0, true);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testToolbarSwipeNextThenPrevTabIncognito() throws InterruptedException {
-        newIncognitoTabFromMenu();
-        newIncognitoTabFromMenu();
-        ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0);
-        UiUtils.settleDownUI(getInstrumentation());
+        mActivityTestRule.newIncognitoTabFromMenu();
+        mActivityTestRule.newIncognitoTabFromMenu();
+        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        final TabModel tabModel = getActivity().getTabModelSelector().getModel(true);
+        final TabModel tabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(true);
 
-        assertEquals("Incorrect starting index", 0, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 0, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.LEFT, 1, true);
 
-        assertEquals("Incorrect starting index", 1, tabModel.index());
+        Assert.assertEquals("Incorrect starting index", 1, tabModel.index());
         runToolbarSideSwipeTestOnCurrentModel(ScrollDirection.RIGHT, 0, true);
     }
 
     private void runToolbarSideSwipeTestOnCurrentModel(ScrollDirection direction, int finalIndex,
             boolean expectsSelection) throws InterruptedException {
         final CallbackHelper selectCallback = new CallbackHelper();
-        final int id = getActivity().getCurrentTabModel().getTabAt(finalIndex).getId();
+        final int id =
+                mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(finalIndex).getId();
         final TabModelObserver observer = new EmptyTabModelObserver() {
             @Override
             public void didSelectTab(Tab tab, TabSelectionType type, int lastId) {
@@ -1443,7 +1628,7 @@
 
         if (expectsSelection) {
             ThreadUtils.runOnUiThreadBlocking(() -> {
-                TabModelSelector selector = getActivity().getTabModelSelector();
+                TabModelSelector selector = mActivityTestRule.getActivity().getTabModelSelector();
                 for (TabModel tabModel : selector.getModels()) {
                     tabModel.addObserver(observer);
                 }
@@ -1452,17 +1637,17 @@
 
         performToolbarSideSwipe(direction);
         waitForStaticLayout();
-        assertEquals("Index after toolbar side swipe is incorrect", finalIndex,
-                getActivity().getCurrentTabModel().index());
+        Assert.assertEquals("Index after toolbar side swipe is incorrect", finalIndex,
+                mActivityTestRule.getActivity().getCurrentTabModel().index());
 
         if (expectsSelection) {
             try {
                 selectCallback.waitForCallback(0);
             } catch (TimeoutException e) {
-                fail("Tab selected event was never received");
+                Assert.fail("Tab selected event was never received");
             }
             ThreadUtils.runOnUiThreadBlocking(() -> {
-                TabModelSelector selector = getActivity().getTabModelSelector();
+                TabModelSelector selector = mActivityTestRule.getActivity().getTabModelSelector();
                 for (TabModel tabModel : selector.getModels()) {
                     tabModel.removeObserver(observer);
                 }
@@ -1472,9 +1657,9 @@
 
 
     private void performToolbarSideSwipe(ScrollDirection direction) {
-        assertTrue("Unexpected direction for side swipe " + direction,
+        Assert.assertTrue("Unexpected direction for side swipe " + direction,
                 direction == ScrollDirection.LEFT || direction == ScrollDirection.RIGHT);
-        final View toolbar = getActivity().findViewById(R.id.toolbar);
+        final View toolbar = mActivityTestRule.getActivity().findViewById(R.id.toolbar);
         int[] toolbarPos = new int[2];
         toolbar.getLocationOnScreen(toolbarPos);
         final int width = toolbar.getWidth();
@@ -1486,9 +1671,9 @@
         final int stepCount = 10;
 
         long downTime = SystemClock.uptimeMillis();
-        dragStart(fromX, y, downTime);
-        dragTo(fromX, toX, y, y, stepCount, downTime);
-        dragEnd(toX, y, downTime);
+        TouchCommon.dragStart(mActivityTestRule.getActivity(), fromX, y, downTime);
+        TouchCommon.dragTo(mActivityTestRule.getActivity(), fromX, toX, y, y, stepCount, downTime);
+        TouchCommon.dragEnd(mActivityTestRule.getActivity(), toX, y, downTime);
     }
 
     private void waitForStaticLayout() throws InterruptedException {
@@ -1496,8 +1681,9 @@
                 new Criteria("Static Layout never selected after side swipe") {
                     @Override
                     public boolean isSatisfied() {
-                        CompositorViewHolder compositorViewHolder = (CompositorViewHolder)
-                                getActivity().findViewById(R.id.compositor_view_holder);
+                        CompositorViewHolder compositorViewHolder =
+                                (CompositorViewHolder) mActivityTestRule.getActivity().findViewById(
+                                        R.id.compositor_view_holder);
                         LayoutManager layoutManager = compositorViewHolder.getLayoutManager();
 
                         return layoutManager.getActiveLayout() instanceof StaticLayout;
@@ -1508,28 +1694,28 @@
     /**
      * Test that swipes and tab transitions are not causing URL bar to be focused.
      */
+    @Test
     @MediumTest
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testOSKIsNotShownDuringSwipe() throws InterruptedException {
-        final View urlBar = getActivity().findViewById(R.id.url_bar);
+        final View urlBar = mActivityTestRule.getActivity().findViewById(R.id.url_bar);
         final LayoutManagerChrome layoutManager = updateTabsViewSize();
         final EdgeSwipeHandler edgeSwipeHandler = layoutManager.getTopSwipeHandler();
 
-        UiUtils.settleDownUI(getInstrumentation());
-        getInstrumentation().runOnMainSync(
-                () -> urlBar.requestFocus());
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> urlBar.requestFocus());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        getInstrumentation().runOnMainSync(
-                () -> urlBar.clearFocus());
-        UiUtils.settleDownUI(getInstrumentation());
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        UiUtils.settleDownUI(getInstrumentation());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> urlBar.clearFocus());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        assertFalse("Keyboard somehow got shown",
-                org.chromium.ui.UiUtils.isKeyboardShowing(getActivity(), urlBar));
+        Assert.assertFalse("Keyboard somehow got shown",
+                org.chromium.ui.UiUtils.isKeyboardShowing(mActivityTestRule.getActivity(), urlBar));
 
         ThreadUtils.runOnUiThread(() -> {
             edgeSwipeHandler.swipeStarted(ScrollDirection.RIGHT, 0, 0);
@@ -1542,14 +1728,15 @@
                 new Criteria("Layout still requesting Tab Android view be attached") {
                     @Override
                     public boolean isSatisfied() {
-                        LayoutManager driver = getActivity().getLayoutManager();
+                        LayoutManager driver = mActivityTestRule.getActivity().getLayoutManager();
                         return !driver.getActiveLayout().shouldDisplayContentOverlay();
                     }
                 });
 
         ThreadUtils.runOnUiThread(() -> {
-            assertFalse("Keyboard should be hidden while swiping",
-                    org.chromium.ui.UiUtils.isKeyboardShowing(getActivity(), urlBar));
+            Assert.assertFalse("Keyboard should be hidden while swiping",
+                    org.chromium.ui.UiUtils.isKeyboardShowing(
+                            mActivityTestRule.getActivity(), urlBar));
             edgeSwipeHandler.swipeFinished();
         });
 
@@ -1557,100 +1744,111 @@
                 new Criteria("Layout not requesting Tab Android view be attached") {
                     @Override
                     public boolean isSatisfied() {
-                        LayoutManager driver = getActivity().getLayoutManager();
+                        LayoutManager driver = mActivityTestRule.getActivity().getLayoutManager();
                         return driver.getActiveLayout().shouldDisplayContentOverlay();
                     }
                 });
 
-        assertFalse("Keyboard should not be shown",
-                org.chromium.ui.UiUtils.isKeyboardShowing(getActivity(), urlBar));
+        Assert.assertFalse("Keyboard should not be shown",
+                org.chromium.ui.UiUtils.isKeyboardShowing(mActivityTestRule.getActivity(), urlBar));
     }
 
     /**
      * Test that orientation changes cause the live tab reflow.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     @RetryOnFailure
     public void testOrientationChangeCausesLiveTabReflowInNormalView()
             throws InterruptedException, TimeoutException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        loadUrl(RESIZE_TEST_URL);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        mActivityTestRule.loadUrl(RESIZE_TEST_URL);
         final WebContents webContents =
-                getActivity().getActivityTab().getWebContents();
+                mActivityTestRule.getActivity().getActivityTab().getWebContents();
 
         JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents,
                                                           "resizeHappened = false;");
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        UiUtils.settleDownUI(getInstrumentation());
-        assertEquals("onresize event wasn't received by the tab (normal view)",
-                "true",
-                JavaScriptUtils.executeJavaScriptAndWaitForResult(
-                        webContents, "resizeHappened",
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertEquals("onresize event wasn't received by the tab (normal view)", "true",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, "resizeHappened",
                         WAIT_RESIZE_TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
     /**
      * Test that orientation changes cause the live tab reflow.
      */
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testOrientationChangeCausesLiveTabReflowInTabSwitcher()
             throws InterruptedException, TimeoutException {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
-        loadUrl(RESIZE_TEST_URL);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        ChromeTabUtils.newTabFromMenu(
+                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
+        mActivityTestRule.loadUrl(RESIZE_TEST_URL);
         final WebContents webContents =
-                        getActivity().getActivityTab().getWebContents();
+                mActivityTestRule.getActivity().getActivityTab().getWebContents();
 
         showOverviewAndWaitForAnimation();
         JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents,
                                                           "resizeHappened = false;");
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        UiUtils.settleDownUI(getInstrumentation());
-        assertEquals("onresize event wasn't received by the live tab (tabswitcher, to Landscape)",
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertEquals(
+                "onresize event wasn't received by the live tab (tabswitcher, to Landscape)",
                 "true",
-                JavaScriptUtils.executeJavaScriptAndWaitForResult(
-                        webContents, "resizeHappened",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, "resizeHappened",
                         WAIT_RESIZE_TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
         JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents,
                                                           "resizeHappened = false;");
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        UiUtils.settleDownUI(getInstrumentation());
-        assertEquals("onresize event wasn't received by the live tab (tabswitcher, to Portrait)",
-                "true",
-                JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents,
-                        "resizeHappened", WAIT_RESIZE_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertEquals(
+                "onresize event wasn't received by the live tab (tabswitcher, to Portrait)", "true",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, "resizeHappened",
+                        WAIT_RESIZE_TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testLastClosedUndoableTabGetsHidden() {
-        final TabModel model = getActivity().getTabModelSelector().getCurrentModel();
+        final TabModel model =
+                mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
         final Tab tab = TabModelUtils.getCurrentTab(model);
 
-        assertEquals("Too many tabs at startup", 1, model.getCount());
+        Assert.assertEquals("Too many tabs at startup", 1, model.getCount());
 
         ThreadUtils.runOnUiThreadBlocking((Runnable) () -> model.closeTab(tab, false, false, true));
 
         ThreadUtils.runOnUiThreadBlocking(() -> {
-            assertTrue("Tab close is not undoable", model.isClosurePending(tab.getId()));
-            assertTrue("Tab was not hidden", tab.isHidden());
+            Assert.assertTrue("Tab close is not undoable", model.isClosurePending(tab.getId()));
+            Assert.assertTrue("Tab was not hidden", tab.isHidden());
         });
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testLastClosedTabTriggersNotifyChangedCall() {
-        final TabModel model = getActivity().getTabModelSelector().getCurrentModel();
+        final TabModel model =
+                mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
         final Tab tab = TabModelUtils.getCurrentTab(model);
-        final TabModelSelector selector = getActivity().getTabModelSelector();
+        final TabModelSelector selector = mActivityTestRule.getActivity().getTabModelSelector();
         mNotifyChangedCalled = false;
 
         selector.addObserver(new EmptyTabModelSelectorObserver() {
@@ -1660,21 +1858,22 @@
             }
         });
 
-        assertEquals("Too many tabs at startup", 1, model.getCount());
+        Assert.assertEquals("Too many tabs at startup", 1, model.getCount());
 
         ThreadUtils.runOnUiThreadBlocking((Runnable) () -> model.closeTab(tab, false, false, true));
 
-        assertTrue("notifyChanged() was not called", mNotifyChangedCalled);
+        Assert.assertTrue("notifyChanged() was not called", mNotifyChangedCalled);
     }
 
+    @Test
     @MediumTest
     @Feature({"Android-TabSwitcher"})
     @RetryOnFailure
     public void testTabsAreDestroyedOnModelDestruction() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         final TabModelSelectorImpl selector =
-                (TabModelSelectorImpl) getActivity().getTabModelSelector();
-        final Tab tab = getActivity().getActivityTab();
+                (TabModelSelectorImpl) mActivityTestRule.getActivity().getTabModelSelector();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         final AtomicBoolean webContentsDestroyCalled = new AtomicBoolean();
 
@@ -1691,36 +1890,41 @@
                             }
                         };
 
-                assertNotNull("No initial tab at startup", tab);
-                assertNotNull("Tab does not have a web contents", tab.getWebContents());
-                assertTrue("Tab is destroyed", tab.isInitialized());
+                Assert.assertNotNull("No initial tab at startup", tab);
+                Assert.assertNotNull("Tab does not have a web contents", tab.getWebContents());
+                Assert.assertTrue("Tab is destroyed", tab.isInitialized());
 
                 selector.destroy();
 
-                assertNull("Tab still has a web contents", tab.getWebContents());
-                assertFalse("Tab was not destroyed", tab.isInitialized());
+                Assert.assertNull("Tab still has a web contents", tab.getWebContents());
+                Assert.assertFalse("Tab was not destroyed", tab.isInitialized());
             }
         });
 
-        assertTrue("WebContentsObserver was never destroyed", webContentsDestroyCalled.get());
+        Assert.assertTrue(
+                "WebContentsObserver was never destroyed", webContentsDestroyCalled.get());
     }
 
     // Flaky even with RetryOnFailure: http://crbug.com/649429
+    @Test
     @DisabledTest
     //    @MediumTest
     //    @Feature({"Android-TabSwitcher"})
     public void testIncognitoTabsNotRestoredAfterSwipe() throws Exception {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        startMainActivityWithURL(mTestServer.getURL(TEST_PAGE_FILE_PATH));
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(TEST_PAGE_FILE_PATH));
 
-        newIncognitoTabFromMenu();
+        mActivityTestRule.newIncognitoTabFromMenu();
         // Tab states are not saved for empty NTP tabs, so navigate to any page to trigger a file
         // to be saved.
-        loadUrl(mTestServer.getURL(TEST_PAGE_FILE_PATH));
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE_FILE_PATH));
 
         File tabStateDir = TabbedModeTabPersistencePolicy.getOrCreateTabbedModeStateDirectory();
-        TabModel normalModel = getActivity().getTabModelSelector().getModel(false);
-        TabModel incognitoModel = getActivity().getTabModelSelector().getModel(true);
+        TabModel normalModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
+        TabModel incognitoModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(true);
         File normalTabFile = new File(tabStateDir,
                 TabState.getTabStateFilename(
                         normalModel.getTabAt(normalModel.getCount() - 1).getId(), false));
@@ -1732,31 +1936,14 @@
 
         // Although we're destroying the activity, the Application will still live on since its in
         // the same process as this test.
-        ApplicationTestUtils.finishActivity(getActivity());
+        ApplicationTestUtils.finishActivity(mActivityTestRule.getActivity());
 
         // Activity will be started without a savedInstanceState.
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         assertFileExists(normalTabFile, true);
         assertFileExists(incognitoTabFile, false);
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        float dpToPx = getInstrumentation().getContext().getResources().getDisplayMetrics().density;
-        mPxToDp = 1.0f / dpToPx;
-
-        // Exclude the tests that can launch directly to a page other than the NTP.
-        if (getName().equals("testOpenAndCloseNewTabButton")
-                || getName().equals("testSwitchToTabThatDoesNotHaveThumbnail")
-                || getName().equals("testCloseTabPortrait")
-                || getName().equals("testCloseTabLandscape")
-                || getName().equals("testTabsAreDestroyedOnModelDestruction")
-                || getName().equals("testIncognitoTabsNotRestoredAfterSwipe")) {
-            return;
-        }
-        startMainActivityFromLauncher();
-    }
-
     private void assertFileExists(final File fileToCheck, final boolean expected)
             throws InterruptedException {
         CriteriaHelper.pollInstrumentationThread(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java
index 3e8ed36..5e3ec1b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java
@@ -13,14 +13,25 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ApplicationState;
 import org.chromium.base.ApplicationStatus;
+import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 
@@ -33,22 +44,27 @@
 /**
  * Tests for launching Chrome.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
 @RetryOnFailure
-public class LauncherActivityTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+public class LauncherActivityTest {
+    @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private Context mContext;
     private static final long DEVICE_STARTUP_TIMEOUT_MS = scaleTimeout(15000);
 
-    public LauncherActivityTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        mContext = getInstrumentation().getTargetContext();
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
     }
 
+    @Test
     @SmallTest
     public void testLaunchWithUrlNoScheme() {
         // Prepare intent
@@ -59,9 +75,10 @@
 
         final Activity startedActivity = tryLaunchingChrome(intent);
         final Intent activityIntent = startedActivity.getIntent();
-        assertEquals(intentUrl, activityIntent.getDataString());
+        Assert.assertEquals(intentUrl, activityIntent.getDataString());
     }
 
+    @Test
     @SmallTest
     public void testDoesNotCrashWithBadParcel() {
         // Prepare bad intent
@@ -78,10 +95,12 @@
 
         final Activity startedActivity = tryLaunchingChrome(intent);
         final Intent activityIntent = startedActivity.getIntent();
-        assertEquals("Data was not preserved", intent.getData(), activityIntent.getData());
-        assertEquals("Action was not preserved", intent.getAction(), activityIntent.getAction());
+        Assert.assertEquals("Data was not preserved", intent.getData(), activityIntent.getData());
+        Assert.assertEquals(
+                "Action was not preserved", intent.getAction(), activityIntent.getAction());
     }
 
+    @Test
     @SmallTest
     public void testDoesNotCrashWithNoUriInViewIntent() {
         // Prepare intent
@@ -128,10 +147,6 @@
         return launchedActivity.get();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-    }
-
     /**
      * This Parcelable does not adhere to the form standards of a well formed Parcelable and will
      * thus cause a BadParcelableException.  The lint suppression is needed since it detects that
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
index 965581b..294fae6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
@@ -8,7 +8,9 @@
 import android.content.SharedPreferences.Editor;
 import android.os.Handler;
 import android.os.Looper;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.text.TextUtils;
@@ -16,9 +18,14 @@
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseActivityInstrumentationTestCase;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
@@ -35,6 +42,7 @@
 import org.chromium.chrome.browser.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.ui.test.util.UiRestriction;
@@ -44,8 +52,12 @@
 /**
  * Tests the DownloadActivity and the DownloadManagerUi.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
-public class DownloadActivityTest extends BaseActivityInstrumentationTestCase<DownloadActivity> {
+public class DownloadActivityTest {
+    @Rule
+    public ActivityTestRule<DownloadActivity> mActivityTestRule =
+            new ActivityTestRule<>(DownloadActivity.class);
 
     private static class TestObserver extends RecyclerView.AdapterDataObserver
             implements SelectionObserver<DownloadHistoryItemWrapper>,
@@ -101,14 +113,8 @@
     private RecyclerView mRecyclerView;
     private TextView mSpaceUsedDisplay;
 
-    public DownloadActivityTest() {
-        super(DownloadActivity.class);
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-
         Editor editor = ContextUtils.getAppSharedPreferences().edit();
         editor.putBoolean(PREF_SHOW_STORAGE_INFO_HEADER, true).apply();
 
@@ -119,17 +125,19 @@
         mStubbedProvider.getSelectionDelegate().addObserver(mAdapterObserver);
 
         startDownloadActivity();
-        mUi = getActivity().getDownloadManagerUiForTests();
+        mUi = mActivityTestRule.getActivity().getDownloadManagerUiForTests();
         mAdapter = mUi.getDownloadHistoryAdapterForTests();
         mAdapter.registerAdapterDataObserver(mAdapterObserver);
 
         mSpaceUsedDisplay =
-                (TextView) getActivity().findViewById(R.id.size_downloaded);
-        mRecyclerView = ((RecyclerView) getActivity().findViewById(R.id.recycler_view));
+                (TextView) mActivityTestRule.getActivity().findViewById(R.id.size_downloaded);
+        mRecyclerView =
+                ((RecyclerView) mActivityTestRule.getActivity().findViewById(R.id.recycler_view));
 
         mAdapter.getSpaceDisplayForTests().addObserverForTests(mAdapterObserver);
     }
 
+    @Test
     @MediumTest
     @RetryOnFailure(message = "crbug.com/751492")
     public void testSpaceDisplay() throws Exception {
@@ -148,7 +156,7 @@
         ThreadUtils.runOnUiThread(() -> mAdapter.onDownloadItemCreated(updateItem));
         mAdapterObserver.onChangedCallback.waitForCallback(callCount, 2);
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(spaceDisplayCallCount);
-        assertEquals("6.50 GB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals("6.50 GB downloaded", mSpaceUsedDisplay.getText());
 
         // Mark one download as deleted on disk, which should prevent it from being counted.
         callCount = mAdapterObserver.onChangedCallback.getCallCount();
@@ -158,7 +166,7 @@
         ThreadUtils.runOnUiThread(() -> mAdapter.onDownloadItemUpdated(deletedItem));
         mAdapterObserver.onChangedCallback.waitForCallback(callCount, 2);
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(spaceDisplayCallCount);
-        assertEquals("5.50 GB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals("5.50 GB downloaded", mSpaceUsedDisplay.getText());
 
         // Say that the offline page has been deleted.
         callCount = mAdapterObserver.onChangedCallback.getCallCount();
@@ -170,10 +178,11 @@
                         deletedPage.getGuid()));
         mAdapterObserver.onChangedCallback.waitForCallback(callCount, 2);
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(spaceDisplayCallCount);
-        assertEquals("512.00 MB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals("512.00 MB downloaded", mSpaceUsedDisplay.getText());
     }
 
     /** Clicking on filters affects various things in the UI. */
+    @Test
     @MediumTest
     public void testFilters() throws Exception {
         // This first check is a Criteria because initialization of the Adapter is asynchronous.
@@ -188,7 +197,7 @@
         // should stay.
         int spaceDisplayCallCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
         clickOnFilter(mUi, 1);
-        assertEquals(3, mAdapter.getItemCount());
+        Assert.assertEquals(3, mAdapter.getItemCount());
 
         // Check that the number of items displayed is correct.
         // We need to poll because RecyclerView doesn't animate changes immediately.
@@ -201,9 +210,10 @@
 
         // Filtering doesn't affect the total download size.
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(spaceDisplayCallCount);
-        assertEquals("6.00 GB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals("6.00 GB downloaded", mSpaceUsedDisplay.getText());
     }
 
+    @Test
     @MediumTest
     @RetryOnFailure
     public void testDeleteFiles() throws Exception {
@@ -222,25 +232,27 @@
         toggleItemSelection(3);
 
         // Click the delete button, which should delete the items and reset the toolbar.
-        assertEquals(12, mAdapter.getItemCount());
+        Assert.assertEquals(12, mAdapter.getItemCount());
         // checkForExternallyRemovedFiles() should have been called once already in onResume().
-        assertEquals(1,
-                mStubbedProvider.getDownloadDelegate().checkExternalCallback.getCallCount());
-        assertEquals(0,
-                mStubbedProvider.getDownloadDelegate().removeDownloadCallback.getCallCount());
-        assertEquals(0, mStubbedProvider.getOfflinePageBridge().deleteItemCallback.getCallCount());
-        ThreadUtils.runOnUiThread(() -> assertTrue(mUi.getDownloadManagerToolbarForTests().getMenu()
-                .performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
+        Assert.assertEquals(
+                1, mStubbedProvider.getDownloadDelegate().checkExternalCallback.getCallCount());
+        Assert.assertEquals(
+                0, mStubbedProvider.getDownloadDelegate().removeDownloadCallback.getCallCount());
+        Assert.assertEquals(
+                0, mStubbedProvider.getOfflinePageBridge().deleteItemCallback.getCallCount());
+        ThreadUtils.runOnUiThread(() -> Assert.assertTrue(mUi.getDownloadManagerToolbarForTests()
+                    .getMenu().performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
 
         mStubbedProvider.getDownloadDelegate().removeDownloadCallback.waitForCallback(0);
-        assertEquals(1,
-                mStubbedProvider.getDownloadDelegate().checkExternalCallback.getCallCount());
+        Assert.assertEquals(
+                1, mStubbedProvider.getDownloadDelegate().checkExternalCallback.getCallCount());
         mStubbedProvider.getOfflinePageBridge().deleteItemCallback.waitForCallback(0);
-        assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
-        assertEquals(9, mAdapter.getItemCount());
-        assertEquals("0.65 KB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertEquals(9, mAdapter.getItemCount());
+        Assert.assertEquals("0.65 KB downloaded", mSpaceUsedDisplay.getText());
     }
 
+    @Test
     @MediumTest
     @RetryOnFailure
     public void testUndoDelete() throws Exception {
@@ -278,38 +290,39 @@
         toggleItemSelection(2);
         toggleItemSelection(6);
 
-        assertEquals(15, mAdapter.getItemCount());
+        Assert.assertEquals(15, mAdapter.getItemCount());
 
         // Click the delete button.
         callCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
-        ThreadUtils.runOnUiThread(() -> assertTrue(mUi.getDownloadManagerToolbarForTests().getMenu()
-                .performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
+        ThreadUtils.runOnUiThread(() -> Assert.assertTrue(mUi.getDownloadManagerToolbarForTests()
+                    .getMenu().performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(callCount);
 
         // Assert that items are temporarily removed from the adapter. The two selected items,
         // one duplicate item, and one date bucket should be removed.
-        assertEquals(11, mAdapter.getItemCount());
-        assertEquals("1.00 GB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals(11, mAdapter.getItemCount());
+        Assert.assertEquals("1.00 GB downloaded", mSpaceUsedDisplay.getText());
 
         // Click "Undo" on the snackbar.
         callCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
         final View rootView = mUi.getView().getRootView();
-        assertNotNull(rootView.findViewById(R.id.snackbar));
+        Assert.assertNotNull(rootView.findViewById(R.id.snackbar));
         ThreadUtils.runOnUiThread(
                 (Runnable) () -> rootView.findViewById(R.id.snackbar_button).callOnClick());
 
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(callCount);
 
         // Assert that items are restored.
-        assertEquals(0,
-                mStubbedProvider.getDownloadDelegate().removeDownloadCallback.getCallCount());
-        assertEquals(0,
-                mStubbedProvider.getOfflinePageBridge().deleteItemCallback.getCallCount());
-        assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
-        assertEquals(15, mAdapter.getItemCount());
-        assertEquals("6.50 GB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals(
+                0, mStubbedProvider.getDownloadDelegate().removeDownloadCallback.getCallCount());
+        Assert.assertEquals(
+                0, mStubbedProvider.getOfflinePageBridge().deleteItemCallback.getCallCount());
+        Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertEquals(15, mAdapter.getItemCount());
+        Assert.assertEquals("6.50 GB downloaded", mSpaceUsedDisplay.getText());
     }
 
+    @Test
     @MediumTest
     @RetryOnFailure
     public void testUndoDeleteDuplicatesSelected() throws Exception {
@@ -345,32 +358,33 @@
         toggleItemSelection(2);
         toggleItemSelection(3);
 
-        assertEquals(15, mAdapter.getItemCount());
+        Assert.assertEquals(15, mAdapter.getItemCount());
 
         // Click the delete button.
         callCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
-        ThreadUtils.runOnUiThread(() -> assertTrue(mUi.getDownloadManagerToolbarForTests().getMenu()
-                .performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
+        ThreadUtils.runOnUiThread(() -> Assert.assertTrue(mUi.getDownloadManagerToolbarForTests()
+                    .getMenu().performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(callCount);
 
         // Assert that the two items and their date bucket are temporarily removed from the adapter.
-        assertEquals(12, mAdapter.getItemCount());
-        assertEquals("6.00 GB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals(12, mAdapter.getItemCount());
+        Assert.assertEquals("6.00 GB downloaded", mSpaceUsedDisplay.getText());
 
         // Click "Undo" on the snackbar.
         callCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
         final View rootView = mUi.getView().getRootView();
-        assertNotNull(rootView.findViewById(R.id.snackbar));
+        Assert.assertNotNull(rootView.findViewById(R.id.snackbar));
         ThreadUtils.runOnUiThread(
                 (Runnable) () -> rootView.findViewById(R.id.snackbar_button).callOnClick());
 
         mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(callCount);
 
         // Assert that items are restored.
-        assertEquals(15, mAdapter.getItemCount());
-        assertEquals("6.50 GB downloaded", mSpaceUsedDisplay.getText());
+        Assert.assertEquals(15, mAdapter.getItemCount());
+        Assert.assertEquals("6.50 GB downloaded", mSpaceUsedDisplay.getText());
     }
 
+    @Test
     @MediumTest
     public void testShareFiles() throws Exception {
         // Adapter positions:
@@ -390,101 +404,119 @@
         // Select an image, download item #6.
         toggleItemSelection(2);
         Intent shareIntent = mUi.createShareIntent();
-        assertEquals("Incorrect intent action", Intent.ACTION_SEND, shareIntent.getAction());
-        assertEquals("Incorrect intent mime type", "image/png", shareIntent.getType());
-        assertNotNull("Intent expected to have stream",
-                shareIntent.getExtras().get(Intent.EXTRA_STREAM));
-        assertNull("Intent not expected to have parcelable ArrayList",
+        Assert.assertEquals("Incorrect intent action", Intent.ACTION_SEND, shareIntent.getAction());
+        Assert.assertEquals("Incorrect intent mime type", "image/png", shareIntent.getType());
+        Assert.assertNotNull(
+                "Intent expected to have stream", shareIntent.getExtras().get(Intent.EXTRA_STREAM));
+        Assert.assertNull("Intent not expected to have parcelable ArrayList",
                 shareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM));
 
         // Scroll to ensure the item at position 8 is visible.
         ThreadUtils.runOnUiThread(() -> mRecyclerView.scrollToPosition(9));
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // Select another image, download item #0.
         toggleItemSelection(9);
         shareIntent = mUi.createShareIntent();
-        assertEquals("Incorrect intent action", Intent.ACTION_SEND_MULTIPLE,
-                shareIntent.getAction());
-        assertEquals("Incorrect intent mime type", "image/*", shareIntent.getType());
-        assertEquals("Intent expected to have parcelable ArrayList",
-                2, shareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM).size());
+        Assert.assertEquals(
+                "Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction());
+        Assert.assertEquals("Incorrect intent mime type", "image/*", shareIntent.getType());
+        Assert.assertEquals("Intent expected to have parcelable ArrayList", 2,
+                shareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM).size());
 
         // Scroll to ensure the item at position 5 is visible.
         ThreadUtils.runOnUiThread(() -> mRecyclerView.scrollToPosition(6));
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // Select non-image item, download item #4.
         toggleItemSelection(6);
         shareIntent = mUi.createShareIntent();
-        assertEquals("Incorrect intent action", Intent.ACTION_SEND_MULTIPLE,
-                shareIntent.getAction());
-        assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
-        assertEquals("Intent expected to have parcelable ArrayList",
-                3, shareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM).size());
+        Assert.assertEquals(
+                "Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction());
+        Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
+        Assert.assertEquals("Intent expected to have parcelable ArrayList", 3,
+                shareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM).size());
 
         // Scroll to ensure the item at position 2 is visible.
         ThreadUtils.runOnUiThread(() -> mRecyclerView.scrollToPosition(3));
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // Select an offline page #3.
         toggleItemSelection(3);
         shareIntent = mUi.createShareIntent();
-        assertEquals("Incorrect intent action", Intent.ACTION_SEND_MULTIPLE,
-                shareIntent.getAction());
-        assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
-        assertEquals("Intent expected to have parcelable ArrayList",
-                3, shareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM).size());
-        assertEquals("Intent expected to have plain text for offline page URL",
+        Assert.assertEquals(
+                "Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction());
+        Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
+        Assert.assertEquals("Intent expected to have parcelable ArrayList", 3,
+                shareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM).size());
+        Assert.assertEquals("Intent expected to have plain text for offline page URL",
                 "https://thangs.com",
                 IntentUtils.safeGetStringExtra(shareIntent, Intent.EXTRA_TEXT));
     }
 
+    @Test
     @MediumTest
     public void testToggleSelection() throws Exception {
         // The selection toolbar should not be showing.
-        assertTrue(mAdapterObserver.mOnSelectionItems.isEmpty());
-        assertEquals(View.VISIBLE, getActivity().findViewById(R.id.close_menu_id).getVisibility());
-        assertEquals(View.GONE,
-                getActivity().findViewById(R.id.selection_mode_number).getVisibility());
-        assertNull(getActivity().findViewById(R.id.selection_mode_share_menu_id));
-        assertNull(getActivity().findViewById(R.id.selection_mode_delete_menu_id));
-        assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertTrue(mAdapterObserver.mOnSelectionItems.isEmpty());
+        Assert.assertEquals(View.VISIBLE,
+                mActivityTestRule.getActivity().findViewById(R.id.close_menu_id).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mActivityTestRule.getActivity()
+                        .findViewById(R.id.selection_mode_number)
+                        .getVisibility());
+        Assert.assertNull(
+                mActivityTestRule.getActivity().findViewById(R.id.selection_mode_share_menu_id));
+        Assert.assertNull(
+                mActivityTestRule.getActivity().findViewById(R.id.selection_mode_delete_menu_id));
+        Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
 
         // Select an item.
         toggleItemSelection(2);
 
         // The toolbar should flip states to allow doing things with the selected items.
-        assertNull(getActivity().findViewById(R.id.close_menu_id));
-        assertEquals(View.VISIBLE,
-                getActivity().findViewById(R.id.selection_mode_number).getVisibility());
-        assertEquals(View.VISIBLE,
-                getActivity().findViewById(R.id.selection_mode_share_menu_id).getVisibility());
-        assertEquals(View.VISIBLE,
-                getActivity().findViewById(R.id.selection_mode_delete_menu_id).getVisibility());
-        assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertNull(mActivityTestRule.getActivity().findViewById(R.id.close_menu_id));
+        Assert.assertEquals(View.VISIBLE,
+                mActivityTestRule.getActivity()
+                        .findViewById(R.id.selection_mode_number)
+                        .getVisibility());
+        Assert.assertEquals(View.VISIBLE,
+                mActivityTestRule.getActivity()
+                        .findViewById(R.id.selection_mode_share_menu_id)
+                        .getVisibility());
+        Assert.assertEquals(View.VISIBLE,
+                mActivityTestRule.getActivity()
+                        .findViewById(R.id.selection_mode_delete_menu_id)
+                        .getVisibility());
+        Assert.assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
 
         // Deselect the same item.
         toggleItemSelection(2);
 
         // The toolbar should flip back.
-        assertTrue(mAdapterObserver.mOnSelectionItems.isEmpty());
-        assertEquals(View.VISIBLE, getActivity().findViewById(R.id.close_menu_id).getVisibility());
-        assertEquals(View.GONE,
-                getActivity().findViewById(R.id.selection_mode_number).getVisibility());
-        assertNull(getActivity().findViewById(R.id.selection_mode_share_menu_id));
-        assertNull(getActivity().findViewById(R.id.selection_mode_delete_menu_id));
-        assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertTrue(mAdapterObserver.mOnSelectionItems.isEmpty());
+        Assert.assertEquals(View.VISIBLE,
+                mActivityTestRule.getActivity().findViewById(R.id.close_menu_id).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mActivityTestRule.getActivity()
+                        .findViewById(R.id.selection_mode_number)
+                        .getVisibility());
+        Assert.assertNull(
+                mActivityTestRule.getActivity().findViewById(R.id.selection_mode_share_menu_id));
+        Assert.assertNull(
+                mActivityTestRule.getActivity().findViewById(R.id.selection_mode_delete_menu_id));
+        Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
     }
 
+    @Test
     @MediumTest
     public void testSearchView() throws Exception {
         final DownloadManagerToolbar toolbar = mUi.getDownloadManagerToolbarForTests();
         View toolbarSearchView = toolbar.getSearchViewForTests();
-        assertEquals(View.GONE, toolbarSearchView.getVisibility());
+        Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility());
 
         toggleItemSelection(2);
-        assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
 
         int callCount = mAdapterObserver.onSelectionCallback.getCallCount();
         ThreadUtils.runOnUiThreadBlocking(
@@ -492,22 +524,22 @@
 
         // The selection should be cleared when a search is started.
         mAdapterObserver.onSelectionCallback.waitForCallback(callCount, 1);
-        assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
-        assertEquals(View.VISIBLE, toolbarSearchView.getVisibility());
+        Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertEquals(View.VISIBLE, toolbarSearchView.getVisibility());
 
         // Select an item and assert that the search view is no longer showing.
         toggleItemSelection(2);
-        assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
-        assertEquals(View.GONE, toolbarSearchView.getVisibility());
+        Assert.assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility());
 
         // Clear the selection and assert that the search view is showing again.
         toggleItemSelection(2);
-        assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
-        assertEquals(View.VISIBLE, toolbarSearchView.getVisibility());
+        Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
+        Assert.assertEquals(View.VISIBLE, toolbarSearchView.getVisibility());
 
         // Close the search view.
         ThreadUtils.runOnUiThreadBlocking(() -> toolbar.onNavigationBack());
-        assertEquals(View.GONE, toolbarSearchView.getVisibility());
+        Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility());
     }
 
     private DownloadActivity startDownloadActivity() throws Exception {
@@ -531,10 +563,10 @@
 
         // Start the activity up.
         Intent intent = new Intent();
-        intent.setClass(getInstrumentation().getTargetContext(), DownloadActivity.class);
+        intent.setClass(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                DownloadActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        setActivityIntent(intent);
-        return getActivity();
+        return mActivityTestRule.launchActivity(intent);
     }
 
     private void clickOnFilter(final DownloadManagerUi ui, final int position) throws Exception {
@@ -550,7 +582,7 @@
     private void toggleItemSelection(int position) throws Exception {
         int callCount = mAdapterObserver.onSelectionCallback.getCallCount();
         ViewHolder mostRecentHolder = mRecyclerView.findViewHolderForAdapterPosition(position);
-        assertTrue(mostRecentHolder instanceof DownloadHistoryItemViewHolder);
+        Assert.assertTrue(mostRecentHolder instanceof DownloadHistoryItemViewHolder);
         final DownloadItemView itemView =
                 ((DownloadHistoryItemViewHolder) mostRecentHolder).getItemView();
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/gcore/MockConnectedTaskTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/gcore/MockConnectedTaskTest.java
index e8e1e9f..9d49dac 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/gcore/MockConnectedTaskTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/gcore/MockConnectedTaskTest.java
@@ -6,22 +6,27 @@
 
 import android.support.test.filters.SmallTest;
 
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.test.gcore.MockChromeGoogleApiClient;
 
 /** Tests for {@link ConnectedTask} */
-public class MockConnectedTaskTest extends TestCase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class MockConnectedTaskTest {
     private MockChromeGoogleApiClient mClient;
     private MockConnectedTask<MockChromeGoogleApiClient> mTask;
 
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         mClient = new MockChromeGoogleApiClient();
         mTask = new MockConnectedTask<>(mClient);
     }
 
+    @Test
     @SmallTest
     @Feature({"GCore"})
     public void testConnectionSuccess() {
@@ -38,6 +43,7 @@
         mClient.assertNoOtherMethodsCalled();
     }
 
+    @Test
     @SmallTest
     @Feature({"GCore"})
     public void testConnectionFailureWithGooglePlayServicesAvailable() {
@@ -54,6 +60,7 @@
         mClient.assertNoOtherMethodsCalled();
     }
 
+    @Test
     @SmallTest
     @Feature({"GCore"})
     public void testConnectionFailureWithGooglePlayServicesUnavailable() {
@@ -70,6 +77,7 @@
         mClient.assertNoOtherMethodsCalled();
     }
 
+    @Test
     @SmallTest
     @Feature({"GCore"})
     public void testRetryLimit() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
index fcc478f..3733701a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
@@ -7,20 +7,30 @@
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.util.Pair;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.TabState;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
 import org.chromium.chrome.browser.tabmodel.TestTabModelDirectory;
 import org.chromium.chrome.browser.tabmodel.TestTabModelDirectory.TabStateInfo;
-import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.LoadUrlParams;
@@ -31,36 +41,37 @@
 /**
  * Tests for the Incognito Notification service.
  */
-public class IncognitoNotificationServiceTest extends ChromeTabbedActivityTestBase {
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        // Each test will start its own activity as needed.
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+public class IncognitoNotificationServiceTest {
+    @Rule
+    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
 
     private void createTabOnUiThread() {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getActivity().getTabCreator(true).createNewTab(new LoadUrlParams("about:blank"),
-                        TabLaunchType.FROM_CHROME_UI, null);
+                mActivityTestRule.getActivity().getTabCreator(true).createNewTab(
+                        new LoadUrlParams("about:blank"), TabLaunchType.FROM_CHROME_UI, null);
             }
         });
     }
 
     private void sendClearIncognitoIntent() throws CanceledException {
-        PendingIntent clearIntent =
-                IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(
-                        getInstrumentation().getTargetContext());
+        PendingIntent clearIntent = IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(
+                InstrumentationRegistry.getTargetContext());
         clearIntent.send();
-
     }
 
+    @Test
     @Feature("Incognito")
     @MediumTest
     public void testSingleRunningChromeTabbedActivity()
             throws InterruptedException, CanceledException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         createTabOnUiThread();
         createTabOnUiThread();
@@ -68,7 +79,10 @@
         CriteriaHelper.pollUiThread(Criteria.equals(2, new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return getActivity().getTabModelSelector().getModel(true).getCount();
+                return mActivityTestRule.getActivity()
+                        .getTabModelSelector()
+                        .getModel(true)
+                        .getCount();
             }
         }));
 
@@ -76,14 +90,17 @@
                 new Callable<Profile>() {
                     @Override
                     public Profile call() throws Exception {
-                        return getActivity().getTabModelSelector().getModel(true).getProfile();
+                        return mActivityTestRule.getActivity()
+                                .getTabModelSelector()
+                                .getModel(true)
+                                .getProfile();
                     }
                 });
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertTrue(incognitoProfile.isOffTheRecord());
-                assertTrue(incognitoProfile.isNativeInitialized());
+                Assert.assertTrue(incognitoProfile.isOffTheRecord());
+                Assert.assertTrue(incognitoProfile.isNativeInitialized());
             }
         });
 
@@ -92,7 +109,10 @@
         CriteriaHelper.pollUiThread(Criteria.equals(0, new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return getActivity().getTabModelSelector().getModel(true).getCount();
+                return mActivityTestRule.getActivity()
+                        .getTabModelSelector()
+                        .getModel(true)
+                        .getCount();
             }
         }));
         CriteriaHelper.pollUiThread(new Criteria() {
@@ -103,11 +123,12 @@
         });
     }
 
+    @Test
     @Feature("Incognito")
     @MediumTest
     @RetryOnFailure
     public void testNoAliveProcess() throws Exception {
-        Context context = getInstrumentation().getTargetContext();
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         final TestTabModelDirectory tabbedModeDirectory = new TestTabModelDirectory(
                 context, "tabs", String.valueOf(0));
 
@@ -132,8 +153,8 @@
         TabPersistentStore.setBaseStateDirectoryForTests(tabbedModeDirectory.getBaseDirectory());
 
         File[] tabbedModeFiles = tabbedModeDirectory.getDataDirectory().listFiles();
-        assertNotNull(tabbedModeFiles);
-        assertEquals(5, tabbedModeFiles.length);
+        Assert.assertNotNull(tabbedModeFiles);
+        Assert.assertEquals(5, tabbedModeFiles.length);
 
         int incognitoCount = 0;
         int normalCount = 0;
@@ -143,8 +164,8 @@
             if (tabFileInfo.second) incognitoCount++;
             else normalCount++;
         }
-        assertEquals(2, normalCount);
-        assertEquals(3, incognitoCount);
+        Assert.assertEquals(2, normalCount);
+        Assert.assertEquals(3, incognitoCount);
 
         sendClearIncognitoIntent();
 
@@ -181,9 +202,8 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertFalse(LibraryLoader.isInitialized());
+                Assert.assertFalse(LibraryLoader.isInitialized());
             }
         });
     }
-
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/input/TextSuggestionMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/input/TextSuggestionMenuTest.java
index 2d460755..371204b5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/input/TextSuggestionMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/input/TextSuggestionMenuTest.java
@@ -8,10 +8,17 @@
 import android.view.View;
 
 import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.R;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.input.SuggestionsPopupWindow;
@@ -27,24 +34,31 @@
 /**
  * Integration tests for the text suggestion menu.
  */
-public class TextSuggestionMenuTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+public class TextSuggestionMenuTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String URL =
             "data:text/html, <div contenteditable id=\"div\">iuvwneaoanls</div>";
 
-    public TextSuggestionMenuTest() {
-        super(ChromeActivity.class);
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @LargeTest
     @RetryOnFailure
     public void testDeleteMisspelledWord() throws InterruptedException, TimeoutException {
-        loadUrl(URL);
-        final ContentViewCore cvc = getActivity().getActivityTab().getContentViewCore();
+        mActivityTestRule.loadUrl(URL);
+        final ContentViewCore cvc =
+                mActivityTestRule.getActivity().getActivityTab().getContentViewCore();
         WebContents webContents = cvc.getWebContents();
 
         // The spell checker is called asynchronously, in an idle-time callback. By waiting for an
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmIncognitoTest.java
index bafb3e9a..0a2789c5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmIncognitoTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/UkmIncognitoTest.java
@@ -7,41 +7,57 @@
 import android.support.test.filters.SmallTest;
 
 import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.content.browser.test.util.JavaScriptUtils;
 import org.chromium.ui.base.PageTransition;
 
 /**
  * Tests for UKM monitoring of incognito activity.
  */
-@CommandLineFlags.Add({"force-enable-metrics-reporting"})
-public class UkmIncognitoTest extends ChromeTabbedActivityTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+        "force-enable-metrics-reporting"})
+public class UkmIncognitoTest {
+    @Rule
+    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+
     private static final String DEBUG_PAGE = "chrome://ukm";
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     public String getUkmState(Tab normalTab) throws Exception {
-        loadUrlInTab(DEBUG_PAGE, PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR, normalTab);
+        mActivityTestRule.loadUrlInTab(
+                DEBUG_PAGE, PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR, normalTab);
         return JavaScriptUtils.executeJavaScriptAndWaitForResult(
                 normalTab.getContentViewCore().getWebContents(),
                 "document.getElementById('state').textContent");
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testUkmIncognito() throws Exception {
-        Tab normalTab = getActivity().getActivityTab();
+        Tab normalTab = mActivityTestRule.getActivity().getActivityTab();
 
         Assert.assertEquals("UKM State:", "\"True\"", getUkmState(normalTab));
 
-        newIncognitoTabFromMenu();
+        mActivityTestRule.newIncognitoTabFromMenu();
 
         Assert.assertEquals("UKM State:", "\"False\"", getUkmState(normalTab));
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/SuggestionAnswerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/SuggestionAnswerTest.java
index a3182151..dbca1e46 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/SuggestionAnswerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/SuggestionAnswerTest.java
@@ -6,32 +6,41 @@
 
 import android.support.test.filters.SmallTest;
 
-import junit.framework.TestCase;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-public class SuggestionAnswerTest extends TestCase {
+import org.chromium.base.test.BaseJUnit4ClassRunner;
+
+@RunWith(BaseJUnit4ClassRunner.class)
+public class SuggestionAnswerTest {
+    @Test
     @SmallTest
     public void testMalformedJsonReturnsNull() {
         String json = "} malformed json {";
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
-        assertNull(answer);
+        Assert.assertNull(answer);
     }
 
+    @Test
     @SmallTest
     public void testEmpyJsonReturnsNull() {
         String json = "";
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
-        assertNull(answer);
+        Assert.assertNull(answer);
     }
 
+    @Test
     @SmallTest
     public void testOneLineReturnsNull() {
         String json = "{ 'l': ["
                 + "  { 'il': { 't': [{ 't': 'text', 'tt': 8 }] } }, "
                 + "] }";
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
-        assertNull(answer);
+        Assert.assertNull(answer);
     }
 
+    @Test
     @SmallTest
     public void testTwoLinesDoesntReturnNull() {
         String json = "{ 'l': ["
@@ -39,9 +48,10 @@
                 + "  { 'il': { 't': [{ 't': 'other text', 'tt': 5 }] } }"
                 + "] }";
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
-        assertNotNull(answer);
+        Assert.assertNotNull(answer);
     }
 
+    @Test
     @SmallTest
     public void testThreeLinesReturnsNull() {
         String json = "{ 'l': ["
@@ -50,9 +60,10 @@
                 + "  { 'il': { 't': [{ 't': 'yet more text', 'tt': 13 }] } }"
                 + "] }";
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
-        assertNull(answer);
+        Assert.assertNull(answer);
     }
 
+    @Test
     @SmallTest
     public void testFiveLinesReturnsNull() {
         String json = "{ 'l': ["
@@ -63,9 +74,10 @@
                 + "  { 'il': { 't': [{ 't': 'line 5', 'tt': 5 }] } }"
                 + "] }";
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
-        assertNull(answer);
+        Assert.assertNull(answer);
     }
 
+    @Test
     @SmallTest
     public void testPropertyPresence() {
         String json = "{ 'l': ["
@@ -78,18 +90,19 @@
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
 
         SuggestionAnswer.ImageLine firstLine = answer.getFirstLine();
-        assertEquals(2, firstLine.getTextFields().size());
-        assertFalse(firstLine.hasAdditionalText());
-        assertFalse(firstLine.hasStatusText());
-        assertTrue(firstLine.hasImage());
+        Assert.assertEquals(2, firstLine.getTextFields().size());
+        Assert.assertFalse(firstLine.hasAdditionalText());
+        Assert.assertFalse(firstLine.hasStatusText());
+        Assert.assertTrue(firstLine.hasImage());
 
         SuggestionAnswer.ImageLine secondLine = answer.getSecondLine();
-        assertEquals(1, secondLine.getTextFields().size());
-        assertTrue(secondLine.hasAdditionalText());
-        assertTrue(secondLine.hasStatusText());
-        assertFalse(secondLine.hasImage());
+        Assert.assertEquals(1, secondLine.getTextFields().size());
+        Assert.assertTrue(secondLine.hasAdditionalText());
+        Assert.assertTrue(secondLine.hasStatusText());
+        Assert.assertFalse(secondLine.hasImage());
     }
 
+    @Test
     @SmallTest
     public void testContents() {
         String json = "{ 'l': ["
@@ -102,18 +115,18 @@
         SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json);
 
         SuggestionAnswer.ImageLine firstLine = answer.getFirstLine();
-        assertEquals("text", firstLine.getTextFields().get(0).getText());
-        assertEquals(8, firstLine.getTextFields().get(0).getType());
-        assertEquals("moar", firstLine.getTextFields().get(1).getText());
-        assertEquals(0, firstLine.getTextFields().get(1).getType());
-        assertEquals("hi there", firstLine.getAdditionalText().getText());
-        assertEquals(7, firstLine.getAdditionalText().getType());
+        Assert.assertEquals("text", firstLine.getTextFields().get(0).getText());
+        Assert.assertEquals(8, firstLine.getTextFields().get(0).getType());
+        Assert.assertEquals("moar", firstLine.getTextFields().get(1).getText());
+        Assert.assertEquals(0, firstLine.getTextFields().get(1).getType());
+        Assert.assertEquals("hi there", firstLine.getAdditionalText().getText());
+        Assert.assertEquals(7, firstLine.getAdditionalText().getType());
 
         SuggestionAnswer.ImageLine secondLine = answer.getSecondLine();
-        assertEquals("ftw", secondLine.getTextFields().get(0).getText());
-        assertEquals(6006, secondLine.getTextFields().get(0).getType());
-        assertEquals("shop S-Mart", secondLine.getStatusText().getText());
-        assertEquals(666, secondLine.getStatusText().getType());
-        assertEquals("Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGlj", secondLine.getImage());
+        Assert.assertEquals("ftw", secondLine.getTextFields().get(0).getText());
+        Assert.assertEquals(6006, secondLine.getTextFields().get(0).getType());
+        Assert.assertEquals("shop S-Mart", secondLine.getStatusText().getText());
+        Assert.assertEquals(666, secondLine.getStatusText().getType());
+        Assert.assertEquals("Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGlj", secondLine.getImage());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
index d982db1b..041a641 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
@@ -13,28 +13,44 @@
 
 import com.google.protobuf.nano.MessageNano;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.library_loader.ProcessInitException;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.preferences.website.ContentSetting;
 import org.chromium.chrome.browser.preferences.website.GeolocationInfo;
 import org.chromium.chrome.browser.preferences.website.WebsitePreferenceBridge;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 import java.util.Locale;
 
 /**
  * Tests for GeolocationHeader and GeolocationTracker.
  */
-public class GeolocationHeaderTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+public class GeolocationHeaderTest {
+
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String SEARCH_URL_1 = "https://www.google.com/search?q=potatoes";
     private static final String SEARCH_URL_2 = "https://www.google.co.jp/webhp?#q=dinosaurs";
     private static final String DISABLE_FEATURES = "disable-features=";
     private static final String ENABLE_FEATURES = "enable-features=";
-    private static final String FEATURE_SEPARATOR = ",";
     private static final String XGEO_VISIBLE_NETWORKS_FEATURE = "XGEOVisibleNetworks";
     private static final String GOOGLE_BASE_URL_SWITCH = "google-base-url=https://www.google.com";
     private static final double LOCATION_LAT = 20.3;
@@ -43,15 +59,17 @@
     private static final boolean ENCODING_PROTO = true;
     private static final boolean ENCODING_ASCII = false;
 
-    public GeolocationHeaderTest() {
-        super(ChromeActivity.class);
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags
             .Add({GOOGLE_BASE_URL_SWITCH, DISABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testConsistentHeader() throws ProcessInitException {
+    public void testConsistentHeader() {
         long now = setMockLocationNow();
 
         // X-Geo should be sent for Google search results page URLs.
@@ -74,11 +92,12 @@
         assertNullHeader("http://www.google.com/webhp?#q=dinosaurs", false);
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags
             .Add({GOOGLE_BASE_URL_SWITCH, DISABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testPermissionAndSetting() throws ProcessInitException {
+    public void testPermissionAndSetting() {
         long now = setMockLocationNow();
 
         // X-Geo shouldn't be sent when location is disallowed for the origin, or when the DSE
@@ -89,30 +108,33 @@
         checkHeaderWithPermissionAndSetting(ContentSetting.BLOCK, false, now, true);
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags.Add({DISABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testAsciiEncoding() throws ProcessInitException {
+    public void testAsciiEncoding() {
         long now = setMockLocationNow();
 
         // X-Geo should be sent for Google search results page URLs using ascii encoding.
         assertNonNullHeader(SEARCH_URL_1, false, now, ENCODING_ASCII);
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags.Add({ENABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testProtoEncoding() throws ProcessInitException {
+    public void testProtoEncoding() {
         long now = setMockLocationNow();
 
         // X-Geo should be sent for Google search results page URLs using proto encoding.
         assertNonNullHeader(SEARCH_URL_1, false, now, ENCODING_PROTO);
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags.Add({DISABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testGpsFallbackNotEnabled() throws ProcessInitException {
+    public void testGpsFallbackNotEnabled() {
         // Only GPS location, should not be sent when flag is off.
         long now = System.currentTimeMillis();
         Location gpsLocation = generateMockLocation(LocationManager.GPS_PROVIDER, now);
@@ -121,10 +143,11 @@
         assertNullHeader(SEARCH_URL_1, false);
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags.Add({ENABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testGpsFallbackEnabled() throws ProcessInitException {
+    public void testGpsFallbackEnabled() {
         // Only GPS location, should be sent when flag is on.
         long now = System.currentTimeMillis();
         Location gpsLocation = generateMockLocation(LocationManager.GPS_PROVIDER, now);
@@ -133,10 +156,11 @@
         assertNonNullHeader(SEARCH_URL_1, false, now, ENCODING_PROTO);
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags.Add({ENABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testGpsFallbackYounger() throws ProcessInitException {
+    public void testGpsFallbackYounger() {
         long now = System.currentTimeMillis();
         // GPS location is younger.
         Location gpsLocation = generateMockLocation(LocationManager.GPS_PROVIDER, now + 100);
@@ -148,10 +172,11 @@
         assertNonNullHeader(SEARCH_URL_1, false, now + 100, ENCODING_PROTO);
     }
 
+    @Test
     @SmallTest
     @Feature({"Location"})
     @CommandLineFlags.Add({ENABLE_FEATURES + XGEO_VISIBLE_NETWORKS_FEATURE})
-    public void testGpsFallbackOlder() throws ProcessInitException {
+    public void testGpsFallbackOlder() {
         long now = System.currentTimeMillis();
         // GPS location is older.
         Location gpsLocation = generateMockLocation(LocationManager.GPS_PROVIDER, now - 100);
@@ -173,7 +198,7 @@
                 infoHttps.setContentSetting(httpsPermission);
                 String header = GeolocationHeader.getGeoHeader(
                         "https://www.google.de/search?q=kartoffelsalat",
-                        getActivity().getActivityTab());
+                        mActivityTestRule.getActivity().getActivityTab());
                 assertHeaderState(header, locationTime, shouldBeNull);
             }
         });
@@ -189,7 +214,7 @@
                 infoHttps.setContentSetting(httpsPermission);
                 WebsitePreferenceBridge.setDSEGeolocationSetting(settingValue);
                 String header = GeolocationHeader.getGeoHeader(
-                        SEARCH_URL_1, getActivity().getActivityTab());
+                        SEARCH_URL_1, mActivityTestRule.getActivity().getActivityTab());
                 assertHeaderState(header, locationTime, shouldBeNull);
             }
         });
@@ -201,7 +226,7 @@
             public void run() {
                 setMockLocation(locationTime);
                 String header = GeolocationHeader.getGeoHeader(SEARCH_URL_1,
-                        getActivity().getActivityTab());
+                        mActivityTestRule.getActivity().getActivityTab());
                 assertHeaderState(header, locationTime, shouldBeNull);
             }
         });
@@ -209,7 +234,7 @@
 
     private void assertHeaderState(String header, long locationTime, boolean shouldBeNull) {
         if (shouldBeNull) {
-            assertNull(header);
+            Assert.assertNull(header);
         } else {
             assertHeaderEquals(locationTime, ENCODING_ASCII, header);
         }
@@ -241,22 +266,22 @@
 
     private void assertNullHeader(final String url, final boolean isIncognito) {
         try {
-            final Tab tab = loadUrlInNewTab("about:blank", isIncognito);
+            final Tab tab = mActivityTestRule.loadUrlInNewTab("about:blank", isIncognito);
             ThreadUtils.runOnUiThreadBlocking(new Runnable() {
                 @Override
                 public void run() {
-                    assertNull(GeolocationHeader.getGeoHeader(url, tab));
+                    Assert.assertNull(GeolocationHeader.getGeoHeader(url, tab));
                 }
             });
         } catch (InterruptedException e) {
-            fail(e.getMessage());
+            Assert.fail(e.getMessage());
         }
     }
 
     private void assertNonNullHeader(final String url, final boolean isIncognito,
             final long locationTime, final boolean encodingType) {
         try {
-            final Tab tab = loadUrlInNewTab("about:blank", isIncognito);
+            final Tab tab = mActivityTestRule.loadUrlInNewTab("about:blank", isIncognito);
             ThreadUtils.runOnUiThreadBlocking(new Runnable() {
                 @Override
                 public void run() {
@@ -265,7 +290,7 @@
                 }
             });
         } catch (InterruptedException e) {
-            fail(e.getMessage());
+            Assert.fail(e.getMessage());
         }
     }
 
@@ -299,7 +324,7 @@
                     MessageNano.toByteArray(locationDescriptor), Base64.NO_WRAP | Base64.URL_SAFE);
             expectedHeader = "X-Geo: w " + locationProto;
         } else {
-            assertEquals(ENCODING_ASCII, encodingType);
+            Assert.assertEquals(ENCODING_ASCII, encodingType);
             String locationAscii = String.format(Locale.US,
                     "role:1 producer:12 timestamp:%d latlng{latitude_e7:%d longitude_e7:%d} "
                             + "radius:%d",
@@ -307,11 +332,6 @@
             expectedHeader = "X-Geo: a "
                     + new String(Base64.encode(locationAscii.getBytes(), Base64.NO_WRAP));
         }
-        assertEquals(expectedHeader, header);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        Assert.assertEquals(expectedHeader, header);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java
index c51cd9a..8953560 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java
@@ -6,18 +6,28 @@
 
 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
 
+import android.support.test.filters.LargeTest;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
 import android.widget.Button;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
 import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
 import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.ui.PhotoPickerListener;
@@ -31,12 +41,20 @@
 /**
  * Tests for the PhotoPickerDialog class.
  */
-public class PhotoPickerDialogTest extends ChromeActivityTestCaseBase<ChromeActivity>
-        implements PhotoPickerListener, DecoderServiceHost.ServiceReadyCallback,
-                   SelectionObserver<PickerBitmap> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+public class PhotoPickerDialogTest implements PhotoPickerListener,
+        SelectionObserver<PickerBitmap>, DecoderServiceHost.ServiceReadyCallback {
     // The timeout (in seconds) to wait for the decoder service to be ready.
     private static final long WAIT_TIMEOUT_SECONDS = scaleTimeout(30);
 
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     // The dialog we are testing.
     private PhotoPickerDialog mDialog;
 
@@ -66,16 +84,9 @@
     // A callback that fires when the decoder is ready.
     public final CallbackHelper onDecoderReadyCallback = new CallbackHelper();
 
-    public PhotoPickerDialogTest() {
-        super(ChromeActivity.class);
-    }
-
-    // ChromeActivityTestCaseBase:
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         mTestFiles = new ArrayList<>();
         mTestFiles.add(new PickerBitmap("a", 5L, PickerBitmap.PICTURE));
         mTestFiles.add(new PickerBitmap("b", 4L, PickerBitmap.PICTURE));
@@ -88,11 +99,6 @@
         DecoderServiceHost.setReadyCallback(this);
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
     // PhotoPickerDialog.PhotoPickerListener:
 
     @Override
@@ -128,8 +134,9 @@
                 ThreadUtils.runOnUiThreadBlocking(new Callable<PhotoPickerDialog>() {
                     @Override
                     public PhotoPickerDialog call() {
-                        final PhotoPickerDialog dialog = new PhotoPickerDialog(
-                                getActivity(), PhotoPickerDialogTest.this, multiselect, mimeTypes);
+                        final PhotoPickerDialog dialog =
+                                new PhotoPickerDialog(mActivityTestRule.getActivity(),
+                                        PhotoPickerDialogTest.this, multiselect, mimeTypes);
                         dialog.show();
                         return dialog;
                     }
@@ -159,8 +166,8 @@
         onSelectionCallback.waitForCallback(callCount, 1);
 
         // Validate the correct selection took place.
-        assertEquals(expectedSelectionCount, mCurrentPhotoSelection.size());
-        assertTrue(mSelectionDelegate.isItemSelected(mTestFiles.get(position)));
+        Assert.assertEquals(expectedSelectionCount, mCurrentPhotoSelection.size());
+        Assert.assertTrue(mSelectionDelegate.isItemSelected(mTestFiles.get(position)));
     }
 
     private void clickDone() throws Exception {
@@ -171,18 +178,18 @@
         int callCount = onActionCallback.getCallCount();
         TouchCommon.singleClickView(done);
         onActionCallback.waitForCallback(callCount, 1);
-        assertEquals(PhotoPickerListener.Action.PHOTOS_SELECTED, mLastActionRecorded);
+        Assert.assertEquals(PhotoPickerListener.Action.PHOTOS_SELECTED, mLastActionRecorded);
     }
 
     public void clickCancel() throws Exception {
         mLastActionRecorded = null;
 
         PickerCategoryView categoryView = mDialog.getCategoryViewForTesting();
-        View cancel = new View(getActivity());
+        View cancel = new View(mActivityTestRule.getActivity());
         int callCount = onActionCallback.getCallCount();
         categoryView.onClick(cancel);
         onActionCallback.waitForCallback(callCount, 1);
-        assertEquals(PhotoPickerListener.Action.CANCEL, mLastActionRecorded);
+        Assert.assertEquals(PhotoPickerListener.Action.CANCEL, mLastActionRecorded);
     }
 
     private void dismissDialog() {
@@ -197,22 +204,21 @@
     /**
      * Continues to be flaky on bots which doesn't reproduce on local devices,
      * continuing to investigate offline.
-     *
-     * https://crbug.com/761060
-     * @LargeTest
      */
-    @DisabledTest
+    @Test
+    @DisabledTest(message = "crbug.com/761060")
+    @LargeTest
     public void testNoSelection() throws Throwable {
         createDialog(false, Arrays.asList("image/*")); // Multi-select = false.
-        assertTrue(mDialog.isShowing());
+        Assert.assertTrue(mDialog.isShowing());
         waitForDecoder();
 
         int expectedSelectionCount = 1;
         clickView(0, expectedSelectionCount);
         clickCancel();
 
-        assertEquals(null, mLastSelectedPhotos);
-        assertEquals(PhotoPickerListener.Action.CANCEL, mLastActionRecorded);
+        Assert.assertNull(mLastSelectedPhotos);
+        Assert.assertEquals(PhotoPickerListener.Action.CANCEL, mLastActionRecorded);
 
         dismissDialog();
     }
@@ -220,14 +226,13 @@
     /**
      * Continues to be flaky on bots which doesn't reproduce on local devices,
      * continuing to investigate offline.
-     *
-     * https://crbug.com/761060
-     * @LargeTest
      */
-    @DisabledTest
+    @Test
+    @DisabledTest(message = "crbug.com/761060")
+    @LargeTest
     public void testSingleSelectionPhoto() throws Throwable {
         createDialog(false, Arrays.asList("image/*")); // Multi-select = false.
-        assertTrue(mDialog.isShowing());
+        Assert.assertTrue(mDialog.isShowing());
         waitForDecoder();
 
         // Expected selection count is 1 because clicking on a new view unselects other.
@@ -236,9 +241,9 @@
         clickView(1, expectedSelectionCount);
         clickDone();
 
-        assertEquals(1, mLastSelectedPhotos.length);
-        assertEquals(PhotoPickerListener.Action.PHOTOS_SELECTED, mLastActionRecorded);
-        assertEquals(mTestFiles.get(1).getFilePath(), mLastSelectedPhotos[0]);
+        Assert.assertEquals(1, mLastSelectedPhotos.length);
+        Assert.assertEquals(PhotoPickerListener.Action.PHOTOS_SELECTED, mLastActionRecorded);
+        Assert.assertEquals(mTestFiles.get(1).getFilePath(), mLastSelectedPhotos[0]);
 
         dismissDialog();
     }
@@ -246,14 +251,13 @@
     /**
      * Continues to be flaky on bots which doesn't reproduce on local devices,
      * continuing to investigate offline.
-     *
-     * https://crbug.com/761060
-     * @LargeTest
      */
-    @DisabledTest
+    @Test
+    @DisabledTest(message = "crbug.com/761060")
+    @LargeTest
     public void testMultiSelectionPhoto() throws Throwable {
         createDialog(true, Arrays.asList("image/*")); // Multi-select = true.
-        assertTrue(mDialog.isShowing());
+        Assert.assertTrue(mDialog.isShowing());
         waitForDecoder();
 
         // Multi-selection is enabled, so each click is counted.
@@ -263,11 +267,11 @@
         clickView(4, expectedSelectionCount++);
         clickDone();
 
-        assertEquals(3, mLastSelectedPhotos.length);
-        assertEquals(PhotoPickerListener.Action.PHOTOS_SELECTED, mLastActionRecorded);
-        assertEquals(mTestFiles.get(0).getFilePath(), mLastSelectedPhotos[0]);
-        assertEquals(mTestFiles.get(2).getFilePath(), mLastSelectedPhotos[1]);
-        assertEquals(mTestFiles.get(4).getFilePath(), mLastSelectedPhotos[2]);
+        Assert.assertEquals(3, mLastSelectedPhotos.length);
+        Assert.assertEquals(PhotoPickerListener.Action.PHOTOS_SELECTED, mLastActionRecorded);
+        Assert.assertEquals(mTestFiles.get(0).getFilePath(), mLastSelectedPhotos[0]);
+        Assert.assertEquals(mTestFiles.get(2).getFilePath(), mLastSelectedPhotos[1]);
+        Assert.assertEquals(mTestFiles.get(4).getFilePath(), mLastSelectedPhotos[2]);
 
         dismissDialog();
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
index 37f66a6..d77f99c3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
@@ -8,6 +8,7 @@
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
@@ -15,6 +16,13 @@
 import android.text.SpannableString;
 import android.widget.ListView;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
@@ -22,6 +30,7 @@
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataTab;
 import org.chromium.chrome.browser.preferences.ButtonPreference;
@@ -31,7 +40,8 @@
 import org.chromium.chrome.browser.webapps.TestFetchStorageCallback;
 import org.chromium.chrome.browser.webapps.WebappDataStorage;
 import org.chromium.chrome.browser.webapps.WebappRegistry;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -45,36 +55,35 @@
 /**
  * Integration tests for ClearBrowsingDataPreferences.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
 @RetryOnFailure
-public class ClearBrowsingDataPreferencesTest
-        extends ChromeActivityTestCaseBase<ChromeActivity> {
+public class ClearBrowsingDataPreferencesTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private EmbeddedTestServer mTestServer;
 
-    @Override
-    protected void setUp() throws Exception {
-        SigninTestUtil.setUpAuthForTest(getInstrumentation());
+    @Before
+    public void setUp() throws Exception {
+        SigninTestUtil.setUpAuthForTest(InstrumentationRegistry.getInstrumentation());
 
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
 
         SigninTestUtil.tearDownAuthForTest();
     }
 
-    public ClearBrowsingDataPreferencesTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
     /**  Waits for the progress dialog to disappear from the given CBD preference. */
     private void waitForProgressToComplete(final ClearBrowsingDataPreferences preferences)
             throws Exception {
@@ -89,18 +98,19 @@
     /**
      * Tests that web apps are cleared when the "cookies and site data" option is selected.
      */
+    @Test
     @MediumTest
     public void testClearingSiteDataClearsWebapps() throws Exception {
         TestFetchStorageCallback callback = new TestFetchStorageCallback();
         WebappRegistry.getInstance().register("first", callback);
         callback.waitForCallback(0);
-        assertEquals(new HashSet<String>(Arrays.asList("first")),
+        Assert.assertEquals(new HashSet<String>(Arrays.asList("first")),
                 WebappRegistry.getRegisteredWebappIdsForTesting());
 
         setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_COOKIES_AND_SITE_DATA));
         final ClearBrowsingDataPreferences preferences =
-                (ClearBrowsingDataPreferences) startPreferences(
-                        ClearBrowsingDataPreferences.class.getName())
+                (ClearBrowsingDataPreferences) mActivityTestRule
+                        .startPreferences(ClearBrowsingDataPreferences.class.getName())
                         .getFragmentForTest();
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -114,13 +124,14 @@
         });
         waitForProgressToComplete(preferences);
 
-        assertTrue(WebappRegistry.getRegisteredWebappIdsForTesting().isEmpty());
+        Assert.assertTrue(WebappRegistry.getRegisteredWebappIdsForTesting().isEmpty());
     }
 
     /**
      * Tests that web app scopes and last launch times are cleared when the "history" option is
      * selected. However, the web app is not removed from the registry.
      */
+    @Test
     @MediumTest
     public void testClearingHistoryClearsWebappScopesAndLaunchTimes() throws Exception {
         Intent shortcutIntent = ShortcutHelper.createWebappShortcutIntentForTesting("id", "url");
@@ -129,13 +140,13 @@
         callback.waitForCallback(0);
         callback.getStorage().updateFromShortcutIntent(shortcutIntent);
 
-        assertEquals(new HashSet<String>(Arrays.asList("first")),
+        Assert.assertEquals(new HashSet<String>(Arrays.asList("first")),
                 WebappRegistry.getRegisteredWebappIdsForTesting());
 
         setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_HISTORY));
         final ClearBrowsingDataPreferences preferences =
-                (ClearBrowsingDataPreferences) startPreferences(
-                        ClearBrowsingDataPreferences.class.getName())
+                (ClearBrowsingDataPreferences) mActivityTestRule
+                        .startPreferences(ClearBrowsingDataPreferences.class.getName())
                         .getFragmentForTest();
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -149,27 +160,28 @@
         });
         waitForProgressToComplete(preferences);
 
-        assertEquals(new HashSet<String>(Arrays.asList("first")),
+        Assert.assertEquals(new HashSet<String>(Arrays.asList("first")),
                 WebappRegistry.getRegisteredWebappIdsForTesting());
 
         // URL and scope should be empty, and last used time should be 0.
         WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage("first");
-        assertEquals("", storage.getScope());
-        assertEquals("", storage.getUrl());
-        assertEquals(0, storage.getLastUsedTime());
+        Assert.assertEquals("", storage.getScope());
+        Assert.assertEquals("", storage.getUrl());
+        Assert.assertEquals(0, storage.getLastUsedTime());
     }
 
     /**
      * Tests that a fragment with all options preselected indeed has all checkboxes checked
      * on startup, and that deletion with all checkboxes checked completes successfully.
      */
+    @Test
     @MediumTest
     public void testClearingEverything() throws Exception {
         setDataTypesToClear(Arrays.asList(DialogOption.values()));
 
         final ClearBrowsingDataPreferences preferences =
-                (ClearBrowsingDataPreferences) startPreferences(
-                        ClearBrowsingDataPreferences.class.getName())
+                (ClearBrowsingDataPreferences) mActivityTestRule
+                        .startPreferences(ClearBrowsingDataPreferences.class.getName())
                         .getFragmentForTest();
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -183,12 +195,12 @@
                         continue;
                     }
                     CheckBoxPreference checkbox = (CheckBoxPreference) pref;
-                    assertTrue(checkbox.isChecked());
+                    Assert.assertTrue(checkbox.isChecked());
                 }
 
                 ButtonPreference clearButton = (ButtonPreference) screen.findPreference(
                         ClearBrowsingDataPreferences.PREF_CLEAR_BUTTON);
-                assertTrue(clearButton.isEnabled());
+                Assert.assertTrue(clearButton.isEnabled());
                 clearButton.getOnPreferenceClickListener().onPreferenceClick(clearButton);
             }
         });
@@ -199,12 +211,13 @@
     /**
      * Tests that for users who are not signed in, only the general footnote is shown.
      */
+    @Test
     @SmallTest
     public void testFooterNonsigned() throws Exception {
         SigninTestUtil.resetSigninState();
 
         final Preferences preferences =
-                startPreferences(ClearBrowsingDataPreferences.class.getName());
+                mActivityTestRule.startPreferences(ClearBrowsingDataPreferences.class.getName());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -213,9 +226,9 @@
                         (ClearBrowsingDataPreferences) preferences.getFragmentForTest();
                 PreferenceScreen screen = fragment.getPreferenceScreen();
 
-                assertNotNull(
+                Assert.assertNotNull(
                         screen.findPreference(ClearBrowsingDataPreferences.PREF_GENERAL_SUMMARY));
-                assertNull(
+                Assert.assertNull(
                         screen.findPreference(ClearBrowsingDataPreferences.PREF_GOOGLE_SUMMARY));
             }
         });
@@ -225,13 +238,14 @@
      * Tests that for users who are signed in, both the general and the Google-specific footnotes
      * are shown.
      */
+    @Test
     @MediumTest
     public void testFooterSigned() throws Exception {
         // Sign in.
         SigninTestUtil.addAndSignInTestAccount();
 
         final Preferences preferences =
-                startPreferences(ClearBrowsingDataPreferences.class.getName());
+                mActivityTestRule.startPreferences(ClearBrowsingDataPreferences.class.getName());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -240,24 +254,30 @@
                         (ClearBrowsingDataPreferences) preferences.getFragmentForTest();
                 PreferenceScreen screen = fragment.getPreferenceScreen();
 
-                assertNotNull(
+                Assert.assertNotNull(
                         screen.findPreference(ClearBrowsingDataPreferences.PREF_GENERAL_SUMMARY));
 
                 Preference google_summary =
                         screen.findPreference(ClearBrowsingDataPreferences.PREF_GOOGLE_SUMMARY);
-                assertNotNull(google_summary);
+                Assert.assertNotNull(google_summary);
 
                 // There is currently no clickable link in the Google-specific summary.
-                assertTrue(!(google_summary.getSummary() instanceof SpannableString)
-                        || ((SpannableString) google_summary.getSummary()).getSpans(
-                                0, google_summary.getSummary().length(), Object.class).length == 0);
+                Assert.assertTrue(!(google_summary.getSummary() instanceof SpannableString)
+                        || ((SpannableString) google_summary.getSummary())
+                                        .getSpans(0, google_summary.getSummary().length(),
+                                                Object.class)
+                                        .length
+                                == 0);
 
                 // When the web history service reports that there are other forms of browsing
                 // history, we should show a link to them.
                 fragment.showNoticeAboutOtherFormsOfBrowsingHistory();
-                assertTrue(google_summary.getSummary() instanceof SpannableString);
-                assertTrue(((SpannableString) google_summary.getSummary()).getSpans(
-                        0, google_summary.getSummary().length(), Object.class).length == 1);
+                Assert.assertTrue(google_summary.getSummary() instanceof SpannableString);
+                Assert.assertTrue(
+                        ((SpannableString) google_summary.getSummary())
+                                .getSpans(0, google_summary.getSummary().length(), Object.class)
+                                .length
+                        == 1);
             }
         });
     }
@@ -288,7 +308,7 @@
             fragment.enableDialogAboutOtherFormsOfBrowsingHistory();
             ButtonPreference clearButton = (ButtonPreference) screen.findPreference(
                     ClearBrowsingDataPreferences.PREF_CLEAR_BUTTON);
-            assertTrue(clearButton.isEnabled());
+            Assert.assertTrue(clearButton.isEnabled());
             clearButton.getOnPreferenceClickListener().onPreferenceClick(clearButton);
         }
     }
@@ -322,17 +342,19 @@
      * after the deletion completes, if and only if browsing history was checked for deletion
      * and it has not been shown before.
      */
+    @Test
     @LargeTest
     public void testDialogAboutOtherFormsOfBrowsingHistory() throws Exception {
         // Sign in.
         SigninTestUtil.addAndSignInTestAccount();
-        OtherFormsOfHistoryDialogFragment.clearShownPreferenceForTesting(getActivity());
+        OtherFormsOfHistoryDialogFragment.clearShownPreferenceForTesting(
+                mActivityTestRule.getActivity());
 
         // History is not selected. We still need to select some other datatype, otherwise the
         // "Clear" button won't be enabled.
         setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_CACHE));
         final Preferences preferences1 =
-                startPreferences(ClearBrowsingDataPreferences.class.getName());
+                mActivityTestRule.startPreferences(ClearBrowsingDataPreferences.class.getName());
         ThreadUtils.runOnUiThreadBlocking(
                 new OpenPreferencesEnableDialogAndClickClearRunnable(preferences1));
 
@@ -343,7 +365,7 @@
         // Reopen Clear Browsing Data preferences, this time with history selected for clearing.
         setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_HISTORY));
         final Preferences preferences2 =
-                startPreferences(ClearBrowsingDataPreferences.class.getName());
+                mActivityTestRule.startPreferences(ClearBrowsingDataPreferences.class.getName());
         ThreadUtils.runOnUiThreadBlocking(
                 new OpenPreferencesEnableDialogAndClickClearRunnable(preferences2));
 
@@ -376,7 +398,7 @@
         // Reopen Clear Browsing Data preferences and clear history once again.
         setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_HISTORY));
         final Preferences preferences3 =
-                startPreferences(ClearBrowsingDataPreferences.class.getName());
+                mActivityTestRule.startPreferences(ClearBrowsingDataPreferences.class.getName());
         ThreadUtils.runOnUiThreadBlocking(
                 new OpenPreferencesEnableDialogAndClickClearRunnable(preferences3));
 
@@ -394,7 +416,7 @@
                 PreferenceScreen screen = preferences.getPreferenceScreen();
                 ButtonPreference clearButton = (ButtonPreference) screen.findPreference(
                         ClearBrowsingDataPreferences.PREF_CLEAR_BUTTON);
-                assertTrue(clearButton.isEnabled());
+                Assert.assertTrue(clearButton.isEnabled());
                 clearButton.getOnPreferenceClickListener().onPreferenceClick(clearButton);
             }
         };
@@ -406,7 +428,7 @@
         return new Runnable() {
             @Override
             public void run() {
-                assertNotNull(preferences);
+                Assert.assertNotNull(preferences);
                 ConfirmImportantSitesDialogFragment dialog =
                         preferences.getImportantSitesDialogFragment();
                 ((AlertDialog) dialog.getDialog()).getButton(whichButton).performClick();
@@ -423,7 +445,7 @@
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                assertNotNull(preferences);
+                Assert.assertNotNull(preferences);
                 if (preferences.getImportantSitesDialogFragment() == null
                         || !preferences.getImportantSitesDialogFragment().getDialog().isShowing()) {
                     return false;
@@ -450,13 +472,14 @@
      * Tests that the important sites dialog is shown, and if we don't deselect anything we
      * correctly clear everything.
      */
+    @Test
     @CommandLineFlags.Add({"enable-features=ImportantSitesInCBD", "enable-site-engagement"})
     @MediumTest
     @Feature({"SiteEngagement"})
     public void testImportantSitesDialogNoFiltering() throws Exception {
         // Sign in.
         SigninTestUtil.addAndSignInTestAccount();
-        assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.IMPORTANT_SITES_IN_CBD));
+        Assert.assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.IMPORTANT_SITES_IN_CBD));
 
         final String testUrl =
                 mTestServer.getURL("/chrome/test/data/android/storage_persistance.html");
@@ -466,18 +489,21 @@
         ThreadUtils.runOnUiThreadBlocking(getMarkOriginsAsImportantRunnable(importantOrigins));
 
         // Load the page and clear any set storage.
-        loadUrl(testUrl + "#clear");
-        assertEquals("false", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
-        runJavaScriptCodeInCurrentTab("setStorage()");
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl(testUrl + "#clear");
+        Assert.assertEquals(
+                "false", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("setStorage()");
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
 
         // Load the page again and ensure the cookie still is set.
-        loadUrl(testUrl);
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl(testUrl);
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
 
         ClearBrowsingDataPreferences preferences =
-                (ClearBrowsingDataPreferences) startPreferences(
-                        ClearBrowsingDataPreferences.class.getName())
+                (ClearBrowsingDataPreferences) mActivityTestRule
+                        .startPreferences(ClearBrowsingDataPreferences.class.getName())
                         .getFragmentForTest();
 
         // Clear in root preference.
@@ -490,8 +516,9 @@
         waitForProgressToComplete(preferences);
 
         // Verify we don't have storage.
-        loadUrl(testUrl);
-        assertEquals("false", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl(testUrl);
+        Assert.assertEquals(
+                "false", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
     }
 
     /**
@@ -499,6 +526,7 @@
      *
      * http://crbug.com/727310
      */
+    @Test
     @CommandLineFlags.Add({"enable-features=ImportantSitesInCBD", "enable-site-engagement"})
     @MediumTest
     @Feature({"SiteEngagement"})
@@ -506,7 +534,7 @@
     public void testImportantSitesDialogNoopOnCancel() throws Exception {
         // Sign in.
         SigninTestUtil.addAndSignInTestAccount();
-        assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.IMPORTANT_SITES_IN_CBD));
+        Assert.assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.IMPORTANT_SITES_IN_CBD));
 
         final String testUrl =
                 mTestServer.getURL("/chrome/test/data/android/storage_persistance.html");
@@ -516,12 +544,15 @@
         ThreadUtils.runOnUiThreadBlocking(getMarkOriginsAsImportantRunnable(importantOrigins));
 
         // Load the page and clear any set storage.
-        loadUrl(testUrl + "#clear");
-        assertEquals("false", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
-        runJavaScriptCodeInCurrentTab("setStorage()");
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl(testUrl + "#clear");
+        Assert.assertEquals(
+                "false", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("setStorage()");
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
 
-        Preferences preferences = startPreferences(ClearBrowsingDataPreferences.class.getName());
+        Preferences preferences =
+                mActivityTestRule.startPreferences(ClearBrowsingDataPreferences.class.getName());
         ClearBrowsingDataPreferences fragment =
                 (ClearBrowsingDataPreferences) preferences.getFragmentForTest();
         ThreadUtils.runOnUiThreadBlocking(getPressClearRunnable(fragment));
@@ -531,21 +562,23 @@
         ThreadUtils.runOnUiThreadBlocking(
                 getPressButtonInImportantDialogRunnable(fragment, AlertDialog.BUTTON_NEGATIVE));
         preferences.finish();
-        loadUrl(testUrl);
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl(testUrl);
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
     }
 
     /**
      * Tests that the important sites dialog is shown, we can successfully uncheck options, and
      * clicking clear doesn't clear the protected domain.
      */
+    @Test
     @CommandLineFlags.Add({"enable-features=ImportantSitesInCBD", "enable-site-engagement"})
     @MediumTest
     @Feature({"SiteEngagement"})
     public void testImportantSitesDialog() throws Exception {
         // Sign in.
         SigninTestUtil.addAndSignInTestAccount();
-        assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.IMPORTANT_SITES_IN_CBD));
+        Assert.assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.IMPORTANT_SITES_IN_CBD));
 
         final String testUrl =
                 mTestServer.getURL("/chrome/test/data/android/storage_persistance.html");
@@ -557,13 +590,15 @@
         ThreadUtils.runOnUiThreadBlocking(getMarkOriginsAsImportantRunnable(importantOrigins));
 
         // Load the page and clear any set storage.
-        loadUrl(testUrl + "#clear");
-        assertEquals("false", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
-        runJavaScriptCodeInCurrentTab("setStorage()");
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl(testUrl + "#clear");
+        Assert.assertEquals(
+                "false", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("setStorage()");
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
 
         final Preferences preferences =
-                startPreferences(ClearBrowsingDataPreferences.class.getName());
+                mActivityTestRule.startPreferences(ClearBrowsingDataPreferences.class.getName());
         final ClearBrowsingDataPreferences fragment =
                 (ClearBrowsingDataPreferences) preferences.getFragmentForTest();
 
@@ -595,7 +630,8 @@
 
         waitForProgressToComplete(fragment);
         // And check we didn't clear our cookies.
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
     }
 
     private void setDataTypesToClear(final List<DialogOption> typesToClear) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContentSuggestionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContentSuggestionsTest.java
index 7337a1f..b8846e413 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContentSuggestionsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContentSuggestionsTest.java
@@ -6,10 +6,17 @@
 
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.ntp.NewTabPage;
 import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
@@ -18,43 +25,53 @@
 import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.NewTabPageTestUtils;
 
 /**
  * Misc. Content Suggestions instrumentation tests.
  */
-public class ContentSuggestionsTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-    public ContentSuggestionsTest() {
-        super(ChromeActivity.class);
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+public class ContentSuggestionsTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @SmallTest
     @Feature("Suggestions")
     @CommandLineFlags.Add("enable-features=ContentSuggestionsSettings")
     public void testRemoteSuggestionsEnabled() throws InterruptedException {
         NewTabPage ntp = loadNTPWithSearchSuggestState(true);
         SuggestionsUiDelegate uiDelegate = ntp.getManagerForTesting();
-        assertTrue(isCategoryEnabled(uiDelegate.getSuggestionsSource(), KnownCategories.ARTICLES));
+        Assert.assertTrue(
+                isCategoryEnabled(uiDelegate.getSuggestionsSource(), KnownCategories.ARTICLES));
     }
 
+    @Test
     @SmallTest
     @Feature("Suggestions")
     @CommandLineFlags.Add("enable-features=ContentSuggestionsSettings")
     public void testRemoteSuggestionsDisabled() throws InterruptedException {
         NewTabPage ntp = loadNTPWithSearchSuggestState(false);
         SuggestionsUiDelegate uiDelegate = ntp.getManagerForTesting();
-        assertFalse(isCategoryEnabled(uiDelegate.getSuggestionsSource(), KnownCategories.ARTICLES));
+        Assert.assertFalse(
+                isCategoryEnabled(uiDelegate.getSuggestionsSource(), KnownCategories.ARTICLES));
     }
 
     private NewTabPage loadNTPWithSearchSuggestState(final boolean enabled)
             throws InterruptedException {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -62,10 +79,10 @@
             }
         });
 
-        loadUrl(UrlConstants.NTP_URL);
+        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
         NewTabPageTestUtils.waitForNtpLoaded(tab);
 
-        assertTrue(tab.getNativePage() instanceof NewTabPage);
+        Assert.assertTrue(tab.getNativePage() instanceof NewTabPage);
         return (NewTabPage) tab.getNativePage();
     }
 
diff --git a/chrome/android/sync_shell/javatests/AndroidManifest.xml b/chrome/android/sync_shell/javatests/AndroidManifest.xml
index 8aff831..e83a3f0 100644
--- a/chrome/android/sync_shell/javatests/AndroidManifest.xml
+++ b/chrome/android/sync_shell/javatests/AndroidManifest.xml
@@ -17,6 +17,10 @@
         android:label="ChromeSyncShellTest">
         <uses-library android:name="android.test.runner" />
     </application>
+    <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
+        android:targetPackage="{{manifest_package}}"
+        android:label="Tests for {{manifest_package}}"
+        chromium-junit4="true"/>
     <instrumentation android:name="org.chromium.chrome.test.ChromeInstrumentationTestRunner"
         android:targetPackage="{{manifest_package}}"
         android:label="Tests for {{manifest_package}}"/>
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java
index efab49fb..1fe3e8ea 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java
@@ -9,9 +9,19 @@
 
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.sync.SyncTestRule.DataCriteria;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.components.sync.ModelType;
 import org.chromium.components.sync.protocol.AutofillProfileSpecifics;
@@ -26,8 +36,16 @@
 /**
  * Test suite for the autofill profile sync data type.
  */
-@RetryOnFailure  // crbug.com/637448
-public class AutofillTest extends SyncTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+@RetryOnFailure // crbug.com/637448
+public class AutofillTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String TAG = "AutofillTest";
 
     private static final String AUTOFILL_TYPE = "Autofill Profiles";
@@ -65,16 +83,16 @@
         }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        setUpTestAccountAndSignIn();
+    @Before
+    public void setUp() throws Exception {
+        mSyncTestRule.setUpTestAccountAndSignIn();
         // Make sure the initial state is clean.
         assertClientAutofillProfileCount(0);
         assertServerAutofillProfileCountWithName(0, STREET);
     }
 
     // Test syncing an autofill profile from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadAutofill() throws Exception {
@@ -84,16 +102,17 @@
 
         // Verify data synced to client.
         List<Autofill> autofills = getClientAutofillProfiles();
-        assertEquals("Only the injected autofill should exist on the client.",
-                1, autofills.size());
+        Assert.assertEquals(
+                "Only the injected autofill should exist on the client.", 1, autofills.size());
         Autofill autofill = autofills.get(0);
-        assertEquals("The wrong street was found for the address.", STREET, autofill.street);
-        assertEquals("The wrong city was found for the autofill.", CITY, autofill.city);
-        assertEquals("The wrong state was found for the autofill.", STATE, autofill.state);
-        assertEquals("The wrong zip was found for the autofill.", ZIP, autofill.zip);
+        Assert.assertEquals("The wrong street was found for the address.", STREET, autofill.street);
+        Assert.assertEquals("The wrong city was found for the autofill.", CITY, autofill.city);
+        Assert.assertEquals("The wrong state was found for the autofill.", STATE, autofill.state);
+        Assert.assertEquals("The wrong zip was found for the autofill.", ZIP, autofill.zip);
     }
 
     // Test syncing an autofill profile modification from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadAutofillModification() throws Exception {
@@ -105,9 +124,9 @@
         // Modify on server, sync, and verify modification locally.
         Autofill autofill = getClientAutofillProfiles().get(0);
         specifics.autofillProfile.addressHomeCity = MODIFIED_CITY;
-        mFakeServerHelper.modifyEntitySpecifics(autofill.id, specifics);
+        mSyncTestRule.getFakeServerHelper().modifyEntitySpecifics(autofill.id, specifics);
         SyncTestUtil.triggerSync();
-        pollInstrumentationThread(new ClientAutofillCriteria() {
+        mSyncTestRule.pollInstrumentationThread(new ClientAutofillCriteria() {
             @Override
             public boolean isSatisfied(List<Autofill> autofills) {
                 Autofill modifiedAutofill = autofills.get(0);
@@ -117,6 +136,7 @@
     }
 
     // Test syncing an autofill profile deletion from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadDeletedAutofill() throws Exception {
@@ -127,17 +147,18 @@
 
         // Delete on server, sync, and verify deleted locally.
         Autofill autofill = getClientAutofillProfiles().get(0);
-        mFakeServerHelper.deleteEntity(autofill.id);
+        mSyncTestRule.getFakeServerHelper().deleteEntity(autofill.id);
         SyncTestUtil.triggerSync();
         waitForClientAutofillProfileCount(0);
     }
 
     // Test that autofill profiles don't get synced if the data type is disabled.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDisabledNoDownloadAutofill() throws Exception {
         // The AUTOFILL type here controls both AUTOFILL and AUTOFILL_PROFILE.
-        disableDataType(ModelType.AUTOFILL);
+        mSyncTestRule.disableDataType(ModelType.AUTOFILL);
         addServerAutofillProfile(STREET, CITY, STATE, ZIP);
         SyncTestUtil.triggerSyncAndWaitForCompletion();
         assertClientAutofillProfileCount(0);
@@ -154,13 +175,13 @@
         profile.addressHomeState = state;
         profile.addressHomeZip = zip;
         specifics.autofillProfile = profile;
-        mFakeServerHelper.injectUniqueClientEntity(street /* name */, specifics);
+        mSyncTestRule.getFakeServerHelper().injectUniqueClientEntity(street /* name */, specifics);
         return specifics;
     }
 
     private List<Autofill> getClientAutofillProfiles() throws JSONException {
-        List<Pair<String, JSONObject>> entities = SyncTestUtil.getLocalData(
-                mContext, AUTOFILL_TYPE);
+        List<Pair<String, JSONObject>> entities =
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), AUTOFILL_TYPE);
         List<Autofill> autofills = new ArrayList<Autofill>(entities.size());
         for (Pair<String, JSONObject> entity : entities) {
             String id = entity.first;
@@ -175,13 +196,13 @@
     }
 
     private void assertClientAutofillProfileCount(int count) throws JSONException {
-        assertEquals("There should be " + count + " local autofill profiles.",
-                count, SyncTestUtil.getLocalData(mContext, AUTOFILL_TYPE).size());
+        Assert.assertEquals("There should be " + count + " local autofill profiles.", count,
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), AUTOFILL_TYPE).size());
     }
 
     private void assertServerAutofillProfileCountWithName(int count, String name) {
-        assertTrue("Expected " + count + " server autofill profiles with name " + name + ".",
-                mFakeServerHelper.verifyEntityCountByTypeAndName(
+        Assert.assertTrue("Expected " + count + " server autofill profiles with name " + name + ".",
+                mSyncTestRule.getFakeServerHelper().verifyEntityCountByTypeAndName(
                         count, ModelType.AUTOFILL_PROFILE, name));
     }
 
@@ -189,7 +210,8 @@
         CriteriaHelper.pollInstrumentationThread(Criteria.equals(count, new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return SyncTestUtil.getLocalData(mContext, AUTOFILL_TYPE).size();
+                return SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), AUTOFILL_TYPE)
+                        .size();
             }
         }), SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
     }
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java
index b558604..5187982e 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java
@@ -9,12 +9,22 @@
 
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.sync.SyncTestRule.DataCriteria;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.components.bookmarks.BookmarkId;
 import org.chromium.components.sync.ModelType;
@@ -29,8 +39,16 @@
 /**
  * Test suite for the bookmarks sync data type.
  */
-@RetryOnFailure  // crbug.com/637448
-public class BookmarksTest extends SyncTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+@RetryOnFailure // crbug.com/637448
+public class BookmarksTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String TAG = "BookmarksTest";
 
     private static final String BOOKMARKS_TYPE_STRING = "Bookmarks";
@@ -75,9 +93,8 @@
         }
     }
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -87,7 +104,7 @@
                 mBookmarkBridge.loadEmptyPartnerBookmarkShimForTesting();
             }
         });
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         // Make sure initial state is clean.
         assertClientBookmarkCount(0);
         assertServerBookmarkCountWithName(0, TITLE);
@@ -95,6 +112,7 @@
     }
 
     // Test syncing a new bookmark from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadBookmark() throws Exception {
@@ -103,14 +121,15 @@
         waitForClientBookmarkCount(1);
 
         List<Bookmark> bookmarks = getClientBookmarks();
-        assertEquals("Only the injected bookmark should exist on the client.",
-                1, bookmarks.size());
+        Assert.assertEquals(
+                "Only the injected bookmark should exist on the client.", 1, bookmarks.size());
         Bookmark bookmark = bookmarks.get(0);
-        assertEquals("The wrong title was found for the bookmark.", TITLE, bookmark.title);
-        assertEquals("The wrong URL was found for the bookmark.", URL, bookmark.url);
+        Assert.assertEquals("The wrong title was found for the bookmark.", TITLE, bookmark.title);
+        Assert.assertEquals("The wrong URL was found for the bookmark.", URL, bookmark.url);
     }
 
     // Test syncing a bookmark modification from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadBookmarkModification() throws Exception {
@@ -123,7 +142,7 @@
         Bookmark bookmark = getClientBookmarks().get(0);
         modifyServerBookmark(bookmark.id, MODIFIED_TITLE, URL);
         SyncTestUtil.triggerSync();
-        pollInstrumentationThread(new ClientBookmarksCriteria() {
+        mSyncTestRule.pollInstrumentationThread(new ClientBookmarksCriteria() {
             @Override
             public boolean isSatisfied(List<Bookmark> bookmarks) {
                 Bookmark modifiedBookmark = bookmarks.get(0);
@@ -133,6 +152,7 @@
     }
 
     // Test syncing a bookmark tombstone from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadBookmarkTombstone() throws Exception {
@@ -143,12 +163,13 @@
 
         // Delete on server, sync, and verify deleted locally.
         Bookmark bookmark = getClientBookmarks().get(0);
-        mFakeServerHelper.deleteEntity(bookmark.id);
+        mSyncTestRule.getFakeServerHelper().deleteEntity(bookmark.id);
         SyncTestUtil.triggerSync();
         waitForClientBookmarkCount(0);
     }
 
     // Test syncing a bookmark modification from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadMovedBookmark() throws Exception {
@@ -169,19 +190,20 @@
         // See http://crbug/642128 - Explicitly set order on bookmark creation
         // and verify the order here.
         List<Bookmark> clientBookmarks = getClientBookmarks();
-        assertEquals(2, clientBookmarks.size());
+        Assert.assertEquals(2, clientBookmarks.size());
         Bookmark item0 = clientBookmarks.get(0);
         Bookmark item1 = clientBookmarks.get(1);
-        assertTrue(item0.isFolder() != item1.isFolder());
+        Assert.assertTrue(item0.isFolder() != item1.isFolder());
         final int bookmarkIndex = item0.isFolder() ? 1 : 0;
         final Bookmark folder = item0.isFolder() ? item0 : item1;
         final Bookmark bookmark = item0.isFolder() ? item1 : item0;
 
         // On the server, move the bookmark into the folder then sync, and
         // verify the move locally.
-        mFakeServerHelper.modifyBookmarkEntity(bookmark.id, TITLE, URL, folder.id);
+        mSyncTestRule.getFakeServerHelper().modifyBookmarkEntity(
+                bookmark.id, TITLE, URL, folder.id);
         SyncTestUtil.triggerSync();
-        pollInstrumentationThread(new ClientBookmarksCriteria() {
+        mSyncTestRule.pollInstrumentationThread(new ClientBookmarksCriteria() {
             @Override
             public boolean isSatisfied(List<Bookmark> bookmarks) {
                 // The "s" is prepended because the server adds one to the parentId.
@@ -191,6 +213,7 @@
     }
 
     // Test syncing a new bookmark folder from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadBookmarkFolder() throws Exception {
@@ -199,14 +222,15 @@
         waitForClientBookmarkCount(1);
 
         List<Bookmark> bookmarks = getClientBookmarks();
-        assertEquals("Only the injected bookmark folder should exist on the client.", 1,
+        Assert.assertEquals("Only the injected bookmark folder should exist on the client.", 1,
                 bookmarks.size());
         Bookmark folder = bookmarks.get(0);
-        assertEquals("The wrong title was found for the folder.", TITLE, folder.title);
-        assertEquals("Bookmark folders do not have a URL.", null, folder.url);
+        Assert.assertEquals("The wrong title was found for the folder.", TITLE, folder.title);
+        Assert.assertEquals("Bookmark folders do not have a URL.", null, folder.url);
     }
 
     // Test syncing a bookmark folder modification from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadBookmarkFolderModification() throws Exception {
@@ -217,11 +241,11 @@
 
         // Modify on server, sync, and verify the modification locally.
         Bookmark folder = getClientBookmarks().get(0);
-        assertTrue(folder.isFolder());
+        Assert.assertTrue(folder.isFolder());
         modifyServerBookmarkFolder(folder.id, MODIFIED_TITLE);
         SyncTestUtil.triggerSync();
 
-        pollInstrumentationThread(new ClientBookmarksCriteria() {
+        mSyncTestRule.pollInstrumentationThread(new ClientBookmarksCriteria() {
             @Override
             public boolean isSatisfied(List<Bookmark> bookmarks) {
                 Bookmark modifiedFolder = bookmarks.get(0);
@@ -231,6 +255,7 @@
     }
 
     // Test syncing a bookmark folder tombstone from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadBookmarkFolderTombstone() throws Exception {
@@ -242,15 +267,16 @@
 
         // Delete on server, sync, and verify deleted locally.
         Bookmark folder = getClientBookmarks().get(0);
-        assertTrue(folder.isFolder());
+        Assert.assertTrue(folder.isFolder());
 
-        mFakeServerHelper.deleteEntity(folder.id);
+        mSyncTestRule.getFakeServerHelper().deleteEntity(folder.id);
         assertServerBookmarkCountWithName(0, TITLE);
         SyncTestUtil.triggerSync();
         waitForClientBookmarkCount(0);
     }
 
     // Test syncing a new bookmark from client to server.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testUploadBookmark() throws Exception {
@@ -260,6 +286,7 @@
     }
 
     // Test syncing a bookmark modification from client to server.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testUploadBookmarkModification() throws Exception {
@@ -274,6 +301,7 @@
     }
 
     // Test syncing a bookmark tombstone from client to server.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testUploadBookmarkTombstone() throws Exception {
@@ -289,6 +317,7 @@
     }
 
     // Test syncing a bookmark modification from client to server.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testUploadMovedBookmark() throws Exception {
@@ -303,13 +332,13 @@
         waitForServerBookmarkCountWithName(1, FOLDER_TITLE);
 
         List<Bookmark> bookmarks = getServerBookmarks();
-        assertEquals("Wrong number of bookmarks.", 2, bookmarks.size());
+        Assert.assertEquals("Wrong number of bookmarks.", 2, bookmarks.size());
         final Bookmark folder = bookmarks.get(bookmarks.get(0).isFolder() ? 0 : 1);
 
         // Move on client, sync, and verify the move on the server.
         moveClientBookmark(bookmarkId, folderId);
         SyncTestUtil.triggerSync();
-        pollInstrumentationThread(new ServerBookmarksCriteria() {
+        mSyncTestRule.pollInstrumentationThread(new ServerBookmarksCriteria() {
             @Override
             public boolean isSatisfied(List<Bookmark> bookmarks) {
                 Bookmark modifiedBookmark = bookmarks.get(bookmarks.get(0).isFolder() ? 1 : 0);
@@ -319,6 +348,7 @@
     }
 
     // Test syncing a new bookmark folder from client to server.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testUploadBookmarkFolder() throws Exception {
@@ -328,6 +358,7 @@
     }
 
     // Test syncing a bookmark folder modification from client to server.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testUploadBookmarkFolderModification() throws Exception {
@@ -342,6 +373,7 @@
     }
 
     // Test syncing a bookmark folder tombstone from client to server.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testUploadBookmarkFolderTombstone() throws Exception {
@@ -356,20 +388,22 @@
     }
 
     // Test that bookmarks don't get downloaded if the data type is disabled.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDisabledNoDownloadBookmark() throws Exception {
-        disableDataType(ModelType.BOOKMARKS);
+        mSyncTestRule.disableDataType(ModelType.BOOKMARKS);
         addServerBookmark(TITLE, URL);
         SyncTestUtil.triggerSyncAndWaitForCompletion();
         assertClientBookmarkCount(0);
     }
 
     // Test that bookmarks don't get uploaded if the data type is disabled.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDisabledNoUploadBookmark() throws Exception {
-        disableDataType(ModelType.BOOKMARKS);
+        mSyncTestRule.disableDataType(ModelType.BOOKMARKS);
         addClientBookmark(TITLE, URL);
         SyncTestUtil.triggerSyncAndWaitForCompletion();
         assertServerBookmarkCountWithName(0, TITLE);
@@ -383,7 +417,7 @@
                 return mBookmarkBridge.addBookmark(parentId, 0, title, url);
             }
         });
-        assertNotNull("Failed to create bookmark.", id);
+        Assert.assertNotNull("Failed to create bookmark.", id);
         return id;
     }
 
@@ -395,28 +429,28 @@
                 return mBookmarkBridge.addFolder(parentId, 0, title);
             }
         });
-        assertNotNull("Failed to create bookmark folder.", id);
+        Assert.assertNotNull("Failed to create bookmark folder.", id);
         return id;
     }
 
     private void addServerBookmark(String title, String url) throws InterruptedException {
-        mFakeServerHelper.injectBookmarkEntity(
-                title, url, mFakeServerHelper.getBookmarkBarFolderId());
+        mSyncTestRule.getFakeServerHelper().injectBookmarkEntity(
+                title, url, mSyncTestRule.getFakeServerHelper().getBookmarkBarFolderId());
     }
 
     private void addServerBookmarkFolder(String title) throws InterruptedException {
-        mFakeServerHelper.injectBookmarkFolderEntity(
-                title, mFakeServerHelper.getBookmarkBarFolderId());
+        mSyncTestRule.getFakeServerHelper().injectBookmarkFolderEntity(
+                title, mSyncTestRule.getFakeServerHelper().getBookmarkBarFolderId());
     }
 
     private void modifyServerBookmark(String bookmarkId, String title, String url) {
-        mFakeServerHelper.modifyBookmarkEntity(
-                bookmarkId, title, url, mFakeServerHelper.getBookmarkBarFolderId());
+        mSyncTestRule.getFakeServerHelper().modifyBookmarkEntity(bookmarkId, title, url,
+                mSyncTestRule.getFakeServerHelper().getBookmarkBarFolderId());
     }
 
     private void modifyServerBookmarkFolder(String folderId, String title) {
-        mFakeServerHelper.modifyBookmarkFolderEntity(
-                folderId, title, mFakeServerHelper.getBookmarkBarFolderId());
+        mSyncTestRule.getFakeServerHelper().modifyBookmarkFolderEntity(
+                folderId, title, mSyncTestRule.getFakeServerHelper().getBookmarkBarFolderId());
     }
 
     private void deleteClientBookmark(final BookmarkId id) {
@@ -447,8 +481,8 @@
     }
 
     private List<Bookmark> getClientBookmarks() throws JSONException {
-        List<Pair<String, JSONObject>> rawBookmarks = SyncTestUtil.getLocalData(
-                mContext, BOOKMARKS_TYPE_STRING);
+        List<Pair<String, JSONObject>> rawBookmarks =
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), BOOKMARKS_TYPE_STRING);
         List<Bookmark> bookmarks = new ArrayList<Bookmark>(rawBookmarks.size());
         for (Pair<String, JSONObject> rawBookmark : rawBookmarks) {
             String id = rawBookmark.first;
@@ -461,7 +495,7 @@
 
     private List<Bookmark> getServerBookmarks() throws Exception {
         List<SyncEntity> entities =
-                mFakeServerHelper.getSyncEntitiesByModelType(ModelType.BOOKMARKS);
+                mSyncTestRule.getFakeServerHelper().getSyncEntitiesByModelType(ModelType.BOOKMARKS);
         List<Bookmark> bookmarks = new ArrayList<Bookmark>(entities.size());
         for (SyncEntity entity : entities) {
             String id = entity.idString;
@@ -473,33 +507,36 @@
     }
 
     private void assertClientBookmarkCount(int count) throws JSONException {
-        assertEquals("There should be " + count + " local bookmarks.",
-                count, SyncTestUtil.getLocalData(mContext, BOOKMARKS_TYPE_STRING).size());
+        Assert.assertEquals("There should be " + count + " local bookmarks.", count,
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), BOOKMARKS_TYPE_STRING)
+                        .size());
     }
 
     private void assertServerBookmarkCountWithName(int count, String name) {
-        assertTrue("There should be " + count + " remote bookmarks with name " + name + ".",
-                mFakeServerHelper.verifyEntityCountByTypeAndName(
-                            count, ModelType.BOOKMARKS, name));
+        Assert.assertTrue("There should be " + count + " remote bookmarks with name " + name + ".",
+                mSyncTestRule.getFakeServerHelper().verifyEntityCountByTypeAndName(
+                        count, ModelType.BOOKMARKS, name));
     }
 
     private void waitForClientBookmarkCount(int n) throws InterruptedException {
-        pollInstrumentationThread(Criteria.equals(n, new Callable<Integer>() {
+        mSyncTestRule.pollInstrumentationThread(Criteria.equals(n, new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return SyncTestUtil.getLocalData(mContext, BOOKMARKS_TYPE_STRING).size();
+                return SyncTestUtil
+                        .getLocalData(mSyncTestRule.getTargetContext(), BOOKMARKS_TYPE_STRING)
+                        .size();
             }
         }));
     }
 
     private void waitForServerBookmarkCountWithName(final int count, final String name)
             throws InterruptedException {
-        pollInstrumentationThread(new Criteria(
+        mSyncTestRule.pollInstrumentationThread(new Criteria(
                 "Expected " + count + " remote bookmarks with name " + name + ".") {
             @Override
             public boolean isSatisfied() {
                 try {
-                    return mFakeServerHelper.verifyEntityCountByTypeAndName(
+                    return mSyncTestRule.getFakeServerHelper().verifyEntityCountByTypeAndName(
                             count, ModelType.BOOKMARKS, name);
                 } catch (Exception e) {
                     throw new RuntimeException(e);
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java
index 53e31f1..9095b72 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java
@@ -11,9 +11,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
@@ -26,6 +34,8 @@
 import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
 import org.chromium.chrome.browser.preferences.Preferences;
 import org.chromium.chrome.browser.signin.AccountManagementFragment;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ActivityUtils;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
@@ -37,9 +47,61 @@
 /**
  * Tests for the first run experience.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add(ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG)
 @CommandLineFlags.Remove(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
-@RetryOnFailure  // crbug.com/637448
-public class FirstRunTest extends SyncTestBase {
+@RetryOnFailure // crbug.com/637448
+public class FirstRunTest {
+    @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule() {
+        @Override
+        public void startMainActivityForSyncTest() throws Exception {
+            FirstRunActivity.setObserverForTest(mTestObserver);
+
+            // Starts up and waits for the FirstRunActivity to be ready.
+            // This isn't exactly what startMainActivity is supposed to be doing, but short of a
+            // refactoring of SyncTestBase to use something other than ChromeTabbedActivity,
+            // it's the only way to reuse the rest of the setup and initialization code inside of
+            // it.
+            final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+            final Context context = instrumentation.getTargetContext();
+
+            // Create an Intent that causes Chrome to run.
+            final Intent intent = new Intent(TEST_ACTION);
+            intent.setPackage(context.getPackageName());
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+            // Start the FRE.
+            final ActivityMonitor freMonitor =
+                    new ActivityMonitor(FirstRunActivity.class.getName(), null, false);
+            instrumentation.addMonitor(freMonitor);
+            ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+                @Override
+                public void run() {
+                    FirstRunFlowSequencer.launch(context, intent, false /* requiresBroadcast */,
+                            false /* preferLightweightFre */);
+                }
+            });
+
+            // Wait for the FRE to be ready to use.
+            Activity activity =
+                    freMonitor.waitForActivityWithTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL);
+            instrumentation.removeMonitor(freMonitor);
+
+            Assert.assertTrue(activity instanceof FirstRunActivity);
+            mActivity = (FirstRunActivity) activity;
+
+            try {
+                mTestObserver.flowIsKnownCallback.waitForCallback(0);
+            } catch (TimeoutException e) {
+                Assert.fail();
+            }
+
+            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        }
+    };
+
     private static final String TEST_ACTION = "com.artificial.package.TEST_ACTION";
 
     private static enum ShowSettings {
@@ -71,60 +133,10 @@
     private final TestObserver mTestObserver = new TestObserver();
     private FirstRunActivity mActivity;
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        FirstRunActivity.setObserverForTest(mTestObserver);
 
-        // Starts up and waits for the FirstRunActivity to be ready.
-        // This isn't exactly what startMainActivity is supposed to be doing, but short of a
-        // refactoring of SyncTestBase to use something other than ChromeTabbedActivity, it's the
-        // only way to reuse the rest of the setup and initialization code inside of it.
-        final Instrumentation instrumentation = getInstrumentation();
-        final Context context = instrumentation.getTargetContext();
-
-        // Create an Intent that causes Chrome to run.
-        final Intent intent = new Intent(TEST_ACTION);
-        intent.setPackage(context.getPackageName());
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // Start the FRE.
-        final ActivityMonitor freMonitor =
-                new ActivityMonitor(FirstRunActivity.class.getName(), null, false);
-        instrumentation.addMonitor(freMonitor);
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                FirstRunFlowSequencer.launch(context, intent, false /* requiresBroadcast */,
-                        false /* preferLightweightFre */);
-            }
-        });
-
-        // Wait for the FRE to be ready to use.
-        Activity activity =
-                freMonitor.waitForActivityWithTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL);
-        instrumentation.removeMonitor(freMonitor);
-
-        assertTrue(activity instanceof FirstRunActivity);
-        mActivity = (FirstRunActivity) activity;
-
-        try {
-            mTestObserver.flowIsKnownCallback.waitForCallback(0);
-        } catch (TimeoutException e) {
-            fail();
-        }
-
-        getInstrumentation().waitForIdleSync();
-    }
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
+    @After
     public void tearDown() throws Exception {
         if (mActivity != null) mActivity.finish();
-        super.tearDown();
     }
 
     // Test that signing in through FirstRun signs in and starts sync.
@@ -132,14 +144,15 @@
      * @SmallTest
      * @Feature({"Sync"})
      */
+    @Test
     @FlakyTest(message = "https://crbug.com/616456")
     public void testSignIn() throws Exception {
         Account testAccount = SigninTestUtil.addTestAccount();
-        assertNull(SigninTestUtil.getCurrentAccount());
-        assertFalse(SyncTestUtil.isSyncRequested());
+        Assert.assertNull(SigninTestUtil.getCurrentAccount());
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
         processFirstRun(testAccount.name, ShowSettings.NO);
-        assertEquals(testAccount, SigninTestUtil.getCurrentAccount());
+        Assert.assertEquals(testAccount, SigninTestUtil.getCurrentAccount());
         SyncTestUtil.waitForSyncActive();
     }
 
@@ -149,6 +162,7 @@
      * @SmallTest
      * @Feature({"Sync"})
      */
+    @Test
     @FlakyTest(message = "https://crbug.com/616456")
     public void testSignInWithOpenSettings() throws Exception {
         final Account testAccount = SigninTestUtil.addTestAccount();
@@ -156,29 +170,30 @@
 
         // User should be signed in and the sync backend should initialize, but sync should not
         // become fully active until the settings page is closed.
-        assertEquals(testAccount, SigninTestUtil.getCurrentAccount());
+        Assert.assertEquals(testAccount, SigninTestUtil.getCurrentAccount());
         SyncTestUtil.waitForEngineInitialized();
-        assertFalse(SyncTestUtil.isSyncActive());
+        Assert.assertFalse(SyncTestUtil.isSyncActive());
 
         // Close the settings fragment.
         AccountManagementFragment fragment =
                 (AccountManagementFragment) prefActivity.getFragmentForTest();
-        assertNotNull(fragment);
+        Assert.assertNotNull(fragment);
         prefActivity.getFragmentManager().beginTransaction().remove(fragment).commit();
 
         // Sync should immediately become active.
-        assertTrue(SyncTestUtil.isSyncActive());
+        Assert.assertTrue(SyncTestUtil.isSyncActive());
     }
 
     // Test that not signing in through FirstRun does not sign in sync.
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testNoSignIn() throws Exception {
         SigninTestUtil.addTestAccount();
-        assertFalse(SyncTestUtil.isSyncRequested());
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
         processFirstRun(null, ShowSettings.NO);
-        assertNull(SigninTestUtil.getCurrentAccount());
-        assertFalse(SyncTestUtil.isSyncRequested());
+        Assert.assertNull(SigninTestUtil.getCurrentAccount());
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
     }
 
     /**
@@ -199,13 +214,14 @@
         Preferences prefActivity = null;
         if (showSettings == ShowSettings.YES) {
             prefActivity = ActivityUtils.waitForActivity(
-                    getInstrumentation(), Preferences.class, new Runnable() {
+                    InstrumentationRegistry.getInstrumentation(), Preferences.class,
+                    new Runnable() {
                         @Override
                         public void run() {
                             processFirstRunOnUiThread();
                         }
                     });
-            assertNotNull("Could not find the preferences activity", prefActivity);
+            Assert.assertNotNull("Could not find the preferences activity", prefActivity);
         } else {
             processFirstRunOnUiThread();
         }
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java
index e340cdd..8a8792f 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java
@@ -7,9 +7,20 @@
 import android.accounts.Account;
 import android.support.test.filters.MediumTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -19,8 +30,16 @@
 /**
  * Test suite for the GmsCoreSyncListener.
  */
-@RetryOnFailure  // crbug.com/637448
-public class GmsCoreSyncListenerTest extends SyncTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+@RetryOnFailure // crbug.com/637448
+public class GmsCoreSyncListenerTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String PASSPHRASE = "passphrase";
 
     static class CountingGmsCoreSyncListener extends GmsCoreSyncListener {
@@ -38,9 +57,8 @@
 
     private CountingGmsCoreSyncListener mListener;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
         mListener = new CountingGmsCoreSyncListener();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -50,40 +68,41 @@
         });
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
                 ProfileSyncService.get().removeSyncStateChangedListener(mListener);
             }
         });
-        super.tearDown();
     }
 
+    @Test
     @MediumTest
     @Feature({"Sync"})
     public void testGetsKey() throws Throwable {
-        Account account = setUpTestAccountAndSignIn();
-        assertEquals(0, mListener.callCount());
+        Account account = mSyncTestRule.setUpTestAccountAndSignIn();
+        Assert.assertEquals(0, mListener.callCount());
         encryptWithPassphrase(PASSPHRASE);
         waitForCallCount(1);
-        signOut();
-        signIn(account);
-        assertEquals(1, mListener.callCount());
+        mSyncTestRule.signOut();
+        mSyncTestRule.signIn(account);
+        Assert.assertEquals(1, mListener.callCount());
         decryptWithPassphrase(PASSPHRASE);
         waitForCallCount(2);
     }
 
+    @Test
     @MediumTest
     @Feature({"Sync"})
     public void testClearData() throws Throwable {
-        Account account = setUpTestAccountAndSignIn();
-        assertEquals(0, mListener.callCount());
+        Account account = mSyncTestRule.setUpTestAccountAndSignIn();
+        Assert.assertEquals(0, mListener.callCount());
         encryptWithPassphrase(PASSPHRASE);
         waitForCallCount(1);
-        clearServerData();
-        signIn(account);
+        mSyncTestRule.clearServerData();
+        mSyncTestRule.signIn(account);
         encryptWithPassphrase(PASSPHRASE);
         waitForCallCount(2);
     }
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java
index 31cdffe..19115a1 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java
@@ -10,15 +10,24 @@
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.TabState;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.components.sync.SyncConstants;
 import org.chromium.components.sync.protocol.EntitySpecifics;
@@ -40,8 +49,16 @@
 /**
  * Test suite for the open tabs (sessions) sync data type.
  */
-@RetryOnFailure  // crbug.com/637448
-public class OpenTabsTest extends SyncTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+@RetryOnFailure // crbug.com/637448
+public class OpenTabsTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String TAG = "OpenTabsTest";
 
     private static final String OPEN_TABS_TYPE = "Sessions";
@@ -76,10 +93,9 @@
         }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        setUpTestAccountAndSignIn();
+    @Before
+    public void setUp() throws Exception {
+        mSyncTestRule.setUpTestAccountAndSignIn();
         mClientName = getClientName();
         mSessionTagCounter = 0;
     }
@@ -89,9 +105,10 @@
     @LargeTest
     @Feature({"Sync"})
     */
+    @Test
     @FlakyTest(message = "https://crbug.com/592437")
     public void testUploadOpenTab() throws Exception {
-        loadUrl(URL);
+        mSyncTestRule.loadUrl(URL);
         waitForLocalTabsForClient(mClientName, URL);
         waitForServerTabs(URL);
     }
@@ -101,11 +118,12 @@
     @LargeTest
     @Feature({"Sync"})
     */
+    @Test
     @FlakyTest(message = "https://crbug.com/592437")
     public void testUploadMultipleOpenTabs() throws Exception {
-        loadUrl(URL);
-        loadUrlInNewTab(URL2);
-        loadUrlInNewTab(URL3);
+        mSyncTestRule.loadUrl(URL);
+        mSyncTestRule.loadUrlInNewTab(URL2);
+        mSyncTestRule.loadUrlInNewTab(URL3);
         waitForLocalTabsForClient(mClientName, URL, URL2, URL3);
         waitForServerTabs(URL, URL2, URL3);
     }
@@ -115,19 +133,20 @@
     @LargeTest
     @Feature({"Sync"})
     */
+    @Test
     @FlakyTest(message = "https://crbug.com/592437")
     public void testUploadAndCloseOpenTab() throws Exception {
-        loadUrl(URL);
+        mSyncTestRule.loadUrl(URL);
         // Can't have zero tabs, so we have to open two to test closing one.
-        loadUrlInNewTab(URL2);
+        mSyncTestRule.loadUrlInNewTab(URL2);
         waitForLocalTabsForClient(mClientName, URL, URL2);
         waitForServerTabs(URL, URL2);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                TabModelSelector selector = getActivity().getTabModelSelector();
-                assertTrue(TabModelUtils.closeCurrentTab(selector.getCurrentModel()));
+                TabModelSelector selector = mSyncTestRule.getActivity().getTabModelSelector();
+                Assert.assertTrue(TabModelUtils.closeCurrentTab(selector.getCurrentModel()));
             }
         });
 
@@ -136,6 +155,7 @@
     }
 
     // Test syncing an open tab from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadOpenTab() throws Exception {
@@ -145,6 +165,7 @@
     }
 
     // Test syncing multiple open tabs from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadMultipleOpenTabs() throws Exception {
@@ -154,6 +175,7 @@
     }
 
     // Test syncing a tab deletion from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadDeletedOpenTab() throws Exception {
@@ -169,6 +191,7 @@
     }
 
     // Test syncing multiple tab deletions from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadMultipleDeletedOpenTabs() throws Exception {
@@ -184,23 +207,28 @@
     }
 
     // Test
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testTabGetsValidSyncId() throws Exception {
-        Tab tab = loadUrlInNewTab(URL);
-
-        TabState state = tab.getState();
-        assertFalse(state.syncId == SyncConstants.INVALID_TAB_NODE_ID);
+        final Tab tab = mSyncTestRule.loadUrlInNewTab(URL);
+        ThreadUtils.runOnUiThreadBlocking(() -> {
+            TabState state = tab.getState();
+            Assert.assertFalse(state.syncId == SyncConstants.INVALID_TAB_NODE_ID);
+        });
     }
 
     // Test
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testIncognitoTabGetsInvalidSyncId() throws Exception {
-        Tab tab = loadUrlInNewTab(URL, /*incognito=*/true);
+        final Tab tab = mSyncTestRule.loadUrlInNewTab(URL, /*incognito=*/true);
 
-        TabState state = tab.getState();
-        assertEquals(state.syncId, SyncConstants.INVALID_TAB_NODE_ID);
+        ThreadUtils.runOnUiThreadBlocking(() -> {
+            TabState state = tab.getState();
+            Assert.assertEquals(state.syncId, SyncConstants.INVALID_TAB_NODE_ID);
+        });
     }
 
     private String makeSessionTag() {
@@ -211,12 +239,12 @@
             throws InterruptedException {
         String tag = makeSessionTag();
         EntitySpecifics header = makeSessionEntity(tag, clientName, urls.length);
-        mFakeServerHelper.injectUniqueClientEntity(tag, header);
+        mSyncTestRule.getFakeServerHelper().injectUniqueClientEntity(tag, header);
         for (int i = 0; i < urls.length; i++) {
             EntitySpecifics tab = makeTabEntity(tag, urls[i], i);
             // It is critical that the name here is "<tag> <tabNodeId>", otherwise sync crashes
             // when it tries to sync due to the use of TabIdToTag in sessions_sync_manager.cc.
-            mFakeServerHelper.injectUniqueClientEntity(tag + " " + i, tab);
+            mSyncTestRule.getFakeServerHelper().injectUniqueClientEntity(tag + " " + i, tab);
         }
     }
 
@@ -255,9 +283,9 @@
 
     private void deleteServerTabsForClient(String clientName) throws JSONException {
         OpenTabs openTabs = getLocalTabsForClient(clientName);
-        mFakeServerHelper.deleteEntity(openTabs.headerId);
+        mSyncTestRule.getFakeServerHelper().deleteEntity(openTabs.headerId);
         for (String tabId : openTabs.tabIds) {
-            mFakeServerHelper.deleteEntity(tabId);
+            mSyncTestRule.getFakeServerHelper().deleteEntity(tabId);
         }
     }
 
@@ -265,22 +293,23 @@
             throws InterruptedException {
         final List<String> urlList = new ArrayList<>(urls.length);
         for (String url : urls) urlList.add(url);
-        pollInstrumentationThread(Criteria.equals(urlList, new Callable<List<String>>() {
-            @Override
-            public List<String> call() throws Exception {
-                return getLocalTabsForClient(clientName).urls;
-            }
-        }));
+        mSyncTestRule.pollInstrumentationThread(
+                Criteria.equals(urlList, new Callable<List<String>>() {
+                    @Override
+                    public List<String> call() throws Exception {
+                        return getLocalTabsForClient(clientName).urls;
+                    }
+                }));
     }
 
     private void waitForServerTabs(final String... urls)
             throws InterruptedException {
-        pollInstrumentationThread(
+        mSyncTestRule.pollInstrumentationThread(
                 new Criteria("Expected server open tabs: " + Arrays.toString(urls)) {
                     @Override
                     public boolean isSatisfied() {
                         try {
-                            return mFakeServerHelper.verifySessions(urls);
+                            return mSyncTestRule.getFakeServerHelper().verifySessions(urls);
                         } catch (Exception e) {
                             throw new RuntimeException(e);
                         }
@@ -289,18 +318,22 @@
     }
 
     private String getClientName() throws Exception {
-        pollInstrumentationThread(new Criteria("Expected at least one tab entity to exist.") {
+        mSyncTestRule.pollInstrumentationThread(new Criteria(
+                "Expected at least one tab entity to exist.") {
             @Override
             public boolean isSatisfied() {
                 try {
-                    return SyncTestUtil.getLocalData(mContext, OPEN_TABS_TYPE).size() > 0;
+                    return SyncTestUtil
+                                   .getLocalData(mSyncTestRule.getTargetContext(), OPEN_TABS_TYPE)
+                                   .size()
+                            > 0;
                 } catch (JSONException e) {
                     return false;
                 }
             }
         });
-        List<Pair<String, JSONObject>> tabEntities = SyncTestUtil.getLocalData(
-                mContext, OPEN_TABS_TYPE);
+        List<Pair<String, JSONObject>> tabEntities =
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), OPEN_TABS_TYPE);
         for (Pair<String, JSONObject> tabEntity : tabEntities) {
             if (tabEntity.second.has("header")) {
                 return tabEntity.second.getJSONObject("header").getString("client_name");
@@ -322,8 +355,8 @@
 
     // Distills the local session data into a simple data object for the given client.
     private OpenTabs getLocalTabsForClient(String clientName) throws JSONException {
-        List<Pair<String, JSONObject>> tabEntities = SyncTestUtil.getLocalData(
-                mContext, OPEN_TABS_TYPE);
+        List<Pair<String, JSONObject>> tabEntities =
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), OPEN_TABS_TYPE);
         // Output lists.
         List<String> urls = new ArrayList<>();
         List<String> tabEntityIds = new ArrayList<>();
@@ -359,7 +392,7 @@
                     // The client was found but there are no tabs.
                     break;
                 }
-                assertEquals("Only single windows are supported.", 1, windows.length());
+                Assert.assertEquals("Only single windows are supported.", 1, windows.length());
                 JSONArray tabs = windows.getJSONObject(0).getJSONArray("tab");
                 for (int i = 0; i < tabs.length(); i++) {
                     tabIds.add(tabs.getString(i));
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java
index d068de3..229724c 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java
@@ -11,16 +11,25 @@
 import android.preference.Preference;
 import android.preference.SwitchPreference;
 import android.preference.TwoStatePreference;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.v7.app.AlertDialog;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.autofill.CardType;
 import org.chromium.chrome.browser.autofill.PersonalDataManager;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
@@ -29,6 +38,8 @@
 import org.chromium.chrome.browser.sync.ui.PassphraseDialogFragment;
 import org.chromium.chrome.browser.sync.ui.PassphraseTypeDialogFragment;
 import org.chromium.chrome.browser.sync.ui.SyncCustomizationFragment;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ActivityUtils;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.components.sync.AndroidSyncSettings;
@@ -47,9 +58,17 @@
 /**
  * Tests for SyncCustomizationFragment.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
 @SuppressLint("UseSparseArrays")
-@RetryOnFailure  // crbug.com/637448
-public class SyncCustomizationFragmentTest extends SyncTestBase {
+@RetryOnFailure // crbug.com/637448
+public class SyncCustomizationFragmentTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String TAG = "SyncCustomizationFragmentTest";
 
     /**
@@ -64,7 +83,8 @@
             setMasterSyncEnabledProvider(new MasterSyncEnabledProvider() {
                 @Override
                 public boolean isMasterSyncEnabled() {
-                    return AndroidSyncSettings.isMasterSyncEnabled(mContext);
+                    return AndroidSyncSettings.isMasterSyncEnabled(
+                            mSyncTestRule.getTargetContext());
                 }
             });
         }
@@ -98,66 +118,73 @@
 
     private Preferences mPreferences;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
         mPreferences = null;
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testSyncSwitch() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         final SwitchPreference syncSwitch = getSyncSwitch(fragment);
 
-        assertTrue(syncSwitch.isChecked());
-        assertTrue(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertTrue(syncSwitch.isChecked());
+        Assert.assertTrue(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
         togglePreference(syncSwitch);
-        assertFalse(syncSwitch.isChecked());
-        assertFalse(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertFalse(syncSwitch.isChecked());
+        Assert.assertFalse(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
         togglePreference(syncSwitch);
-        assertTrue(syncSwitch.isChecked());
-        assertTrue(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertTrue(syncSwitch.isChecked());
+        Assert.assertTrue(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
     }
 
     /**
      * This is a regression test for http://crbug.com/454939.
      */
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testOpeningSettingsDoesntEnableSync() throws Exception {
-        setUpTestAccountAndSignIn();
-        stopSync();
+        mSyncTestRule.setUpTestAccountAndSignIn();
+        mSyncTestRule.stopSync();
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         closeFragment(fragment);
-        assertFalse(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertFalse(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
     }
 
     /**
      * This is a regression test for http://crbug.com/467600.
      */
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testOpeningSettingsDoesntStartEngine() throws Exception {
-        setUpTestAccountAndSignIn();
-        stopSync();
+        mSyncTestRule.setUpTestAccountAndSignIn();
+        mSyncTestRule.stopSync();
         startSyncCustomizationFragment();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertFalse(mProfileSyncService.isSyncRequested());
-                assertFalse(mProfileSyncService.isEngineInitialized());
+                Assert.assertFalse(mSyncTestRule.getProfileSyncService().isSyncRequested());
+                Assert.assertFalse(mSyncTestRule.getProfileSyncService().isEngineInitialized());
             }
         });
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testDefaultControlStatesWithSyncOffThenOn() throws Exception {
-        setUpTestAccountAndSignIn();
-        stopSync();
+        mSyncTestRule.setUpTestAccountAndSignIn();
+        mSyncTestRule.stopSync();
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         assertDefaultSyncOffState(fragment);
         togglePreference(getSyncSwitch(fragment));
@@ -165,10 +192,11 @@
         assertDefaultSyncOnState(fragment);
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testDefaultControlStatesWithSyncOnThenOff() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         assertDefaultSyncOnState(fragment);
@@ -176,10 +204,11 @@
         assertDefaultSyncOffState(fragment);
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testSyncEverythingAndDataTypes() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         SwitchPreference syncEverything = getSyncEverything(fragment);
@@ -188,23 +217,25 @@
         assertDefaultSyncOnState(fragment);
         togglePreference(syncEverything);
         for (CheckBoxPreference dataType : dataTypes) {
-            assertTrue(dataType.isChecked());
-            assertTrue(dataType.isEnabled());
+            Assert.assertTrue(dataType.isChecked());
+            Assert.assertTrue(dataType.isEnabled());
         }
 
         // If all data types are unchecked, sync should turn off.
         for (CheckBoxPreference dataType : dataTypes) {
             togglePreference(dataType);
         }
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
         assertDefaultSyncOffState(fragment);
-        assertFalse(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertFalse(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testSettingDataTypes() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         SwitchPreference syncEverything = getSyncEverything(fragment);
@@ -213,8 +244,8 @@
         assertDefaultSyncOnState(fragment);
         togglePreference(syncEverything);
         for (CheckBoxPreference dataType : dataTypes.values()) {
-            assertTrue(dataType.isChecked());
-            assertTrue(dataType.isEnabled());
+            Assert.assertTrue(dataType.isChecked());
+            Assert.assertTrue(dataType.isEnabled());
         }
 
         Set<Integer> expectedTypes = new HashSet<Integer>(dataTypes.keySet());
@@ -232,10 +263,11 @@
         assertDataTypesAre(expectedTypes);
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationChecked() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(true);
 
@@ -245,14 +277,15 @@
         CheckBoxPreference paymentsIntegration = (CheckBoxPreference) fragment.findPreference(
                 SyncCustomizationFragment.PREFERENCE_PAYMENTS_INTEGRATION);
 
-        assertFalse(paymentsIntegration.isEnabled());
-        assertTrue(paymentsIntegration.isChecked());
+        Assert.assertFalse(paymentsIntegration.isEnabled());
+        Assert.assertTrue(paymentsIntegration.isChecked());
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationUnchecked() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(false);
 
@@ -264,14 +297,15 @@
         CheckBoxPreference paymentsIntegration = (CheckBoxPreference) fragment.findPreference(
                 SyncCustomizationFragment.PREFERENCE_PAYMENTS_INTEGRATION);
 
-        assertTrue(paymentsIntegration.isEnabled());
-        assertFalse(paymentsIntegration.isChecked());
+        Assert.assertTrue(paymentsIntegration.isEnabled());
+        Assert.assertFalse(paymentsIntegration.isChecked());
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationCheckboxDisablesPaymentsIntegration() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(true);
 
@@ -288,10 +322,11 @@
         assertPaymentsIntegrationEnabled(false);
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationCheckboxEnablesPaymentsIntegration() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(false);
 
@@ -308,16 +343,17 @@
         assertPaymentsIntegrationEnabled(true);
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationCheckboxClearsServerAutofillCreditCards() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(true);
 
-        assertFalse("There should be no server cards", hasServerAutofillCreditCards());
+        Assert.assertFalse("There should be no server cards", hasServerAutofillCreditCards());
         addServerAutofillCreditCard();
-        assertTrue("There should be server cards", hasServerAutofillCreditCards());
+        Assert.assertTrue("There should be server cards", hasServerAutofillCreditCards());
 
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         assertDefaultSyncOnState(fragment);
@@ -331,39 +367,46 @@
         closeFragment(fragment);
         assertPaymentsIntegrationEnabled(false);
 
-        assertFalse("There should be no server cards remaining", hasServerAutofillCreditCards());
+        Assert.assertFalse(
+                "There should be no server cards remaining", hasServerAutofillCreditCards());
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testSyncSwitchClearsServerAutofillCreditCards() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(true);
 
-        assertFalse("There should be no server cards", hasServerAutofillCreditCards());
+        Assert.assertFalse("There should be no server cards", hasServerAutofillCreditCards());
         addServerAutofillCreditCard();
-        assertTrue("There should be server cards", hasServerAutofillCreditCards());
+        Assert.assertTrue("There should be server cards", hasServerAutofillCreditCards());
 
-        assertTrue(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertTrue(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         assertDefaultSyncOnState(fragment);
         SwitchPreference syncSwitch = getSyncSwitch(fragment);
-        assertTrue(syncSwitch.isChecked());
-        assertTrue(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertTrue(syncSwitch.isChecked());
+        Assert.assertTrue(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
         togglePreference(syncSwitch);
-        assertFalse(syncSwitch.isChecked());
-        assertFalse(AndroidSyncSettings.isChromeSyncEnabled(mContext));
+        Assert.assertFalse(syncSwitch.isChecked());
+        Assert.assertFalse(
+                AndroidSyncSettings.isChromeSyncEnabled(mSyncTestRule.getTargetContext()));
 
         closeFragment(fragment);
 
-        assertFalse("There should be no server cards remaining", hasServerAutofillCreditCards());
+        Assert.assertFalse(
+                "There should be no server cards remaining", hasServerAutofillCreditCards());
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationDisabledByAutofillSyncCheckbox() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(true);
 
@@ -378,17 +421,18 @@
 
         CheckBoxPreference paymentsIntegration = (CheckBoxPreference) fragment.findPreference(
                 SyncCustomizationFragment.PREFERENCE_PAYMENTS_INTEGRATION);
-        assertFalse(paymentsIntegration.isEnabled());
-        assertFalse(paymentsIntegration.isChecked());
+        Assert.assertFalse(paymentsIntegration.isEnabled());
+        Assert.assertFalse(paymentsIntegration.isChecked());
 
         closeFragment(fragment);
         assertPaymentsIntegrationEnabled(false);
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationEnabledByAutofillSyncCheckbox() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
 
         setPaymentsIntegrationEnabled(false);
 
@@ -404,19 +448,20 @@
 
         CheckBoxPreference paymentsIntegration = (CheckBoxPreference) fragment.findPreference(
                 SyncCustomizationFragment.PREFERENCE_PAYMENTS_INTEGRATION);
-        assertTrue(paymentsIntegration.isEnabled());
-        assertTrue(paymentsIntegration.isChecked());
+        Assert.assertTrue(paymentsIntegration.isEnabled());
+        Assert.assertTrue(paymentsIntegration.isChecked());
 
         closeFragment(fragment);
         assertPaymentsIntegrationEnabled(true);
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPaymentsIntegrationEnabledBySyncEverything() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         setPaymentsIntegrationEnabled(false);
-        disableDataType(ModelType.AUTOFILL);
+        mSyncTestRule.disableDataType(ModelType.AUTOFILL);
 
         // Get the UI elements.
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
@@ -427,19 +472,19 @@
                 SyncCustomizationFragment.PREFERENCE_PAYMENTS_INTEGRATION);
 
         // All three are unchecked and payments is disabled.
-        assertFalse(syncEverything.isChecked());
-        assertFalse(syncAutofill.isChecked());
-        assertTrue(syncAutofill.isEnabled());
-        assertFalse(paymentsIntegration.isChecked());
-        assertFalse(paymentsIntegration.isEnabled());
+        Assert.assertFalse(syncEverything.isChecked());
+        Assert.assertFalse(syncAutofill.isChecked());
+        Assert.assertTrue(syncAutofill.isEnabled());
+        Assert.assertFalse(paymentsIntegration.isChecked());
+        Assert.assertFalse(paymentsIntegration.isEnabled());
 
         // All three are checked after toggling sync everything.
         togglePreference(syncEverything);
-        assertTrue(syncEverything.isChecked());
-        assertTrue(syncAutofill.isChecked());
-        assertFalse(syncAutofill.isEnabled());
-        assertTrue(paymentsIntegration.isChecked());
-        assertFalse(paymentsIntegration.isEnabled());
+        Assert.assertTrue(syncEverything.isChecked());
+        Assert.assertTrue(syncAutofill.isChecked());
+        Assert.assertFalse(syncAutofill.isEnabled());
+        Assert.assertTrue(paymentsIntegration.isChecked());
+        Assert.assertFalse(paymentsIntegration.isEnabled());
 
         // Closing the fragment enabled payments integration.
         closeFragment(fragment);
@@ -451,17 +496,18 @@
      *
      * This is a regression test for http://crbug.com/507557.
      */
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testChoosePassphraseTypeWhenSyncIsOff() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         Preference encryption = getEncryption(fragment);
         clickPreference(encryption);
 
         final PassphraseTypeDialogFragment typeFragment = getPassphraseTypeDialogFragment();
-        stopSync();
+        mSyncTestRule.stopSync();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -475,13 +521,14 @@
     /**
      * Test that entering a passphrase while sync is off doesn't crash.
      */
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testEnterPassphraseWhenSyncIsOff() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         final SyncCustomizationFragment fragment = startSyncCustomizationFragment();
-        stopSync();
+        mSyncTestRule.stopSync();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -494,12 +541,13 @@
     /**
      * Test that triggering OnPassphraseAccepted dismisses PassphraseDialogFragment.
      */
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPassphraseDialogDismissed() throws Exception {
         final FakeProfileSyncService pss = overrideProfileSyncService();
 
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         // Trigger PassphraseDialogFragment to be shown when taping on Encryption.
         pss.setPassphraseRequiredForDecryption(true);
@@ -509,7 +557,7 @@
         clickPreference(encryption);
 
         final PassphraseDialogFragment passphraseFragment = getPassphraseDialogFragment();
-        assertTrue(passphraseFragment.isAdded());
+        Assert.assertTrue(passphraseFragment.isAdded());
 
         // Simulate OnPassphraseAccepted from external event by setting PassphraseRequired to false
         // and triggering syncStateChanged().
@@ -520,17 +568,18 @@
             public void run() {
                 pss.syncStateChanged();
                 fragment.getFragmentManager().executePendingTransactions();
-                assertNull("PassphraseDialogFragment should be dismissed.",
+                Assert.assertNull("PassphraseDialogFragment should be dismissed.",
                         mPreferences.getFragmentManager().findFragmentByTag(
                                 SyncCustomizationFragment.FRAGMENT_ENTER_PASSPHRASE));
             }
         });
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testPassphraseCreation() throws Exception {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         SyncTestUtil.waitForSyncActive();
         final SyncCustomizationFragment fragment = startSyncCustomizationFragment();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -539,7 +588,7 @@
                 fragment.onPassphraseTypeSelected(PassphraseType.CUSTOM_PASSPHRASE);
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
         PassphraseCreationDialogFragment pcdf = getPassphraseCreationDialogFragment();
         AlertDialog dialog = (AlertDialog) pcdf.getDialog();
         Button okButton = dialog.getButton(Dialog.BUTTON_POSITIVE);
@@ -547,52 +596,52 @@
         EditText confirmPassphrase = (EditText) dialog.findViewById(R.id.confirm_passphrase);
 
         // Error if you try to submit empty passphrase.
-        assertNull(confirmPassphrase.getError());
+        Assert.assertNull(confirmPassphrase.getError());
         clickButton(okButton);
-        assertTrue(pcdf.isResumed());
-        assertNotNull(enterPassphrase.getError());
-        assertNull(confirmPassphrase.getError());
+        Assert.assertTrue(pcdf.isResumed());
+        Assert.assertNotNull(enterPassphrase.getError());
+        Assert.assertNull(confirmPassphrase.getError());
 
         // Error if you try to submit with only the first box filled.
         clearError(confirmPassphrase);
         setText(enterPassphrase, "foo");
         clickButton(okButton);
-        assertTrue(pcdf.isResumed());
-        assertNull(enterPassphrase.getError());
-        assertNotNull(confirmPassphrase.getError());
+        Assert.assertTrue(pcdf.isResumed());
+        Assert.assertNull(enterPassphrase.getError());
+        Assert.assertNotNull(confirmPassphrase.getError());
 
         // Remove first box should only show empty error message
         setText(enterPassphrase, "");
         clickButton(okButton);
-        assertNotNull(enterPassphrase.getError());
-        assertNull(confirmPassphrase.getError());
+        Assert.assertNotNull(enterPassphrase.getError());
+        Assert.assertNull(confirmPassphrase.getError());
 
         // Error if you try to submit with only the second box filled.
         clearError(confirmPassphrase);
         setText(confirmPassphrase, "foo");
         clickButton(okButton);
-        assertTrue(pcdf.isResumed());
-        assertNull(enterPassphrase.getError());
-        assertNotNull(confirmPassphrase.getError());
+        Assert.assertTrue(pcdf.isResumed());
+        Assert.assertNull(enterPassphrase.getError());
+        Assert.assertNotNull(confirmPassphrase.getError());
 
         // No error if text doesn't match without button press.
         setText(enterPassphrase, "foo");
         clearError(confirmPassphrase);
         setText(confirmPassphrase, "bar");
-        assertNull(enterPassphrase.getError());
-        assertNull(confirmPassphrase.getError());
+        Assert.assertNull(enterPassphrase.getError());
+        Assert.assertNull(confirmPassphrase.getError());
 
         // Error if you try to submit unmatching text.
         clearError(confirmPassphrase);
         clickButton(okButton);
-        assertTrue(pcdf.isResumed());
-        assertNull(enterPassphrase.getError());
-        assertNotNull(confirmPassphrase.getError());
+        Assert.assertTrue(pcdf.isResumed());
+        Assert.assertNull(enterPassphrase.getError());
+        Assert.assertNotNull(confirmPassphrase.getError());
 
         // Success if text matches.
         setText(confirmPassphrase, "foo");
         clickButton(okButton);
-        assertFalse(pcdf.isResumed());
+        Assert.assertFalse(pcdf.isResumed());
     }
 
     private FakeProfileSyncService overrideProfileSyncService() {
@@ -608,8 +657,8 @@
     }
 
     private SyncCustomizationFragment startSyncCustomizationFragment() {
-        mPreferences = startPreferences(SyncCustomizationFragment.class.getName());
-        getInstrumentation().waitForIdleSync();
+        mPreferences = mSyncTestRule.startPreferences(SyncCustomizationFragment.class.getName());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
         return (SyncCustomizationFragment) mPreferences.getFragmentForTest();
     }
 
@@ -617,7 +666,7 @@
         FragmentTransaction transaction = mPreferences.getFragmentManager().beginTransaction();
         transaction.remove(fragment);
         transaction.commit();
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     private SwitchPreference getSyncSwitch(SyncCustomizationFragment fragment) {
@@ -670,36 +719,40 @@
     }
 
     private void assertDefaultSyncOnState(SyncCustomizationFragment fragment) {
-        assertTrue("The sync switch should be on.", getSyncSwitch(fragment).isChecked());
-        assertTrue("The sync switch should be enabled.", getSyncSwitch(fragment).isEnabled());
+        Assert.assertTrue("The sync switch should be on.", getSyncSwitch(fragment).isChecked());
+        Assert.assertTrue(
+                "The sync switch should be enabled.", getSyncSwitch(fragment).isEnabled());
         SwitchPreference syncEverything = getSyncEverything(fragment);
-        assertTrue("The sync everything switch should be on.", syncEverything.isChecked());
-        assertTrue("The sync everything switch should be enabled.", syncEverything.isEnabled());
+        Assert.assertTrue("The sync everything switch should be on.", syncEverything.isChecked());
+        Assert.assertTrue(
+                "The sync everything switch should be enabled.", syncEverything.isEnabled());
         for (CheckBoxPreference dataType : getDataTypes(fragment).values()) {
             String key = dataType.getKey();
-            assertTrue("Data type " + key + " should be checked.", dataType.isChecked());
-            assertFalse("Data type " + key + " should be disabled.", dataType.isEnabled());
+            Assert.assertTrue("Data type " + key + " should be checked.", dataType.isChecked());
+            Assert.assertFalse("Data type " + key + " should be disabled.", dataType.isEnabled());
         }
-        assertTrue("The encryption button should be enabled.",
-                getEncryption(fragment).isEnabled());
-        assertTrue("The manage sync data button should be always enabled.",
+        Assert.assertTrue(
+                "The encryption button should be enabled.", getEncryption(fragment).isEnabled());
+        Assert.assertTrue("The manage sync data button should be always enabled.",
                 getManageData(fragment).isEnabled());
     }
 
     private void assertDefaultSyncOffState(SyncCustomizationFragment fragment) {
-        assertFalse("The sync switch should be off.", getSyncSwitch(fragment).isChecked());
-        assertTrue("The sync switch should be enabled.", getSyncSwitch(fragment).isEnabled());
+        Assert.assertFalse("The sync switch should be off.", getSyncSwitch(fragment).isChecked());
+        Assert.assertTrue(
+                "The sync switch should be enabled.", getSyncSwitch(fragment).isEnabled());
         SwitchPreference syncEverything = getSyncEverything(fragment);
-        assertTrue("The sync everything switch should be on.", syncEverything.isChecked());
-        assertFalse("The sync everything switch should be disabled.", syncEverything.isEnabled());
+        Assert.assertTrue("The sync everything switch should be on.", syncEverything.isChecked());
+        Assert.assertFalse(
+                "The sync everything switch should be disabled.", syncEverything.isEnabled());
         for (CheckBoxPreference dataType : getDataTypes(fragment).values()) {
             String key = dataType.getKey();
-            assertTrue("Data type " + key + " should be checked.", dataType.isChecked());
-            assertFalse("Data type " + key + " should be disabled.", dataType.isEnabled());
+            Assert.assertTrue("Data type " + key + " should be checked.", dataType.isChecked());
+            Assert.assertFalse("Data type " + key + " should be disabled.", dataType.isEnabled());
         }
-        assertFalse("The encryption button should be disabled.",
-                getEncryption(fragment).isEnabled());
-        assertTrue("The manage sync data button should be always enabled.",
+        Assert.assertFalse(
+                "The encryption button should be disabled.", getEncryption(fragment).isEnabled());
+        Assert.assertTrue("The manage sync data button should be always enabled.",
                 getManageData(fragment).isEnabled());
     }
 
@@ -709,9 +762,10 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                Set<Integer> actualDataTypes = mProfileSyncService.getPreferredDataTypes();
-                assertTrue(actualDataTypes.containsAll(enabledDataTypes));
-                assertTrue(Collections.disjoint(disabledDataTypes, actualDataTypes));
+                Set<Integer> actualDataTypes =
+                        mSyncTestRule.getProfileSyncService().getPreferredDataTypes();
+                Assert.assertTrue(actualDataTypes.containsAll(enabledDataTypes));
+                Assert.assertTrue(Collections.disjoint(disabledDataTypes, actualDataTypes));
             }
         });
     }
@@ -729,7 +783,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertEquals(enabled, PersonalDataManager.isPaymentsIntegrationEnabled());
+                Assert.assertEquals(enabled, PersonalDataManager.isPaymentsIntegrationEnabled());
             }
         });
     }
@@ -773,7 +827,7 @@
                 pref.setChecked(newValue);
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     private void clickPreference(final Preference pref) {
@@ -783,7 +837,7 @@
                 pref.getOnPreferenceClickListener().onPreferenceClick(pref);
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     private void clickButton(final Button button) {
@@ -793,7 +847,7 @@
                 button.performClick();
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     private void setText(final TextView textView, final String text) {
@@ -803,7 +857,7 @@
                 textView.setText(text);
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     private void clearError(final TextView textView) {
@@ -813,6 +867,6 @@
                 textView.setError(null);
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 }
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
index 9a3e8cd9..c454767 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
@@ -6,20 +6,30 @@
 
 import android.accounts.Account;
 import android.app.Activity;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ActivityState;
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.signin.AccountIdProvider;
 import org.chromium.chrome.browser.signin.AccountTrackerService;
 import org.chromium.chrome.browser.signin.SigninHelper;
 import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.signin.MockChangeEventChecker;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
@@ -31,17 +41,26 @@
 /**
  * Test suite for Sync.
  */
-@RetryOnFailure  // crbug.com/637448
-public class SyncTest extends SyncTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+@RetryOnFailure // crbug.com/637448
+public class SyncTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String TAG = "SyncTest";
 
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testFlushDirectoryDoesntBreakSync() throws Throwable {
-        setUpTestAccountAndSignIn();
-        final Activity activity = getActivity();
+        mSyncTestRule.setUpTestAccountAndSignIn();
+        final Activity activity = mSyncTestRule.getActivity();
 
-        runTestOnUiThread(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 ApplicationStatus.onStateChangeForTesting(activity, ActivityState.PAUSED);
@@ -51,43 +70,47 @@
         // TODO(pvalenzuela): When available, check that sync is still functional.
     }
 
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testSignInAndOut() throws InterruptedException {
-        Account account = setUpTestAccountAndSignIn();
+        Account account = mSyncTestRule.setUpTestAccountAndSignIn();
 
         // Signing out should disable sync.
-        signOut();
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.signOut();
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
         // Signing back in should re-enable sync.
-        signIn(account);
+        mSyncTestRule.signIn(account);
         SyncTestUtil.waitForSyncActive();
     }
 
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testStopAndClear() {
-        setUpTestAccountAndSignIn();
+        mSyncTestRule.setUpTestAccountAndSignIn();
         CriteriaHelper.pollUiThread(
                 new Criteria("Timed out checking that isSignedInOnNative() == true") {
                     @Override
                     public boolean isSatisfied() {
-                        return SigninManager.get(mContext).isSignedInOnNative();
+                        return SigninManager.get(mSyncTestRule.getTargetContext())
+                                .isSignedInOnNative();
                     }
                 },
                 SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
 
-        clearServerData();
+        mSyncTestRule.clearServerData();
 
         // Clearing server data should turn off sync and sign out of chrome.
-        assertNull(SigninTestUtil.getCurrentAccount());
-        assertFalse(SyncTestUtil.isSyncRequested());
+        Assert.assertNull(SigninTestUtil.getCurrentAccount());
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
         CriteriaHelper.pollUiThread(
                 new Criteria("Timed out checking that isSignedInOnNative() == false") {
                     @Override
                     public boolean isSatisfied() {
-                        return !SigninManager.get(mContext).isSignedInOnNative();
+                        return !SigninManager.get(mSyncTestRule.getTargetContext())
+                                        .isSignedInOnNative();
                     }
                 },
                 SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
@@ -98,10 +121,11 @@
      * @LargeTest
      * @Feature({"Sync"})
      */
+    @Test
     @DisabledTest(message = "crbug.com/588050,crbug.com/595893")
     public void testRename() {
         // The two accounts object that would represent the account rename.
-        final Account oldAccount = setUpTestAccountAndSignIn();
+        final Account oldAccount = mSyncTestRule.setUpTestAccountAndSignIn();
         final Account newAccount = SigninTestUtil.addTestAccount("test2@gmail.com");
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -112,13 +136,15 @@
                 // real account rename events instead of the mocks.
                 MockChangeEventChecker eventChecker = new MockChangeEventChecker();
                 eventChecker.insertRenameEvent(oldAccount.name, newAccount.name);
-                SigninHelper.resetAccountRenameEventIndex(mContext);
-                SigninHelper.updateAccountRenameData(mContext, eventChecker);
+                SigninHelper.resetAccountRenameEventIndex(mSyncTestRule.getTargetContext());
+                SigninHelper.updateAccountRenameData(
+                        mSyncTestRule.getTargetContext(), eventChecker);
 
                 // Tell the fake content resolver that a rename had happen and copy over the sync
-                // settings. This would normally be done by the SystemSyncContentResolver.
-                mSyncContentResolver.renameAccounts(
-                        oldAccount, newAccount, AndroidSyncSettings.getContractAuthority(mContext));
+                // settings. This would normally be done by the
+                // SystemSyncTestRule.getSyncContentResolver().
+                mSyncTestRule.getSyncContentResolver().renameAccounts(oldAccount, newAccount,
+                        AndroidSyncSettings.getContractAuthority(mSyncTestRule.getTargetContext()));
 
                 // Inform the AccountTracker, these would normally be done by account validation
                 // or signin. We will only be calling the testing versions of it.
@@ -130,7 +156,7 @@
 
                 // Starts the rename process. Normally, this is triggered by the broadcast
                 // listener as well.
-                SigninHelper.get(mContext).validateAccountSettings(true);
+                SigninHelper.get(mSyncTestRule.getTargetContext()).validateAccountSettings(true);
             }
         });
 
@@ -143,68 +169,72 @@
         SyncTestUtil.waitForSyncActive();
     }
 
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testStopAndStartSync() {
-        Account account = setUpTestAccountAndSignIn();
+        Account account = mSyncTestRule.setUpTestAccountAndSignIn();
 
-        stopSync();
-        assertEquals(account, SigninTestUtil.getCurrentAccount());
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.stopSync();
+        Assert.assertEquals(account, SigninTestUtil.getCurrentAccount());
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
-        startSyncAndWait();
+        mSyncTestRule.startSyncAndWait();
     }
 
     /*
      * @LargeTest
      * @Feature({"Sync"})
      */
+    @Test
     @FlakyTest(message = "crbug.com/594558")
     public void testStopAndStartSyncThroughAndroid() {
-        Account account = setUpTestAccountAndSignIn();
+        Account account = mSyncTestRule.setUpTestAccountAndSignIn();
 
-        String authority = AndroidSyncSettings.getContractAuthority(mContext);
+        String authority =
+                AndroidSyncSettings.getContractAuthority(mSyncTestRule.getTargetContext());
 
         // Disabling Android sync should turn Chrome sync engine off.
-        mSyncContentResolver.setSyncAutomatically(account, authority, false);
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.getSyncContentResolver().setSyncAutomatically(account, authority, false);
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
         // Enabling Android sync should turn Chrome sync engine on.
-        mSyncContentResolver.setSyncAutomatically(account, authority, true);
+        mSyncTestRule.getSyncContentResolver().setSyncAutomatically(account, authority, true);
         SyncTestUtil.waitForSyncActive();
 
         // Disabling Android's master sync should turn Chrome sync engine off.
-        mSyncContentResolver.setMasterSyncAutomatically(false);
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.getSyncContentResolver().setMasterSyncAutomatically(false);
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
         // Enabling Android's master sync should turn Chrome sync engine on.
-        mSyncContentResolver.setMasterSyncAutomatically(true);
+        mSyncTestRule.getSyncContentResolver().setMasterSyncAutomatically(true);
         SyncTestUtil.waitForSyncActive();
 
         // Disabling both should definitely turn sync off.
-        mSyncContentResolver.setSyncAutomatically(account, authority, false);
-        mSyncContentResolver.setMasterSyncAutomatically(false);
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.getSyncContentResolver().setSyncAutomatically(account, authority, false);
+        mSyncTestRule.getSyncContentResolver().setMasterSyncAutomatically(false);
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
         // Re-enabling master sync should not turn sync back on.
-        mSyncContentResolver.setMasterSyncAutomatically(true);
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.getSyncContentResolver().setMasterSyncAutomatically(true);
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
         // But then re-enabling Chrome sync should.
-        mSyncContentResolver.setSyncAutomatically(account, authority, true);
+        mSyncTestRule.getSyncContentResolver().setSyncAutomatically(account, authority, true);
         SyncTestUtil.waitForSyncActive();
     }
 
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testMasterSyncBlocksSyncStart() {
-        setUpTestAccountAndSignIn();
-        stopSync();
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.setUpTestAccountAndSignIn();
+        mSyncTestRule.stopSync();
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
 
-        mSyncContentResolver.setMasterSyncAutomatically(false);
-        startSync();
-        assertFalse(SyncTestUtil.isSyncRequested());
+        mSyncTestRule.getSyncContentResolver().setMasterSyncAutomatically(false);
+        mSyncTestRule.startSync();
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
     }
 
     private static ContentViewCore getContentViewCore(ChromeActivity activity) {
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java
deleted file mode 100644
index 99a987a3..0000000
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.sync;
-
-import android.accounts.Account;
-import android.content.Context;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.browser.identity.UniqueIdentificationGenerator;
-import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory;
-import org.chromium.chrome.browser.identity.UuidBasedUniqueIdentificationGenerator;
-import org.chromium.chrome.browser.signin.SigninManager;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
-import org.chromium.chrome.test.util.ApplicationTestUtils;
-import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
-import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
-import org.chromium.components.sync.AndroidSyncSettings;
-import org.chromium.components.sync.ModelType;
-import org.chromium.components.sync.test.util.MockSyncContentResolverDelegate;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Base class for common functionality between sync tests.
- */
-public class SyncTestBase extends ChromeActivityTestCaseBase<ChromeActivity> {
-    private static final String TAG = "SyncTestBase";
-
-    private static final String CLIENT_ID = "Client_ID";
-
-    private static final Set<Integer> USER_SELECTABLE_TYPES =
-            new HashSet<Integer>(Arrays.asList(new Integer[] {
-                ModelType.AUTOFILL,
-                ModelType.BOOKMARKS,
-                ModelType.PASSWORDS,
-                ModelType.PREFERENCES,
-                ModelType.PROXY_TABS,
-                ModelType.TYPED_URLS,
-            }));
-
-    protected abstract class DataCriteria<T> extends Criteria {
-        public DataCriteria() {
-            super("Sync data criteria not met.");
-        }
-
-        public abstract boolean isSatisfied(List<T> data);
-
-        public abstract List<T> getData() throws Exception;
-
-        @Override
-        public boolean isSatisfied() {
-            try {
-                return isSatisfied(getData());
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    protected Context mContext;
-    protected FakeServerHelper mFakeServerHelper;
-    protected ProfileSyncService mProfileSyncService;
-    protected MockSyncContentResolverDelegate mSyncContentResolver;
-
-    public SyncTestBase() {
-      super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        // Start the activity by opening about:blank. This URL is ideal because it is not synced as
-        // a typed URL. If another URL is used, it could interfere with test data.
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        // This must be called before doing anything with the SharedPreferences because
-        // super.setUp() normally wipes them clean between runs.  Setting a SharedPreference here
-        // via the SigninTestUtil.setUpAuthForTest() call below causes Android to cache them before
-        // the files get cleared, meaning that a data clear is useless and test runs influence each
-        // other.
-        ApplicationTestUtils.clearAppData(getInstrumentation().getTargetContext());
-
-        // This must be called before super.setUp() in order for test authentication to work.
-        SigninTestUtil.setUpAuthForTest(getInstrumentation());
-
-        super.setUp();
-        mContext = getInstrumentation().getTargetContext();
-
-        setUpMockAndroidSyncSettings();
-
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                // Ensure SyncController is registered with the new AndroidSyncSettings.
-                AndroidSyncSettings.registerObserver(mContext, SyncController.get(mContext));
-                mFakeServerHelper = FakeServerHelper.get();
-            }
-        });
-        FakeServerHelper.useFakeServer(mContext);
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mProfileSyncService = ProfileSyncService.get();
-            }
-        });
-
-        UniqueIdentificationGeneratorFactory.registerGenerator(
-                UuidBasedUniqueIdentificationGenerator.GENERATOR_ID,
-                new UniqueIdentificationGenerator() {
-                    @Override
-                    public String getUniqueId(String salt) {
-                        return CLIENT_ID;
-                    }
-                }, true);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mProfileSyncService.requestStop();
-                FakeServerHelper.deleteFakeServer();
-            }
-        });
-        SigninTestUtil.resetSigninState();
-        SigninTestUtil.tearDownAuthForTest();
-
-        super.tearDown();
-    }
-
-    private void setUpMockAndroidSyncSettings() {
-        mSyncContentResolver = new MockSyncContentResolverDelegate();
-        mSyncContentResolver.setMasterSyncAutomatically(true);
-        AndroidSyncSettings.overrideForTests(mContext, mSyncContentResolver);
-    }
-
-    protected Account setUpTestAccount() {
-        Account account = SigninTestUtil.addTestAccount();
-        assertFalse(SyncTestUtil.isSyncRequested());
-        return account;
-    }
-
-    protected Account setUpTestAccountAndSignIn() {
-        Account account = setUpTestAccount();
-        signIn(account);
-        return account;
-    }
-
-    protected void startSync() {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mProfileSyncService.requestStart();
-            }
-        });
-    }
-
-    protected void startSyncAndWait() {
-        startSync();
-        SyncTestUtil.waitForSyncActive();
-    }
-
-    protected void stopSync() {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mProfileSyncService.requestStop();
-            }
-        });
-        getInstrumentation().waitForIdleSync();
-    }
-
-    protected void signIn(final Account account) {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                SigninManager.get(mContext).signIn(account, null, null);
-            }
-        });
-        SyncTestUtil.waitForSyncActive();
-        SyncTestUtil.triggerSyncAndWaitForCompletion();
-        assertEquals(account, SigninTestUtil.getCurrentAccount());
-    }
-
-    protected void signOut() throws InterruptedException {
-        final Semaphore s = new Semaphore(0);
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                SigninManager.get(mContext).signOut(new Runnable() {
-                    @Override
-                    public void run() {
-                        s.release();
-                    }
-                });
-            }
-        });
-        assertTrue(s.tryAcquire(SyncTestUtil.TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertNull(SigninTestUtil.getCurrentAccount());
-        assertFalse(SyncTestUtil.isSyncRequested());
-    }
-
-    protected void clearServerData() {
-        mFakeServerHelper.clearServerData();
-        SyncTestUtil.triggerSync();
-        CriteriaHelper.pollUiThread(new Criteria("Timed out waiting for sync to stop.") {
-            @Override
-            public boolean isSatisfied() {
-                return !ProfileSyncService.get().isSyncRequested();
-            }
-        }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
-    }
-
-    protected void disableDataType(final int modelType) {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                Set<Integer> preferredTypes = mProfileSyncService.getPreferredDataTypes();
-                preferredTypes.retainAll(USER_SELECTABLE_TYPES);
-                preferredTypes.remove(modelType);
-                mProfileSyncService.setPreferredDataTypes(false, preferredTypes);
-            }
-        });
-    }
-
-    protected void pollInstrumentationThread(Criteria criteria) {
-        CriteriaHelper.pollInstrumentationThread(
-                criteria, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
-    }
-}
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
new file mode 100644
index 0000000..058b832
--- /dev/null
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
@@ -0,0 +1,276 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.sync;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.Assert;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.identity.UniqueIdentificationGenerator;
+import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory;
+import org.chromium.chrome.browser.identity.UuidBasedUniqueIdentificationGenerator;
+import org.chromium.chrome.browser.signin.SigninManager;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.util.ApplicationTestUtils;
+import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
+import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
+import org.chromium.components.sync.AndroidSyncSettings;
+import org.chromium.components.sync.ModelType;
+import org.chromium.components.sync.test.util.MockSyncContentResolverDelegate;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * TestRule for common functionality between sync tests.
+ */
+public class SyncTestRule extends ChromeActivityTestRule<ChromeActivity> {
+    private static final String TAG = "SyncTestBase";
+
+    private static final String CLIENT_ID = "Client_ID";
+
+    private static final Set<Integer> USER_SELECTABLE_TYPES =
+            new HashSet<Integer>(Arrays.asList(new Integer[] {
+                    ModelType.AUTOFILL, ModelType.BOOKMARKS, ModelType.PASSWORDS,
+                    ModelType.PREFERENCES, ModelType.PROXY_TABS, ModelType.TYPED_URLS,
+            }));
+
+    public abstract static class DataCriteria<T> extends Criteria {
+        public DataCriteria() {
+            super("Sync data criteria not met.");
+        }
+
+        public abstract boolean isSatisfied(List<T> data);
+
+        public abstract List<T> getData() throws Exception;
+
+        @Override
+        public boolean isSatisfied() {
+            try {
+                return isSatisfied(getData());
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private Context mContext;
+    private FakeServerHelper mFakeServerHelper;
+    private ProfileSyncService mProfileSyncService;
+    private MockSyncContentResolverDelegate mSyncContentResolver;
+
+    public SyncTestRule() {
+        super(ChromeActivity.class);
+    }
+
+    /**Getters for Test variables */
+    public Context getTargetContext() {
+        return mContext;
+    }
+
+    public FakeServerHelper getFakeServerHelper() {
+        return mFakeServerHelper;
+    }
+
+    public ProfileSyncService getProfileSyncService() {
+        return mProfileSyncService;
+    }
+
+    public MockSyncContentResolverDelegate getSyncContentResolver() {
+        return mSyncContentResolver;
+    }
+
+    public void startMainActivityForSyncTest() throws Exception {
+        // Start the activity by opening about:blank. This URL is ideal because it is not synced as
+        // a typed URL. If another URL is used, it could interfere with test data.
+        startMainActivityOnBlankPage();
+    }
+
+    private void setUpMockAndroidSyncSettings() {
+        mSyncContentResolver = new MockSyncContentResolverDelegate();
+        mSyncContentResolver.setMasterSyncAutomatically(true);
+        AndroidSyncSettings.overrideForTests(mContext, mSyncContentResolver);
+    }
+
+    public Account setUpTestAccount() {
+        Account account = SigninTestUtil.addTestAccount();
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
+        return account;
+    }
+
+    public Account setUpTestAccountAndSignIn() {
+        Account account = setUpTestAccount();
+        signIn(account);
+        return account;
+    }
+
+    public void startSync() {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mProfileSyncService.requestStart();
+            }
+        });
+    }
+
+    public void startSyncAndWait() {
+        startSync();
+        SyncTestUtil.waitForSyncActive();
+    }
+
+    public void stopSync() {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mProfileSyncService.requestStop();
+            }
+        });
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+
+    public void signIn(final Account account) {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                SigninManager.get(mContext).signIn(account, null, null);
+            }
+        });
+        SyncTestUtil.waitForSyncActive();
+        SyncTestUtil.triggerSyncAndWaitForCompletion();
+        Assert.assertEquals(account, SigninTestUtil.getCurrentAccount());
+    }
+
+    public void signOut() throws InterruptedException {
+        final Semaphore s = new Semaphore(0);
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                SigninManager.get(mContext).signOut(new Runnable() {
+                    @Override
+                    public void run() {
+                        s.release();
+                    }
+                });
+            }
+        });
+        Assert.assertTrue(s.tryAcquire(SyncTestUtil.TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertNull(SigninTestUtil.getCurrentAccount());
+        Assert.assertFalse(SyncTestUtil.isSyncRequested());
+    }
+
+    public void clearServerData() {
+        mFakeServerHelper.clearServerData();
+        SyncTestUtil.triggerSync();
+        CriteriaHelper.pollUiThread(new Criteria("Timed out waiting for sync to stop.") {
+            @Override
+            public boolean isSatisfied() {
+                return !ProfileSyncService.get().isSyncRequested();
+            }
+        }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
+    }
+
+    public void disableDataType(final int modelType) {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                Set<Integer> preferredTypes = mProfileSyncService.getPreferredDataTypes();
+                preferredTypes.retainAll(USER_SELECTABLE_TYPES);
+                preferredTypes.remove(modelType);
+                mProfileSyncService.setPreferredDataTypes(false, preferredTypes);
+            }
+        });
+    }
+
+    public void pollInstrumentationThread(Criteria criteria) {
+        CriteriaHelper.pollInstrumentationThread(
+                criteria, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
+    }
+
+    @Override
+    public Statement apply(final Statement statement, final Description desc) {
+        final Statement base = super.apply(new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                startMainActivityForSyncTest();
+                mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+                setUpMockAndroidSyncSettings();
+
+                ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+                    @Override
+                    public void run() {
+                        // Ensure SyncController is registered with the new AndroidSyncSettings.
+                        AndroidSyncSettings.registerObserver(
+                                mContext, SyncController.get(mContext));
+                        mFakeServerHelper = FakeServerHelper.get();
+                    }
+                });
+                FakeServerHelper.useFakeServer(mContext);
+                ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+                    @Override
+                    public void run() {
+                        mProfileSyncService = ProfileSyncService.get();
+                    }
+                });
+
+                UniqueIdentificationGeneratorFactory.registerGenerator(
+                        UuidBasedUniqueIdentificationGenerator.GENERATOR_ID,
+                        new UniqueIdentificationGenerator() {
+                            @Override
+                            public String getUniqueId(String salt) {
+                                return CLIENT_ID;
+                            }
+                        }, true);
+                statement.evaluate();
+            }
+        }, desc);
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                ruleSetUp();
+                base.evaluate();
+                ruleTearDown();
+            }
+        };
+    }
+
+    private void ruleSetUp() throws Throwable {
+        // This must be called before doing anything with the SharedPreferences because
+        // ChromeActivityTestRule's setUp normally wipes them clean between runs.
+        // Setting a SharedPreference here via the SigninTestUtil.setUpAuthForTest() call below
+        // causes Android to cache them before the files get cleared, meaning that a data clear
+        // is useless and test runs influence each other.
+        ApplicationTestUtils.clearAppData(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
+
+        // This must be called before super.setUp() in order for test authentication to work.
+        SigninTestUtil.setUpAuthForTest(InstrumentationRegistry.getInstrumentation());
+    }
+
+    private void ruleTearDown() throws Exception {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mProfileSyncService.requestStop();
+                FakeServerHelper.deleteFakeServer();
+            }
+        });
+        SigninTestUtil.resetSigninState();
+        SigninTestUtil.tearDownAuthForTest();
+    }
+
+}
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java
index fcda49e..1b72b379 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java
@@ -9,11 +9,20 @@
 
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
 import org.chromium.components.sync.ModelType;
 import org.chromium.components.sync.protocol.EntitySpecifics;
@@ -31,8 +40,16 @@
 /**
  * Test suite for the typed URLs sync data type.
  */
-@RetryOnFailure  // crbug.com/637448
-public class TypedUrlsTest extends SyncTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+@RetryOnFailure // crbug.com/637448
+public class TypedUrlsTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String TAG = "TypedUrlsTest";
 
     private static final String TYPED_URLS_TYPE = "Typed URLs";
@@ -53,10 +70,9 @@
         }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        setUpTestAccountAndSignIn();
+    @Before
+    public void setUp() throws Exception {
+        mSyncTestRule.setUpTestAccountAndSignIn();
         // Make sure the initial state is clean.
         assertClientTypedUrlCount(0);
         assertServerTypedUrlCountWithName(0, URL);
@@ -67,6 +83,7 @@
     @LargeTest
     @Feature({"Sync"})
     */
+    @Test
     @FlakyTest(message = "https://crbug.com/592437")
     public void testUploadTypedUrl() {
         loadUrlByTyping(URL);
@@ -75,6 +92,7 @@
     }
 
     // Test syncing a typed URL from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadTypedUrl() throws Exception {
@@ -84,13 +102,14 @@
 
         // Verify data synced to client.
         List<TypedUrl> typedUrls = getClientTypedUrls();
-        assertEquals("Only the injected typed URL should exist on the client.",
-                1, typedUrls.size());
+        Assert.assertEquals(
+                "Only the injected typed URL should exist on the client.", 1, typedUrls.size());
         TypedUrl typedUrl = typedUrls.get(0);
-        assertEquals("The wrong URL was found for the typed URL.", URL, typedUrl.url);
+        Assert.assertEquals("The wrong URL was found for the typed URL.", URL, typedUrl.url);
     }
 
     // Test syncing a typed URL deletion from server to client.
+    @Test
     @LargeTest
     @Feature({"Sync"})
     public void testDownloadDeletedTypedUrl() throws Exception {
@@ -101,7 +120,7 @@
 
         // Delete on server, sync, and verify deleted locally.
         TypedUrl typedUrl = getClientTypedUrls().get(0);
-        mFakeServerHelper.deleteEntity(typedUrl.id);
+        mSyncTestRule.getFakeServerHelper().deleteEntity(typedUrl.id);
         SyncTestUtil.triggerSync();
         waitForClientTypedUrlCount(0);
     }
@@ -111,7 +130,7 @@
             @Override
             public void run() {
                 LoadUrlParams params = new LoadUrlParams(url, PageTransition.TYPED);
-                getActivity().getActivityTab().loadUrl(params);
+                mSyncTestRule.getActivity().getActivityTab().loadUrl(params);
             }
         });
     }
@@ -123,12 +142,12 @@
         specifics.typedUrl.title = url;
         specifics.typedUrl.visits = new long[]{1L};
         specifics.typedUrl.visitTransitions = new int[]{SyncEnums.TYPED};
-        mFakeServerHelper.injectUniqueClientEntity(url /* name */, specifics);
+        mSyncTestRule.getFakeServerHelper().injectUniqueClientEntity(url /* name */, specifics);
     }
 
     private List<TypedUrl> getClientTypedUrls() throws JSONException {
-        List<Pair<String, JSONObject>> rawTypedUrls = SyncTestUtil.getLocalData(
-                mContext, TYPED_URLS_TYPE);
+        List<Pair<String, JSONObject>> rawTypedUrls =
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), TYPED_URLS_TYPE);
         List<TypedUrl> typedUrls = new ArrayList<TypedUrl>(rawTypedUrls.size());
         for (Pair<String, JSONObject> rawTypedUrl : rawTypedUrls) {
             String id =  rawTypedUrl.first;
@@ -138,13 +157,14 @@
     }
 
     private void assertClientTypedUrlCount(int count) throws JSONException {
-        assertEquals("There should be " + count + " local typed URL entities.",
-                count, SyncTestUtil.getLocalData(mContext, TYPED_URLS_TYPE).size());
+        Assert.assertEquals("There should be " + count + " local typed URL entities.", count,
+                SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), TYPED_URLS_TYPE)
+                        .size());
     }
 
     private void assertServerTypedUrlCountWithName(int count, String name) {
-        assertTrue("Expected " + count + " server typed URLs with name " + name + ".",
-                mFakeServerHelper.verifyEntityCountByTypeAndName(
+        Assert.assertTrue("Expected " + count + " server typed URLs with name " + name + ".",
+                mSyncTestRule.getFakeServerHelper().verifyEntityCountByTypeAndName(
                         count, ModelType.TYPED_URLS, name));
     }
 
@@ -152,7 +172,8 @@
         CriteriaHelper.pollInstrumentationThread(Criteria.equals(count, new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return SyncTestUtil.getLocalData(mContext, TYPED_URLS_TYPE).size();
+                return SyncTestUtil.getLocalData(mSyncTestRule.getTargetContext(), TYPED_URLS_TYPE)
+                        .size();
             }
         }), SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
     }
@@ -163,7 +184,7 @@
             @Override
             public boolean isSatisfied() {
                 try {
-                    return mFakeServerHelper.verifyEntityCountByTypeAndName(
+                    return mSyncTestRule.getFakeServerHelper().verifyEntityCountByTypeAndName(
                             count, ModelType.TYPED_URLS, name);
                 } catch (Exception e) {
                     throw new RuntimeException(e);
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java
index 97ffc07..0c641b52 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java
@@ -4,22 +4,40 @@
 
 package org.chromium.chrome.browser.sync.ui;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.widget.CheckedTextView;
 import android.widget.ListView;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.sync.SyncTestBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.sync.SyncTestRule;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.sync.PassphraseType;
 
 /**
  * Tests to make sure that PassphraseTypeDialogFragment presents the correct options.
  */
-@RetryOnFailure  // crbug.com/637448
-public class PassphraseTypeDialogFragmentTest extends SyncTestBase {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+@RetryOnFailure // crbug.com/637448
+public class PassphraseTypeDialogFragmentTest {
+    @Rule
+    public SyncTestRule mSyncTestRule = new SyncTestRule();
+
     private static final String TAG = "PassphraseTypeDialogFragmentTest";
 
     private static final boolean ENABLED = true;
@@ -40,6 +58,7 @@
 
     private PassphraseTypeDialogFragment mTypeFragment;
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testKeystoreEncryptionOptions() throws Exception {
@@ -49,6 +68,7 @@
                 new TypeOptions(PassphraseType.KEYSTORE_PASSPHRASE, ENABLED, CHECKED));
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testCustomEncryptionOptions() throws Exception {
@@ -62,6 +82,7 @@
      * @SmallTest
      * @Feature({"Sync"})
      */
+    @Test
     @FlakyTest(message = "crbug.com/588050")
     public void testFrozenImplicitEncryptionOptions() throws Exception {
         createFragment(PassphraseType.FROZEN_IMPLICIT_PASSPHRASE, true);
@@ -70,6 +91,7 @@
                 new TypeOptions(PassphraseType.KEYSTORE_PASSPHRASE, DISABLED, UNCHECKED));
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testImplicitEncryptionOptions() throws Exception {
@@ -79,6 +101,7 @@
                 new TypeOptions(PassphraseType.IMPLICIT_PASSPHRASE, ENABLED, CHECKED));
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testKeystoreEncryptionOptionsEncryptEverythingDisallowed() throws Exception {
@@ -88,6 +111,7 @@
                 new TypeOptions(PassphraseType.KEYSTORE_PASSPHRASE, ENABLED, CHECKED));
     }
 
+    @Test
     @SmallTest
     @Feature({"Sync"})
     public void testImplicitEncryptionOptionsEncryptEverythingDisallowed() throws Exception {
@@ -99,25 +123,27 @@
 
     public void createFragment(PassphraseType type, boolean isEncryptEverythingAllowed) {
         mTypeFragment = PassphraseTypeDialogFragment.create(type, 0, isEncryptEverythingAllowed);
-        mTypeFragment.show(getActivity().getFragmentManager(), TAG);
-        getInstrumentation().waitForIdleSync();
+        mTypeFragment.show(mSyncTestRule.getActivity().getFragmentManager(), TAG);
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     public void assertPassphraseTypeOptions(TypeOptions... optionsList) {
         ListView listView =
                 (ListView) mTypeFragment.getDialog().findViewById(R.id.passphrase_type_list);
-        assertEquals("Number of options doesn't match.", optionsList.length, listView.getCount());
+        Assert.assertEquals(
+                "Number of options doesn't match.", optionsList.length, listView.getCount());
         PassphraseTypeDialogFragment.Adapter adapter =
                 (PassphraseTypeDialogFragment.Adapter) listView.getAdapter();
 
         for (int i = 0; i < optionsList.length; i++) {
             TypeOptions options = optionsList[i];
-            assertEquals("Option " + i + " type is wrong.", options.type, adapter.getType(i));
+            Assert.assertEquals(
+                    "Option " + i + " type is wrong.", options.type, adapter.getType(i));
             CheckedTextView checkedView = (CheckedTextView) listView.getChildAt(i);
-            assertEquals("Option " + i + " enabled state is wrong.",
-                    options.isEnabled, checkedView.isEnabled());
-            assertEquals("Option " + i + " checked state is wrong.",
-                    options.isChecked, checkedView.isChecked());
+            Assert.assertEquals("Option " + i + " enabled state is wrong.", options.isEnabled,
+                    checkedView.isEnabled());
+            Assert.assertEquals("Option " + i + " checked state is wrong.", options.isChecked,
+                    checkedView.isChecked());
         }
     }
 }
diff --git a/chrome/app/theme/chromium/BRANDING b/chrome/app/theme/chromium/BRANDING
index 6a6bc26..4f9ef78 100644
--- a/chrome/app/theme/chromium/BRANDING
+++ b/chrome/app/theme/chromium/BRANDING
@@ -4,6 +4,6 @@
 PRODUCT_SHORTNAME=Chromium
 PRODUCT_INSTALLER_FULLNAME=Chromium Installer
 PRODUCT_INSTALLER_SHORTNAME=Chromium Installer
-COPYRIGHT=Copyright 2016 The Chromium Authors. All rights reserved.
+COPYRIGHT=Copyright 2017 The Chromium Authors. All rights reserved.
 MAC_BUNDLE_ID=org.chromium.Chromium
 MAC_CREATOR_CODE=Cr24
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_app_launcher_browsertest.cc b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher_browsertest.cc
index c899244..94f9f24 100644
--- a/chrome/browser/chromeos/login/demo_mode/demo_app_launcher_browsertest.cc
+++ b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher_browsertest.cc
@@ -54,7 +54,7 @@
 
 bool VerifyNetworksDisabled() {
   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
-  return !handler->DefaultNetwork();
+  return !handler->FirstNetworkByType(NetworkTypePattern::NonVirtual());
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc
index 1fa0ed94..42795a1 100644
--- a/chrome/browser/chromeos/tether/tether_service.cc
+++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/chromeos/tether/tether_service_factory.h"
 #include "chrome/browser/cryptauth/chrome_cryptauth_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
@@ -159,7 +158,6 @@
   PA_LOG(INFO) << "Starting up Tether component.";
   initializer_ = chromeos::tether::InitializerImpl::Factory::NewInstance(
       cryptauth_service_, notification_presenter_.get(), profile_->GetPrefs(),
-      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_),
       network_state_handler_,
       chromeos::NetworkHandler::Get()->managed_network_configuration_handler(),
       chromeos::NetworkConnect::Get(),
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc
index 402d4a8..47ab232 100644
--- a/chrome/browser/chromeos/tether/tether_service_unittest.cc
+++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -157,7 +157,6 @@
       cryptauth::CryptAuthService* cryptauth_service,
       chromeos::tether::NotificationPresenter* notification_presenter,
       PrefService* pref_service,
-      ProfileOAuth2TokenService* token_service,
       chromeos::NetworkStateHandler* network_state_handler,
       chromeos::ManagedNetworkConfigurationHandler*
           managed_network_configuration_handler,
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
index 05d9cbb..b62c6f5f 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
@@ -31,9 +31,7 @@
 #include "chromeos/network/managed_network_configuration_handler.h"
 #include "chromeos/network/network_certificate_handler.h"
 #include "chromeos/network/network_handler.h"
-#include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
-#include "chromeos/network/network_type_pattern.h"
 #include "chromeos/network/onc/onc_utils.h"
 #include "chromeos/network/portal_detector/network_portal_detector.h"
 #include "components/onc/onc_constants.h"
@@ -627,27 +625,6 @@
   EXPECT_TRUE(RunNetworkingSubtest("getPropertiesCellular")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest,
-                       GetCellularPropertiesDefault) {
-  SetupCellular();
-  const chromeos::NetworkState* cellular =
-      chromeos::NetworkHandler::Get()
-          ->network_state_handler()
-          ->FirstNetworkByType(chromeos::NetworkTypePattern::Cellular());
-  ASSERT_TRUE(cellular);
-  std::string cellular_guid = std::string(kCellular1ServicePath) + "_guid";
-  EXPECT_EQ(cellular_guid, cellular->guid());
-  // Remove the Cellular service. This should create a default Cellular network.
-  service_test_->RemoveService(kCellular1ServicePath);
-  content::RunAllPendingInMessageLoop();
-  cellular = chromeos::NetworkHandler::Get()
-                 ->network_state_handler()
-                 ->FirstNetworkByType(chromeos::NetworkTypePattern::Cellular());
-  ASSERT_TRUE(cellular);
-  EXPECT_EQ(cellular_guid, cellular->guid());
-  EXPECT_TRUE(RunNetworkingSubtest("getPropertiesCellularDefault")) << message_;
-}
-
 IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, GetState) {
   EXPECT_TRUE(RunNetworkingSubtest("getState")) << message_;
 }
diff --git a/chrome/browser/profiling_host/OWNERS b/chrome/browser/profiling_host/OWNERS
new file mode 100644
index 0000000..9c3ba7e4
--- /dev/null
+++ b/chrome/browser/profiling_host/OWNERS
@@ -0,0 +1,3 @@
+ajwong@chromium.org
+brettw@chromium.org
+erikchen@chromium.org
diff --git a/chrome/common/profiling/OWNERS b/chrome/common/profiling/OWNERS
index 08850f4..46ce22a5 100644
--- a/chrome/common/profiling/OWNERS
+++ b/chrome/common/profiling/OWNERS
@@ -1,2 +1,6 @@
+ajwong@chromium.org
+brettw@chromium.org
+erikchen@chromium.org
+
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/profiling/OWNERS b/chrome/profiling/OWNERS
index 007b552..6d35899 100644
--- a/chrome/profiling/OWNERS
+++ b/chrome/profiling/OWNERS
@@ -1,2 +1,6 @@
+ajwong@chromium.org
+brettw@chromium.org
+erikchen@chromium.org
+
 per-file profiling_manifest.json=set noparent
 per-file profiling_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chrome/profiling/json_exporter.cc b/chrome/profiling/json_exporter.cc
index ddcb6ac..4395f82f 100644
--- a/chrome/profiling/json_exporter.cc
+++ b/chrome/profiling/json_exporter.cc
@@ -276,7 +276,8 @@
       out << ",\n";
     else
       first_time = false;
-    out << cur.first.size;
+    // Output the total size, which is size * count.
+    out << cur.first.size * cur.second;
   }
   out << "]";
 }
diff --git a/chrome/profiling/json_exporter_unittest.cc b/chrome/profiling/json_exporter_unittest.cc
index 3e7ecb7..66a66c3 100644
--- a/chrome/profiling/json_exporter_unittest.cc
+++ b/chrome/profiling/json_exporter_unittest.cc
@@ -375,7 +375,7 @@
   // Validate node allocated with |stack1|.
   EXPECT_EQ(2, counts->GetList()[node1].GetInt());
   EXPECT_EQ(0, types->GetList()[node1].GetInt());
-  EXPECT_EQ(20, sizes->GetList()[node1].GetInt());
+  EXPECT_EQ(40, sizes->GetList()[node1].GetInt());
   EXPECT_EQ(id1, backtraces->GetList()[node1].GetInt());
 
   // Validate node allocated with |stack2|.
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
index 7eae4da..0345f56 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
@@ -278,7 +278,7 @@
         }
 
         try {
-            createdCallback.waitForCallback(0);
+            createdCallback.waitForCallback(null, 0, 1, 10, TimeUnit.SECONDS);
         } catch (TimeoutException e) {
             Assert.fail("Never received tab creation event");
         }
diff --git a/chrome/test/base/memory_tracing_browsertest.cc b/chrome/test/base/memory_tracing_browsertest.cc
index 1e6f550..a8baa6b 100644
--- a/chrome/test/base/memory_tracing_browsertest.cc
+++ b/chrome/test/base/memory_tracing_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/test/base/tracing.h"
 
+#include "base/allocator/features.h"
 #include "base/command_line.h"
 #include "base/location.h"
 #include "base/run_loop.h"
@@ -12,6 +13,7 @@
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/trace_config_memory_test_util.h"
 #include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -67,7 +69,8 @@
 
   void PerformDumpMemoryTestActions(
       const base::trace_event::TraceConfig& trace_config,
-      base::trace_event::MemoryDumpLevelOfDetail explicit_dump_type) {
+      base::trace_event::MemoryDumpLevelOfDetail explicit_dump_type,
+      std::string* json_events) {
     GURL url1("about:blank");
     ui_test_utils::NavigateToURLWithDisposition(
         browser(), url1, WindowOpenDisposition::NEW_FOREGROUND_TAB,
@@ -98,14 +101,13 @@
     ASSERT_NO_FATAL_FAILURE(ExecuteJavascriptOnCurrentTab());
 
     run_loop.Run();
-    std::string json_events;
-    ASSERT_TRUE(EndTracing(&json_events));
+    ASSERT_TRUE(EndTracing(json_events));
 
     if (should_test_memory_dump_success_) {
       // Expect the basic memory dumps to be present in the trace.
-      EXPECT_NE(std::string::npos, json_events.find("process_totals"));
-      EXPECT_NE(std::string::npos, json_events.find("v8"));
-      EXPECT_NE(std::string::npos, json_events.find("blink_gc"));
+      EXPECT_NE(std::string::npos, json_events->find("process_totals"));
+      EXPECT_NE(std::string::npos, json_events->find("v8"));
+      EXPECT_NE(std::string::npos, json_events->find("blink_gc"));
     }
   }
 
@@ -117,11 +119,12 @@
   // is fixed to be called after enable tracing is acked by all processes,
   // crbug.com/709524. The test still tests if dumping does not crash.
   should_test_memory_dump_success_ = false;
+  std::string json_events;
   PerformDumpMemoryTestActions(
       base::trace_event::TraceConfig(
           base::trace_event::TraceConfigMemoryTestUtil::
               GetTraceConfig_EmptyTriggers()),
-      base::trace_event::MemoryDumpLevelOfDetail::DETAILED);
+      base::trace_event::MemoryDumpLevelOfDetail::DETAILED, &json_events);
 }
 
 IN_PROC_BROWSER_TEST_F(MemoryTracingBrowserTest, TestBackgroundMemoryInfra) {
@@ -129,11 +132,57 @@
   // is fixed to be called after enable tracing is acked by all processes,
   // crbug.com/709524. The test still tests if dumping does not crash.
   should_test_memory_dump_success_ = false;
+  std::string json_events;
   PerformDumpMemoryTestActions(
       base::trace_event::TraceConfig(
           base::trace_event::TraceConfigMemoryTestUtil::
               GetTraceConfig_BackgroundTrigger(200)),
-      base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND);
+      base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, &json_events);
 }
 
+#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
+IN_PROC_BROWSER_TEST_F(MemoryTracingBrowserTest, TestHeapProfilingPseudo) {
+  should_test_memory_dump_success_ = true;
+  // TODO(ssid): Enable heap profiling on all processes once the
+  // memory_instrumentation api is available, crbug.com/757747.
+  base::trace_event::MemoryDumpManager::GetInstance()->EnableHeapProfiling(
+      base::trace_event::kHeapProfilingModePseudo);
+  std::string json_events;
+  PerformDumpMemoryTestActions(
+      base::trace_event::TraceConfig(
+          base::trace_event::TraceConfigMemoryTestUtil::
+              GetTraceConfig_PeriodicTriggers(100, 500)),
+      base::trace_event::MemoryDumpLevelOfDetail::DETAILED, &json_events);
+  EXPECT_NE(std::string::npos, json_events.find("stackFrames"));
+  // TODO(ssid): Fix mac and win to get thread names in the allocation context,
+  // crbug.com/764454.
+  EXPECT_NE(std::string::npos, json_events.find("[Thread:"));
+  EXPECT_NE(std::string::npos, json_events.find("MessageLoop::RunTask"));
+  EXPECT_NE(std::string::npos, json_events.find("typeNames"));
+  EXPECT_NE(std::string::npos, json_events.find("content/browser"));
+  EXPECT_NE(std::string::npos, json_events.find("\"malloc\":{\"entries\""));
+}
+
+IN_PROC_BROWSER_TEST_F(MemoryTracingBrowserTest, TestHeapProfilingNoStack) {
+  should_test_memory_dump_success_ = true;
+  // TODO(ssid): Enable heap profiling on all processes once the
+  // memory_instrumentation api is available, crbug.com/757747.
+  base::trace_event::MemoryDumpManager::GetInstance()->EnableHeapProfiling(
+      base::trace_event::kHeapProfilingModeNoStack);
+  std::string json_events;
+  PerformDumpMemoryTestActions(
+      base::trace_event::TraceConfig(
+          base::trace_event::TraceConfigMemoryTestUtil::
+              GetTraceConfig_BackgroundTrigger(200)),
+      base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, &json_events);
+  // LOG(ERROR) << "ssid \n" << json_events;
+  EXPECT_NE(std::string::npos, json_events.find("stackFrames"));
+  EXPECT_NE(std::string::npos, json_events.find("[Thread:"));
+  EXPECT_EQ(std::string::npos, json_events.find("MessageLoop::RunTask"));
+  EXPECT_NE(std::string::npos, json_events.find("typeNames"));
+  EXPECT_NE(std::string::npos, json_events.find("content/browser"));
+  EXPECT_NE(std::string::npos, json_events.find("\"malloc\":{\"entries\""));
+}
+#endif  // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
+
 }  // namespace
diff --git a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
index 2e3254e..0274335 100644
--- a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
+++ b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
@@ -610,40 +610,6 @@
         }, result);
       }));
   },
-  function getPropertiesCellularDefault() {
-    chrome.networkingPrivate.getProperties(
-      kCellularGuid,
-      callbackPass(function(result) {
-        assertEq({
-          Cellular: {
-            AllowRoaming: false,
-            Carrier: 'Cellular1_Carrier',
-            ESN: "test_esn",
-            Family: 'GSM',
-            HomeProvider: {
-              Code: '000000',
-              Country: 'us',
-              Name: 'Cellular1_Provider'
-            },
-            ICCID: "test_iccid",
-            IMEI: "test_imei",
-            MDN: "test_mdn",
-            MEID: "test_meid",
-            MIN: "test_min",
-            ModelID:"test_model_id",
-            SIMLockStatus: {LockEnabled: true, LockType: '', RetriesLeft: 3},
-            SignalStrength: 0,
-          },
-          Connectable: false,
-          ConnectionState: ConnectionStateType.NOT_CONNECTED,
-          GUID: kCellularGuid,
-          Name: '',
-          Priority: 0,
-          Source: 'None',
-          Type: NetworkType.CELLULAR,
-        }, result);
-      }));
-  },
   function getManagedProperties() {
     chrome.networkingPrivate.getManagedProperties(
       'stub_wifi2',
diff --git a/chrome/test/data/webui/media_router/media_router_elements_browsertest.js b/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
index 423f7d4..9dd68e9c 100644
--- a/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
+++ b/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
@@ -152,8 +152,14 @@
   mocha.run();
 });
 
+// This test is flaky on Windows. See https://crbug.com/760288.
+GEN('#if defined(OS_WIN)');
+GEN('#define MAYBE_MediaRouterContainerSearch DISABLED_MediaRouterContainerSearch');
+GEN('#else');
+GEN('#define MAYBE_MediaRouterContainerSearch MediaRouterContainerSearch');
+GEN('#endif');
 TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerSearch',
+    'MAYBE_MediaRouterContainerSearch',
     function() {
   media_router_container_search.registerTests();
   mocha.run();
diff --git a/chrome/test/mini_installer/variable_expander.py b/chrome/test/mini_installer/variable_expander.py
index 28f6ef1..dc90e3e 100644
--- a/chrome/test/mini_installer/variable_expander.py
+++ b/chrome/test/mini_installer/variable_expander.py
@@ -119,7 +119,8 @@
         'NEXT_VERSION_MINI_INSTALLER': next_version_mini_installer_abspath,
         'NEXT_VERSION_MINI_INSTALLER_FILE_VERSION': _GetFileVersion(
             next_version_mini_installer_abspath),
-        'PROGRAM_FILES': shell.SHGetFolderPath(0, shellcon.CSIDL_PROGRAM_FILES,
+        'PROGRAM_FILES': shell.SHGetFolderPath(0,
+                                               shellcon.CSIDL_PROGRAM_FILESX86,
                                                None, 0),
         'USER_SPECIFIC_REGISTRY_SUFFIX': _GetUserSpecificRegistrySuffix(),
         'VERSION_SERVER_2003': '(5, 2)',
diff --git a/chromecast/browser/devtools/cast_devtools_manager_delegate.cc b/chromecast/browser/devtools/cast_devtools_manager_delegate.cc
index 0323633..0800bb7 100644
--- a/chromecast/browser/devtools/cast_devtools_manager_delegate.cc
+++ b/chromecast/browser/devtools/cast_devtools_manager_delegate.cc
@@ -67,9 +67,5 @@
 #endif
 }
 
-bool CastDevToolsManagerDelegate::IsBrowserTargetDiscoverable() {
-  return true;
-}
-
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/browser/devtools/cast_devtools_manager_delegate.h b/chromecast/browser/devtools/cast_devtools_manager_delegate.h
index e3599df..113bb80 100644
--- a/chromecast/browser/devtools/cast_devtools_manager_delegate.h
+++ b/chromecast/browser/devtools/cast_devtools_manager_delegate.h
@@ -34,7 +34,6 @@
   // content::DevToolsManagerDelegate implementation.
   content::DevToolsAgentHost::List RemoteDebuggingTargets() override;
   std::string GetDiscoveryPageHTML() override;
-  bool IsBrowserTargetDiscoverable() override;
 
  private:
   std::unordered_set<content::WebContents*> enabled_webcontents_;
diff --git a/chromecast/browser/devtools/remote_debugging_server.cc b/chromecast/browser/devtools/remote_debugging_server.cc
index 9a685219..d088012 100644
--- a/chromecast/browser/devtools/remote_debugging_server.cc
+++ b/chromecast/browser/devtools/remote_debugging_server.cc
@@ -174,6 +174,10 @@
   dev_tools_delegate->DisableWebContentsForDebugging(web_contents);
 
   if (is_started_ && !dev_tools_delegate->HasEnabledWebContents()) {
+    // TODO(seantopping): The debugging server goes down temporarily when there
+    // are no active apps. This can sometimes break in-progress traces. Find a
+    // fix for this.
+    LOG(INFO) << "Stopping Devtools server.";
     content::DevToolsAgentHost::StopRemoteDebuggingServer();
     is_started_ = false;
   }
diff --git a/chromecast/tools/tracinglib.py b/chromecast/tools/tracinglib.py
index ed5b686b..5f96f91 100644
--- a/chromecast/tools/tracinglib.py
+++ b/chromecast/tools/tracinglib.py
@@ -8,6 +8,7 @@
 import json
 import logging
 import math
+import requests
 import subprocess
 import time
 import websocket
@@ -44,7 +45,10 @@
   def Connect(self):
     """Connect to cast_shell."""
     assert not self._socket
-    url = 'ws://%s:%i/devtools/browser' % (self._device_ip, self._devtools_port)
+    # Get the secure browser debugging target.
+    r = requests.get(
+        'http://%s:%i/json/version' % (self._device_ip, self._devtools_port))
+    url = r.json()['webSocketDebuggerUrl']
     print('Connect to %s ...' % url)
     self._socket = websocket.create_connection(url, timeout=self._timeout)
     self._next_request_id = 0
diff --git a/chromeos/components/tether/initializer_impl.cc b/chromeos/components/tether/initializer_impl.cc
index 35baf49..cd2d35e 100644
--- a/chromeos/components/tether/initializer_impl.cc
+++ b/chromeos/components/tether/initializer_impl.cc
@@ -64,7 +64,6 @@
     cryptauth::CryptAuthService* cryptauth_service,
     NotificationPresenter* notification_presenter,
     PrefService* pref_service,
-    ProfileOAuth2TokenService* token_service,
     NetworkStateHandler* network_state_handler,
     ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
     NetworkConnect* network_connect,
@@ -74,7 +73,7 @@
     factory_instance_ = new Factory();
   }
   return factory_instance_->BuildInstance(
-      cryptauth_service, notification_presenter, pref_service, token_service,
+      cryptauth_service, notification_presenter, pref_service,
       network_state_handler, managed_network_configuration_handler,
       network_connect, network_connection_handler, adapter);
 }
@@ -96,14 +95,13 @@
     cryptauth::CryptAuthService* cryptauth_service,
     NotificationPresenter* notification_presenter,
     PrefService* pref_service,
-    ProfileOAuth2TokenService* token_service,
     NetworkStateHandler* network_state_handler,
     ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
     NetworkConnect* network_connect,
     NetworkConnectionHandler* network_connection_handler,
     scoped_refptr<device::BluetoothAdapter> adapter) {
   return base::WrapUnique(new InitializerImpl(
-      cryptauth_service, notification_presenter, pref_service, token_service,
+      cryptauth_service, notification_presenter, pref_service,
       network_state_handler, managed_network_configuration_handler,
       network_connect, network_connection_handler, adapter));
 }
@@ -112,7 +110,6 @@
     cryptauth::CryptAuthService* cryptauth_service,
     NotificationPresenter* notification_presenter,
     PrefService* pref_service,
-    ProfileOAuth2TokenService* token_service,
     NetworkStateHandler* network_state_handler,
     ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
     NetworkConnect* network_connect,
@@ -121,7 +118,6 @@
     : cryptauth_service_(cryptauth_service),
       notification_presenter_(notification_presenter),
       pref_service_(pref_service),
-      token_service_(token_service),
       network_state_handler_(network_state_handler),
       managed_network_configuration_handler_(
           managed_network_configuration_handler),
@@ -129,20 +125,10 @@
       network_connection_handler_(network_connection_handler),
       adapter_(adapter),
       weak_ptr_factory_(this) {
-  if (!token_service_->RefreshTokenIsAvailable(
-          cryptauth_service_->GetAccountId())) {
-    PA_LOG(INFO) << "Refresh token not yet available; "
-                 << "waiting for valid token to initializing tether feature.";
-    token_service_->AddObserver(this);
-    return;
-  }
-
-  PA_LOG(INFO) << "Refresh token is available; initializing tether feature.";
   CreateComponent();
 }
 
 InitializerImpl::~InitializerImpl() {
-  token_service_->RemoveObserver(this);
   network_state_handler_->set_tether_sort_delegate(nullptr);
 
   if (disconnect_tethering_request_sender_)
@@ -187,20 +173,6 @@
   StartAsynchronousShutdown();
 }
 
-void InitializerImpl::OnRefreshTokensLoaded() {
-  if (!token_service_->RefreshTokenIsAvailable(
-          cryptauth_service_->GetAccountId())) {
-    // If a token for the active account is still not available, continue
-    // waiting for a new token.
-    return;
-  }
-
-  PA_LOG(INFO) << "Refresh token has loaded; initializing tether feature.";
-
-  token_service_->RemoveObserver(this);
-  CreateComponent();
-}
-
 void InitializerImpl::OnPendingDisconnectRequestsComplete() {
   DCHECK(status() == Initializer::Status::SHUTTING_DOWN);
   disconnect_tethering_request_sender_->RemoveObserver(this);
@@ -217,9 +189,6 @@
 }
 
 void InitializerImpl::CreateComponent() {
-  PA_LOG(INFO) << "Successfully set Bluetooth advertisement interval. "
-               << "Initializing tether feature.";
-
   network_list_sorter_ = base::MakeUnique<NetworkListSorter>();
   network_state_handler_->set_tether_sort_delegate(network_list_sorter_.get());
   tether_host_fetcher_ =
diff --git a/chromeos/components/tether/initializer_impl.h b/chromeos/components/tether/initializer_impl.h
index b6f461e..2322db9 100644
--- a/chromeos/components/tether/initializer_impl.h
+++ b/chromeos/components/tether/initializer_impl.h
@@ -15,7 +15,6 @@
 #include "chromeos/components/tether/disconnect_tethering_request_sender.h"
 #include "chromeos/components/tether/initializer.h"
 #include "components/prefs/pref_registry_simple.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_advertisement.h"
 
@@ -64,7 +63,6 @@
 
 // Initializes the Tether Chrome OS component.
 class InitializerImpl : public Initializer,
-                        public OAuth2TokenService::Observer,
                         public DisconnectTetheringRequestSender::Observer {
  public:
   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
@@ -75,7 +73,6 @@
         cryptauth::CryptAuthService* cryptauth_service,
         NotificationPresenter* notification_presenter,
         PrefService* pref_service,
-        ProfileOAuth2TokenService* token_service,
         NetworkStateHandler* network_state_handler,
         ManagedNetworkConfigurationHandler*
             managed_network_configuration_handler,
@@ -90,7 +87,6 @@
         cryptauth::CryptAuthService* cryptauth_service,
         NotificationPresenter* notification_presenter,
         PrefService* pref_service,
-        ProfileOAuth2TokenService* token_service,
         NetworkStateHandler* network_state_handler,
         ManagedNetworkConfigurationHandler*
             managed_network_configuration_handler,
@@ -106,7 +102,6 @@
       cryptauth::CryptAuthService* cryptauth_service,
       NotificationPresenter* notification_presenter,
       PrefService* pref_service,
-      ProfileOAuth2TokenService* token_service,
       NetworkStateHandler* network_state_handler,
       ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
       NetworkConnect* network_connect,
@@ -118,9 +113,6 @@
   // Initializer:
   void RequestShutdown() override;
 
-  // OAuth2TokenService::Observer:
-  void OnRefreshTokensLoaded() override;
-
   // DisconnectTetheringRequestSender::Observer:
   void OnPendingDisconnectRequestsComplete() override;
 
@@ -134,7 +126,6 @@
   cryptauth::CryptAuthService* cryptauth_service_;
   NotificationPresenter* notification_presenter_;
   PrefService* pref_service_;
-  ProfileOAuth2TokenService* token_service_;
   NetworkStateHandler* network_state_handler_;
   ManagedNetworkConfigurationHandler* managed_network_configuration_handler_;
   NetworkConnect* network_connect_;
diff --git a/chromeos/components/tether/initializer_impl_unittest.cc b/chromeos/components/tether/initializer_impl_unittest.cc
index c683af9..a8045dc 100644
--- a/chromeos/components/tether/initializer_impl_unittest.cc
+++ b/chromeos/components/tether/initializer_impl_unittest.cc
@@ -27,7 +27,6 @@
 #include "components/cryptauth/proto/cryptauth_api.pb.h"
 #include "components/cryptauth/secure_message_delegate.h"
 #include "components/prefs/testing_pref_service.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -142,14 +141,13 @@
       cryptauth::CryptAuthService* cryptauth_service,
       NotificationPresenter* notification_presenter,
       PrefService* pref_service,
-      ProfileOAuth2TokenService* token_service,
       NetworkStateHandler* network_state_handler,
       ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
       NetworkConnect* network_connect,
       NetworkConnectionHandler* network_connection_handler,
       scoped_refptr<device::BluetoothAdapter> adapter) {
     Initializer* initializer = new InitializerImpl(
-        cryptauth_service, notification_presenter, pref_service, token_service,
+        cryptauth_service, notification_presenter, pref_service,
         network_state_handler, managed_network_configuration_handler,
         network_connect, network_connection_handler, adapter);
     delete initializer;
@@ -193,9 +191,6 @@
   std::unique_ptr<TestingPrefServiceSimple> test_pref_service =
       base::MakeUnique<TestingPrefServiceSimple>();
 
-  std::unique_ptr<FakeProfileOAuth2TokenService> fake_token_service =
-      base::MakeUnique<FakeProfileOAuth2TokenService>();
-
   std::unique_ptr<ManagedNetworkConfigurationHandler>
       managed_network_configuration_handler = base::WrapUnique(
           new NiceMock<MockManagedNetworkConfigurationHandler>);
@@ -214,10 +209,9 @@
   // InitializerTest only applies to the class itself, not these test functions.
   InitializeAndDestroy(
       fake_cryptauth_service.get(), fake_notification_presenter.get(),
-      test_pref_service_.get(), fake_token_service.get(),
-      network_state_handler(), managed_network_configuration_handler.get(),
-      mock_network_connect.get(), network_connection_handler_.get(),
-      mock_adapter);
+      test_pref_service_.get(), network_state_handler(),
+      managed_network_configuration_handler.get(), mock_network_connect.get(),
+      network_connection_handler_.get(), mock_adapter);
 }
 
 }  // namespace tether
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc
index d55642a..a9c8eca 100644
--- a/chromeos/dbus/fake_shill_manager_client.cc
+++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -789,15 +789,16 @@
       state = shill::kStateOnline;
     }
     AddTechnology(shill::kTypeCellular, enabled);
-    devices->AddDevice("/device/cellular1", shill::kTypeCellular,
-                       "stub_cellular_device1");
+    devices->AddDevice(
+        "/device/cellular1", shill::kTypeCellular, "stub_cellular_device1");
     devices->SetDeviceProperty("/device/cellular1", shill::kCarrierProperty,
                                base::Value(shill::kCarrierSprint));
     base::ListValue carrier_list;
     carrier_list.AppendString(shill::kCarrierSprint);
     carrier_list.AppendString(shill::kCarrierGenericUMTS);
     devices->SetDeviceProperty("/device/cellular1",
-                               shill::kSupportedCarriersProperty, carrier_list);
+                               shill::kSupportedCarriersProperty,
+                               carrier_list);
     if (roaming_state_ == kRoamingRequired) {
       devices->SetDeviceProperty("/device/cellular1",
                                  shill::kProviderRequiresRoamingProperty,
@@ -812,66 +813,66 @@
       devices->SetSimLocked("/device/cellular1", false);
     }
 
-    if (state != shill::kStateIdle) {
-      services->AddService(kCellularServicePath, "cellular1_guid",
-                           "cellular1" /* name */, shill::kTypeCellular, state,
-                           add_to_visible);
-      base::Value technology_value(cellular_technology_);
-      devices->SetDeviceProperty("/device/cellular1",
-                                 shill::kTechnologyFamilyProperty,
+    services->AddService(kCellularServicePath,
+                         "cellular1_guid",
+                         "cellular1" /* name */,
+                         shill::kTypeCellular,
+                         state,
+                         add_to_visible);
+    base::Value technology_value(cellular_technology_);
+    devices->SetDeviceProperty("/device/cellular1",
+                               shill::kTechnologyFamilyProperty,
+                               technology_value);
+    services->SetServiceProperty(kCellularServicePath,
+                                 shill::kNetworkTechnologyProperty,
                                  technology_value);
-      services->SetServiceProperty(kCellularServicePath,
-                                   shill::kNetworkTechnologyProperty,
-                                   technology_value);
-      base::Value strength_value(50);
+    base::Value strength_value(50);
+    services->SetServiceProperty(
+        kCellularServicePath, shill::kSignalStrengthProperty, strength_value);
+
+    if (activated) {
       services->SetServiceProperty(
-          kCellularServicePath, shill::kSignalStrengthProperty, strength_value);
-
-      if (activated) {
-        services->SetServiceProperty(
-            kCellularServicePath, shill::kActivationStateProperty,
-            base::Value(shill::kActivationStateActivated));
-        services->SetServiceProperty(kCellularServicePath,
-                                     shill::kConnectableProperty,
-                                     base::Value(true));
-      } else {
-        services->SetServiceProperty(
-            kCellularServicePath, shill::kActivationStateProperty,
-            base::Value(shill::kActivationStateNotActivated));
-      }
-
-      std::string shill_roaming_state;
-      if (roaming_state_ == kRoamingRequired)
-        shill_roaming_state = shill::kRoamingStateRoaming;
-      else if (roaming_state_.empty())
-        shill_roaming_state = shill::kRoamingStateHome;
-      else  // |roaming_state_| is expected to be a valid Shill state.
-        shill_roaming_state = roaming_state_;
-      services->SetServiceProperty(kCellularServicePath,
-                                   shill::kRoamingStateProperty,
-                                   base::Value(shill_roaming_state));
-
-      base::DictionaryValue apn;
-      apn.SetKey(shill::kApnProperty, base::Value("testapn"));
-      apn.SetKey(shill::kApnNameProperty, base::Value("Test APN"));
-      apn.SetKey(shill::kApnLocalizedNameProperty,
-                 base::Value("Localized Test APN"));
-      apn.SetKey(shill::kApnUsernameProperty, base::Value("User1"));
-      apn.SetKey(shill::kApnPasswordProperty, base::Value("password"));
-      base::DictionaryValue apn2;
-      apn2.SetKey(shill::kApnProperty, base::Value("testapn2"));
-      services->SetServiceProperty(kCellularServicePath,
-                                   shill::kCellularApnProperty, apn);
-      services->SetServiceProperty(kCellularServicePath,
-                                   shill::kCellularLastGoodApnProperty, apn);
-      base::ListValue apn_list;
-      apn_list.Append(apn.CreateDeepCopy());
-      apn_list.Append(apn2.CreateDeepCopy());
-      devices->SetDeviceProperty("/device/cellular1",
-                                 shill::kCellularApnListProperty, apn_list);
-
-      profiles->AddService(shared_profile, kCellularServicePath);
+          kCellularServicePath, shill::kActivationStateProperty,
+          base::Value(shill::kActivationStateActivated));
+      services->SetServiceProperty(
+          kCellularServicePath, shill::kConnectableProperty, base::Value(true));
+    } else {
+      services->SetServiceProperty(
+          kCellularServicePath, shill::kActivationStateProperty,
+          base::Value(shill::kActivationStateNotActivated));
     }
+
+    std::string shill_roaming_state;
+    if (roaming_state_ == kRoamingRequired)
+      shill_roaming_state = shill::kRoamingStateRoaming;
+    else if (roaming_state_.empty())
+      shill_roaming_state = shill::kRoamingStateHome;
+    else  // |roaming_state_| is expected to be a valid Shill state.
+      shill_roaming_state = roaming_state_;
+    services->SetServiceProperty(kCellularServicePath,
+                                 shill::kRoamingStateProperty,
+                                 base::Value(shill_roaming_state));
+
+    base::DictionaryValue apn;
+    apn.SetKey(shill::kApnProperty, base::Value("testapn"));
+    apn.SetKey(shill::kApnNameProperty, base::Value("Test APN"));
+    apn.SetKey(shill::kApnLocalizedNameProperty,
+               base::Value("Localized Test APN"));
+    apn.SetKey(shill::kApnUsernameProperty, base::Value("User1"));
+    apn.SetKey(shill::kApnPasswordProperty, base::Value("password"));
+    base::DictionaryValue apn2;
+    apn2.SetKey(shill::kApnProperty, base::Value("testapn2"));
+    services->SetServiceProperty(kCellularServicePath,
+                                 shill::kCellularApnProperty, apn);
+    services->SetServiceProperty(kCellularServicePath,
+                                 shill::kCellularLastGoodApnProperty, apn);
+    base::ListValue apn_list;
+    apn_list.Append(apn.CreateDeepCopy());
+    apn_list.Append(apn2.CreateDeepCopy());
+    devices->SetDeviceProperty("/device/cellular1",
+                               shill::kCellularApnListProperty, apn_list);
+
+    profiles->AddService(shared_profile, kCellularServicePath);
   }
 
   // VPN
diff --git a/chromeos/network/device_state.cc b/chromeos/network/device_state.cc
index e43057a..3f9cf50 100644
--- a/chromeos/network/device_state.cc
+++ b/chromeos/network/device_state.cc
@@ -158,7 +158,7 @@
 }
 
 bool DeviceState::IsSimAbsent() const {
-  return technology_family_ != shill::kTechnologyFamilyCdma && !sim_present_;
+  return technology_family_ == shill::kTechnologyFamilyGsm && !sim_present_;
 }
 
 }  // namespace chromeos
diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc
index 2f9140d..4a93ce0b 100644
--- a/chromeos/network/network_configuration_handler.cc
+++ b/chromeos/network/network_configuration_handler.cc
@@ -232,15 +232,16 @@
   const NetworkState* network_state =
       network_state_handler_->GetNetworkState(service_path);
   if (network_state &&
-      (NetworkTypePattern::Tether().MatchesType(network_state->type()) ||
-       network_state->IsDefaultCellular())) {
-    // This is a Tether network or a Cellular network with no Service.
-    // Provide properties from NetworkState.
+      NetworkTypePattern::Tether().MatchesType(network_state->type())) {
+    // If this is a Tether network, use the properties present in the
+    // NetworkState object provided by NetworkStateHandler. Tether networks are
+    // not present in Shill, so the Shill call below will not work.
     base::DictionaryValue dictionary;
     network_state->GetStateProperties(&dictionary);
     callback.Run(service_path, dictionary);
     return;
   }
+
   DBusThreadManager::Get()->GetShillServiceClient()->GetProperties(
       dbus::ObjectPath(service_path),
       base::Bind(&NetworkConfigurationHandler::GetPropertiesCallback,
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc
index 882a7ce..07a875d 100644
--- a/chromeos/network/network_state.cc
+++ b/chromeos/network/network_state.cc
@@ -9,7 +9,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
@@ -26,8 +25,6 @@
 
 const char kErrorUnknown[] = "Unknown";
 
-const char kDefaultCellularNetworkPath[] = "/cellular";
-
 bool ConvertListValueToStringVector(const base::ListValue& string_list,
                                     std::vector<std::string>* result) {
   for (size_t i = 0; i < string_list.GetSize(); ++i) {
@@ -246,10 +243,9 @@
   dictionary->SetKey(shill::kProfileProperty, base::Value(profile_path()));
   dictionary->SetKey(shill::kPriorityProperty, base::Value(priority_));
 
-  if (visible())
+  if (visible()) {
     dictionary->SetKey(shill::kStateProperty, base::Value(connection_state()));
-  if (!device_path().empty())
-    dictionary->SetKey(shill::kDeviceProperty, base::Value(device_path()));
+  }
 
   // VPN properties.
   if (NetworkTypePattern::VPN().MatchesType(type())) {
@@ -408,11 +404,6 @@
          profile_path_ != NetworkProfileHandler::GetSharedProfilePath();
 }
 
-bool NetworkState::IsDefaultCellular() const {
-  return type() == shill::kTypeCellular &&
-         path() == kDefaultCellularNetworkPath;
-}
-
 std::string NetworkState::GetHexSsid() const {
   return base::HexEncode(raw_ssid().data(), raw_ssid().size());
 }
@@ -438,9 +429,9 @@
   }
   if (type() == shill::kTypeWifi)
     return name() + "_" + security_class_;
-  if (type() != shill::kTypeCellular && !name().empty())
+  if (!name().empty())
     return name();
-  return type();  // For unnamed networks, i.e. Ethernet and Cellular.
+  return type();  // For unnamed networks such as ethernet.
 }
 
 void NetworkState::SetGuid(const std::string& guid) {
@@ -489,15 +480,4 @@
   return !error.empty() && error != kErrorUnknown;
 }
 
-// static
-std::unique_ptr<NetworkState> NetworkState::CreateDefaultCellular(
-    const std::string& device_path) {
-  auto new_state = base::MakeUnique<NetworkState>(kDefaultCellularNetworkPath);
-  new_state->set_type(shill::kTypeCellular);
-  new_state->set_update_received();
-  new_state->set_visible(true);
-  new_state->device_path_ = device_path;
-  return new_state;
-}
-
 }  // namespace chromeos
diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h
index 145c826..c7d7e38 100644
--- a/chromeos/network/network_state.h
+++ b/chromeos/network/network_state.h
@@ -145,10 +145,6 @@
   // Returns true if the network properties are stored in a user profile.
   bool IsPrivate() const;
 
-  // Returns true if the network is a default Cellular network (see
-  // NetworkStateHandler::EnsureCellularNetwork()).
-  bool IsDefaultCellular() const;
-
   // Returns the |raw_ssid| as a hex-encoded string
   std::string GetHexSsid() const;
 
@@ -175,8 +171,6 @@
   static bool NetworkStateIsCaptivePortal(
       const base::DictionaryValue& shill_properties);
   static bool ErrorIsValid(const std::string& error);
-  static std::unique_ptr<NetworkState> CreateDefaultCellular(
-      const std::string& device_path);
 
  private:
   friend class MobileActivatorTest;
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
index 5fa7a6f1..c17d8c2 100644
--- a/chromeos/network/network_state_handler.cc
+++ b/chromeos/network/network_state_handler.cc
@@ -1298,26 +1298,16 @@
 
   // Note: usually active networks will precede inactive networks, however
   // this may briefly be untrue during state transitions (e.g. a network may
-  // transition to idle before the list is updated). Also separate Cellular
-  // networks (see below).
-  ManagedStateList cellular, active, non_wifi_visible, wifi_visible, hidden,
-      new_networks;
+  // transition to idle before the list is updated).
+  ManagedStateList active, non_wifi_visible, wifi_visible, hidden, new_networks;
   for (ManagedStateList::iterator iter = network_list_.begin();
        iter != network_list_.end(); ++iter) {
     NetworkState* network = (*iter)->AsNetworkState();
-    if (NetworkTypePattern::Cellular().MatchesType(network->type())) {
-      cellular.push_back(std::move(*iter));
-      continue;
-    }
-    // NetworkState entries are created when they appear in the list, but the
-    // details are not populated until an update is received.
     if (!network->update_received()) {
       new_networks.push_back(std::move(*iter));
       continue;
     }
-    // Ethernet networks are always considered active.
-    if (network->IsConnectingOrConnected() ||
-        NetworkTypePattern::Ethernet().MatchesType(network->type())) {
+    if (network->IsConnectedState() || network->IsConnectingState()) {
       active.push_back(std::move(*iter));
       continue;
     }
@@ -1330,20 +1320,12 @@
       hidden.push_back(std::move(*iter));
     }
   }
-  EnsureCellularNetwork(&cellular);
-  // List active non Cellular network first.
+  network_list_.clear();
   network_list_ = std::move(active);
-  // Ethernet is always active so list any Cellular network next.
-  std::move(cellular.begin(), cellular.end(),
-            std::back_inserter(network_list_));
-  // List any other non WiFi visible networks (i.e. WiMAX).
   std::move(non_wifi_visible.begin(), non_wifi_visible.end(),
             std::back_inserter(network_list_));
-  // List WiFi networks last.
   std::move(wifi_visible.begin(), wifi_visible.end(),
             std::back_inserter(network_list_));
-  // Include hidden and new networks in the list at the end; they should not
-  // be shown by the UI.
   std::move(hidden.begin(), hidden.end(), std::back_inserter(network_list_));
   std::move(new_networks.begin(), new_networks.end(),
             std::back_inserter(network_list_));
@@ -1437,14 +1419,11 @@
     // If the network is saved in a profile, remove the entry from the map.
     // Otherwise ensure that the entry matches the specified GUID. (e.g. in
     // case a visible network with a specified guid gets configured with a
-    // new guid). Exception: Ethernet and Cellular expect to have a single
-    // network and a consistent GUID.
-    if (network->type() != shill::kTypeEthernet &&
-        network->type() != shill::kTypeCellular && network->IsInProfile()) {
+    // new guid).
+    if (network->IsInProfile())
       specifier_guid_map_.erase(specifier);
-    } else {
+    else
       specifier_guid_map_[specifier] = network->guid();
-    }
     return;
   }
   // Ensure that the NetworkState has a valid GUID.
@@ -1459,37 +1438,6 @@
   network->SetGuid(guid);
 }
 
-void NetworkStateHandler::EnsureCellularNetwork(
-    ManagedStateList* cellular_networks) {
-  const DeviceState* device =
-      GetDeviceStateByType(NetworkTypePattern::Cellular());
-  if (!device) {
-    cellular_networks->clear();
-    return;
-  }
-  if (cellular_networks->empty()) {
-    // Create a default Cellular network. Properties from the associated Device
-    // will be provided to the UI.
-    std::unique_ptr<NetworkState> network =
-        NetworkState::CreateDefaultCellular(device->path());
-    UpdateGuid(network.get());
-    cellular_networks->push_back(std::move(network));
-    return;
-  }
-  if (cellular_networks->size() == 1)
-    return;
-  // If we have > 1 Cellular NetworkState, then Shill provided a Cellular
-  // Service after the default Cellular NetworkState was created, so remove the
-  // default state.
-  for (auto iter = cellular_networks->begin(); iter != cellular_networks->end();
-       ++iter) {
-    if ((*iter)->AsNetworkState()->IsDefaultCellular()) {
-      cellular_networks->erase(iter);
-      break;  // There will only ever be one default Cellular network.
-    }
-  }
-}
-
 void NetworkStateHandler::NotifyNetworkListChanged() {
   NET_LOG_EVENT("NOTIFY:NetworkListChanged",
                 base::StringPrintf("Size:%" PRIuS, network_list_.size()));
diff --git a/chromeos/network/network_state_handler.h b/chromeos/network/network_state_handler.h
index 765505d..7f57404 100644
--- a/chromeos/network/network_state_handler.h
+++ b/chromeos/network/network_state_handler.h
@@ -437,12 +437,6 @@
   // Ensure a valid GUID for NetworkState.
   void UpdateGuid(NetworkState* network);
 
-  // Cellular networks may not have an associated Shill Service (e.g. when the
-  // SIM is locked or a mobile network is not available). To simplify the UI,
-  // if a Cellular Device exists |cellular_networks| will be modified to contain
-  // exactly one network, creating a default network if necessary.
-  void EnsureCellularNetwork(ManagedStateList* cellular_networks);
-
   // Sends NetworkListChanged() to observers and logs an event.
   void NotifyNetworkListChanged();
 
diff --git a/chromeos/network/network_state_handler_unittest.cc b/chromeos/network/network_state_handler_unittest.cc
index e433207..f22e047 100644
--- a/chromeos/network/network_state_handler_unittest.cc
+++ b/chromeos/network/network_state_handler_unittest.cc
@@ -1653,67 +1653,4 @@
       kShillManagerClientStubDefaultWifi));
 }
 
-TEST_F(NetworkStateHandlerTest, UpdateGuid) {
-  const NetworkState* wifi1 = network_state_handler_->GetNetworkState(
-      kShillManagerClientStubDefaultWifi);
-  ASSERT_TRUE(wifi1);
-  EXPECT_EQ("wifi1_guid", wifi1->guid());
-  // Remove the wifi service.
-  service_test_->RemoveService(kShillManagerClientStubDefaultWifi);
-  base::RunLoop().RunUntilIdle();
-  wifi1 = network_state_handler_->GetNetworkState(
-      kShillManagerClientStubDefaultWifi);
-  EXPECT_FALSE(wifi1);
-  // Add the wifi service but do not specify a guid; the same guid should be
-  // reused.
-  AddService(kShillManagerClientStubDefaultWifi, "", "wifi1", shill::kTypeWifi,
-             shill::kStateOnline);
-  base::RunLoop().RunUntilIdle();
-  wifi1 = network_state_handler_->GetNetworkState(
-      kShillManagerClientStubDefaultWifi);
-  ASSERT_TRUE(wifi1);
-  EXPECT_EQ("wifi1_guid", wifi1->guid());
-
-  const NetworkState* cellular =
-      network_state_handler_->GetNetworkState(kShillManagerClientStubCellular);
-  ASSERT_TRUE(cellular);
-  EXPECT_EQ("cellular1_guid", cellular->guid());
-  // Remove the cellular service. This should create a default network with the
-  // same GUID.
-  service_test_->RemoveService(kShillManagerClientStubCellular);
-  base::RunLoop().RunUntilIdle();
-  // No service matching kShillManagerClientStubCellular.
-  EXPECT_FALSE(
-      network_state_handler_->GetNetworkState(kShillManagerClientStubCellular));
-  // The default cellular network should have the same guid as before.
-  cellular = network_state_handler_->FirstNetworkByType(
-      NetworkTypePattern::Cellular());
-  ASSERT_TRUE(cellular);
-  EXPECT_EQ("cellular1_guid", cellular->guid());
-}
-
-TEST_F(NetworkStateHandlerTest, EnsureCellularNetwork) {
-  // ClearServices will trigger a kServiceCompleteListProperty property change
-  // which will create a default Cellular network.
-  service_test_->ClearServices();
-  base::RunLoop().RunUntilIdle();
-  NetworkStateHandler::NetworkStateList cellular_networks;
-  network_state_handler_->GetNetworkListByType(
-      NetworkTypePattern::Cellular(), false /* configured_only */,
-      false /* visible_only */, 0, &cellular_networks);
-  ASSERT_EQ(1u, cellular_networks.size());
-  EXPECT_TRUE(cellular_networks[0]->IsDefaultCellular());
-
-  // Add a Cellular service. This should replace the default cellular network.
-  AddService(kShillManagerClientStubCellular, "cellular1_guid", "cellular1",
-             shill::kTypeCellular, shill::kStateIdle);
-  base::RunLoop().RunUntilIdle();
-  network_state_handler_->GetNetworkListByType(
-      NetworkTypePattern::Cellular(), false /* configured_only */,
-      false /* visible_only */, 0, &cellular_networks);
-  ASSERT_EQ(1u, cellular_networks.size());
-  EXPECT_FALSE(cellular_networks[0]->IsDefaultCellular());
-  EXPECT_EQ("/service/cellular1", cellular_networks[0]->path());
-}
-
 }  // namespace chromeos
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc
index 0b7a758e..1a72037 100644
--- a/chromeos/network/onc/onc_signature.cc
+++ b/chromeos/network/onc/onc_signature.cc
@@ -183,6 +183,8 @@
     {::onc::ipconfig::kNameServers, &kStringListSignature},
     {::onc::ipconfig::kRoutingPrefix, &kIntegerSignature},
     {::onc::ipconfig::kSearchDomains, &kStringListSignature},
+    {::onc::ipconfig::kIncludedRoutes, &kStringListSignature},
+    {::onc::ipconfig::kExcludedRoutes, &kStringListSignature},
     {::onc::ipconfig::kType, &kStringSignature},
     {::onc::ipconfig::kWebProxyAutoDiscoveryUrl, &kStringSignature},
     {NULL}};
diff --git a/chromeos/network/onc/onc_translation_tables.cc b/chromeos/network/onc/onc_translation_tables.cc
index b311b87..6e13d31e 100644
--- a/chromeos/network/onc/onc_translation_tables.cc
+++ b/chromeos/network/onc/onc_translation_tables.cc
@@ -235,6 +235,9 @@
     {::onc::ipconfig::kGateway, shill::kGatewayProperty},
     {::onc::ipconfig::kRoutingPrefix, shill::kPrefixlenProperty},
     {::onc::ipconfig::kNameServers, shill::kNameServersProperty},
+    {::onc::ipconfig::kSearchDomains, shill::kSearchDomainsProperty},
+    {::onc::ipconfig::kIncludedRoutes, shill::kIncludedRoutesProperty},
+    {::onc::ipconfig::kExcludedRoutes, shill::kExcludedRoutesProperty},
     {NULL}};
 
 struct OncValueTranslationEntry {
diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/network/onc/onc_translator_shill_to_onc.cc
index 3c0122f..0ae0c73 100644
--- a/chromeos/network/onc/onc_translator_shill_to_onc.cc
+++ b/chromeos/network/onc/onc_translator_shill_to_onc.cc
@@ -779,8 +779,7 @@
     const std::string& onc_field_name) {
   std::string shill_value;
   if (!shill_dictionary_->GetStringWithoutPathExpansion(shill_property_name,
-                                                        &shill_value) ||
-      shill_value.empty()) {
+                                                        &shill_value)) {
     return;
   }
   std::string onc_value;
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 242f7f6..a23e07c 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -457,6 +457,8 @@
     "//base:base_java_test_support",
     "//net/android:net_java_test_support",
     "//third_party/android_support_test_runner:runner_java",
+    "//third_party/android_support_test_runner:rules_java",
+    "//third_party/junit",
   ]
   additional_apks = [ "//net/android:net_test_support_apk" ]
 
@@ -560,7 +562,7 @@
 
 cronet_smoketests_platform_only_common_srcs = [
   "test/smoketests/src/org/chromium/net/smoke/ChromiumPlatformOnlyTestSupport.java",
-  "test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestCase.java",
+  "test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestRule.java",
   "test/smoketests/src/org/chromium/net/smoke/HttpTestServer.java",
   "test/smoketests/src/org/chromium/net/smoke/SmokeTestRequestCallback.java",
   "test/smoketests/src/org/chromium/net/smoke/TestSupport.java",
@@ -568,7 +570,7 @@
 
 cronet_smoketests_native_common_srcs = cronet_smoketests_platform_only_common_srcs + [
                                          "test/smoketests/src/org/chromium/net/smoke/ChromiumNativeTestSupport.java",
-                                         "test/smoketests/src/org/chromium/net/smoke/NativeCronetTestCase.java",
+                                         "test/smoketests/src/org/chromium/net/smoke/NativeCronetTestRule.java",
                                        ]
 
 android_library("cronet_smoketests_native_java") {
@@ -582,6 +584,8 @@
     ":cronet_api_java",
     ":cronet_test_apk_java",
     "//base:base_java",
+    "//base:base_java_test_support",
+    "//third_party/junit",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/netty4:netty_all_java",
   ]
@@ -748,6 +752,8 @@
   java_files = [ "test/smoketests/src/org/chromium/net/smoke/PlatformOnlyEngineTest.java" ] + cronet_smoketests_platform_only_common_srcs
   deps = [
     ":cronet_api_java",
+    "//base:base_java_test_support",
+    "//third_party/junit",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/netty4:netty_all_java",
   ]
@@ -798,6 +804,8 @@
     ":cronet_api_java",
     ":cronet_test_apk_java",
     "//base:base_java",
+    "//base:base_java_test_support",
+    "//third_party/junit",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/netty4:netty_all_java",
   ]
diff --git a/components/cronet/android/cronet_url_request_context_adapter.h b/components/cronet/android/cronet_url_request_context_adapter.h
index 75fccdd..97ec1e8 100644
--- a/components/cronet/android/cronet_url_request_context_adapter.h
+++ b/components/cronet/android/cronet_url_request_context_adapter.h
@@ -224,14 +224,14 @@
   // that weakly references |network_quality_estimator_|.
   std::unique_ptr<net::NetworkQualityEstimator> network_quality_estimator_;
 
+  std::unique_ptr<net::URLRequestContext> context_;
+
   // Manages the PrefService and all associated persistence managers
   // such as NetworkQualityPrefsManager, HostCachePersistenceManager, etc.
-  // It should be destroyed before |network_quality_estimator_|. It also owns a
-  // PrefService object should outlive |context_|.
+  // It should be destroyed before |network_quality_estimator_| and
+  // |context_|.
   std::unique_ptr<CronetPrefsManager> cronet_prefs_manager_;
 
-  std::unique_ptr<net::URLRequestContext> context_;
-
   std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
 
   // Context config is only valid until context is initialized.
diff --git a/components/cronet/android/sample/javatests/AndroidManifest.xml b/components/cronet/android/sample/javatests/AndroidManifest.xml
index f9af6cfb..5acebd8 100644
--- a/components/cronet/android/sample/javatests/AndroidManifest.xml
+++ b/components/cronet/android/sample/javatests/AndroidManifest.xml
@@ -16,6 +16,10 @@
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="org.chromium.cronet_sample_apk"
+        android:label="Tests for org.chromium.cronet_sample_apk"
+        chromium-junit4="true"/>
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.cronet_sample_apk"
         android:label="Tests for org.chromium.cronet_sample_apk"/>
diff --git a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java b/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
index f3c9500..6a2798f 100644
--- a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
+++ b/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
@@ -8,47 +8,56 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.ConditionVariable;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
-import android.test.ActivityInstrumentationTestCase2;
+import android.support.test.rule.ActivityTestRule;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.widget.TextView;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.net.test.EmbeddedTestServer;
 
 /**
  * Base test class for all CronetSample based tests.
  */
-public class CronetSampleTest extends
-        ActivityInstrumentationTestCase2<CronetSampleActivity> {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class CronetSampleTest {
     private EmbeddedTestServer mTestServer;
     private String mUrl;
 
-    public CronetSampleTest() {
-        super(CronetSampleActivity.class);
-    }
+    @Rule
+    public ActivityTestRule<CronetSampleActivity> mActivityTestRule =
+            new ActivityTestRule<>(CronetSampleActivity.class, false, false);
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+    @Before
+    public void setUp() throws Exception {
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mUrl = mTestServer.getURL("/echo?status=200");
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
+    @Test
     @SmallTest
     @Feature({"Cronet"})
     public void testLoadUrl() throws Exception {
         CronetSampleActivity activity = launchCronetSampleWithUrl(mUrl);
 
         // Make sure the activity was created as expected.
-        assertNotNull(activity);
+        Assert.assertNotNull(activity);
 
         // Verify successful fetch.
         final TextView textView = (TextView) activity.findViewById(R.id.resultView);
@@ -81,10 +90,9 @@
         intent.addCategory(Intent.CATEGORY_LAUNCHER);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.setData(Uri.parse(url));
-        intent.setComponent(new ComponentName(
-                getInstrumentation().getTargetContext(),
-                CronetSampleActivity.class));
-        setActivityIntent(intent);
-        return getActivity();
+        intent.setComponent(
+                new ComponentName(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                        CronetSampleActivity.class));
+        return mActivityTestRule.launchActivity(intent);
     }
 }
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestCase.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestCase.java
deleted file mode 100644
index dd2f7ad..0000000
--- a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestCase.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.net.smoke;
-
-import android.content.Context;
-import android.test.AndroidTestCase;
-
-import org.chromium.net.CronetEngine;
-import org.chromium.net.ExperimentalCronetEngine;
-import org.chromium.net.UrlResponseInfo;
-
-/**
- * Base test class. This class should not import any classes from the org.chromium.base package.
- */
-public class CronetSmokeTestCase extends AndroidTestCase {
-    /**
-     * The key in the string resource file that specifies {@link TestSupport} that should
-     * be instantiated.
-     */
-    private static final String SUPPORT_IMPL_RES_KEY = "TestSupportImplClass";
-
-    protected ExperimentalCronetEngine.Builder mCronetEngineBuilder;
-    protected CronetEngine mCronetEngine;
-    protected TestSupport mTestSupport;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mCronetEngineBuilder = new ExperimentalCronetEngine.Builder(getContext());
-        initTestSupport();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (mCronetEngine != null) {
-            mCronetEngine.shutdown();
-        }
-        super.tearDown();
-    }
-
-    protected void initCronetEngine() {
-        mCronetEngine = mCronetEngineBuilder.build();
-    }
-
-    static void assertSuccessfulNonEmptyResponse(SmokeTestRequestCallback callback, String url) {
-        // Check the request state
-        if (callback.getFinalState() == SmokeTestRequestCallback.State.Failed) {
-            throw new RuntimeException(
-                    "The request failed with an error", callback.getFailureError());
-        }
-        assertEquals(SmokeTestRequestCallback.State.Succeeded, callback.getFinalState());
-
-        // Check the response info
-        UrlResponseInfo responseInfo = callback.getResponseInfo();
-        assertNotNull(responseInfo);
-        assertFalse(responseInfo.wasCached());
-        assertEquals(url, responseInfo.getUrl());
-        assertEquals(url, responseInfo.getUrlChain().get(responseInfo.getUrlChain().size() - 1));
-        assertEquals(200, responseInfo.getHttpStatusCode());
-        assertTrue(responseInfo.toString().length() > 0);
-    }
-
-    static void assertJavaEngine(CronetEngine engine) {
-        assertNotNull(engine);
-        assertEquals("org.chromium.net.impl.JavaCronetEngine", engine.getClass().getName());
-    }
-
-    static void assertNativeEngine(CronetEngine engine) {
-        assertNotNull(engine);
-        assertEquals("org.chromium.net.impl.CronetUrlRequestContext", engine.getClass().getName());
-    }
-
-    /**
-     * Instantiates a concrete implementation of {@link TestSupport} interface.
-     * The name of the implementation class is determined dynamically by reading
-     * the value of |TestSupportImplClass| from the Android string resource file.
-     *
-     * @throws Exception if the class cannot be instantiated.
-     */
-    private void initTestSupport() throws Exception {
-        Context ctx = getContext();
-        String packageName = ctx.getPackageName();
-        int resId = ctx.getResources().getIdentifier(SUPPORT_IMPL_RES_KEY, "string", packageName);
-        String className = ctx.getResources().getString(resId);
-        Class<? extends TestSupport> cl = Class.forName(className).asSubclass(TestSupport.class);
-        mTestSupport = cl.newInstance();
-    }
-}
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestRule.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestRule.java
new file mode 100644
index 0000000..a00ada0d
--- /dev/null
+++ b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestRule.java
@@ -0,0 +1,118 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.net.smoke;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.Assert;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import org.chromium.net.CronetEngine;
+import org.chromium.net.ExperimentalCronetEngine;
+import org.chromium.net.UrlResponseInfo;
+
+/**
+ * Base test class. This class should not import any classes from the org.chromium.base package.
+ */
+public class CronetSmokeTestRule implements TestRule {
+    /**
+     * The key in the string resource file that specifies {@link TestSupport} that should
+     * be instantiated.
+     */
+    private static final String SUPPORT_IMPL_RES_KEY = "TestSupportImplClass";
+
+    public ExperimentalCronetEngine.Builder mCronetEngineBuilder;
+    public CronetEngine mCronetEngine;
+    public TestSupport mTestSupport;
+
+    @Override
+    public Statement apply(final Statement base, Description desc) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                ruleSetUp();
+                base.evaluate();
+                ruleTearDown();
+            }
+        };
+    }
+
+    public TestSupport getTestSupport() {
+        return mTestSupport;
+    }
+
+    public CronetEngine getCronetEngine() {
+        return mCronetEngine;
+    }
+
+    public ExperimentalCronetEngine.Builder getCronetEngineBuilder() {
+        return mCronetEngineBuilder;
+    }
+
+    private void ruleSetUp() throws Exception {
+        mCronetEngineBuilder =
+                new ExperimentalCronetEngine.Builder(InstrumentationRegistry.getTargetContext());
+        initTestSupport();
+    }
+
+    private void ruleTearDown() throws Exception {
+        if (mCronetEngine != null) {
+            mCronetEngine.shutdown();
+        }
+    }
+
+    public void initCronetEngine() {
+        mCronetEngine = mCronetEngineBuilder.build();
+    }
+
+    static void assertSuccessfulNonEmptyResponse(SmokeTestRequestCallback callback, String url) {
+        // Check the request state
+        if (callback.getFinalState() == SmokeTestRequestCallback.State.Failed) {
+            throw new RuntimeException(
+                    "The request failed with an error", callback.getFailureError());
+        }
+        Assert.assertEquals(SmokeTestRequestCallback.State.Succeeded, callback.getFinalState());
+
+        // Check the response info
+        UrlResponseInfo responseInfo = callback.getResponseInfo();
+        Assert.assertNotNull(responseInfo);
+        Assert.assertFalse(responseInfo.wasCached());
+        Assert.assertEquals(url, responseInfo.getUrl());
+        Assert.assertEquals(
+                url, responseInfo.getUrlChain().get(responseInfo.getUrlChain().size() - 1));
+        Assert.assertEquals(200, responseInfo.getHttpStatusCode());
+        Assert.assertTrue(responseInfo.toString().length() > 0);
+    }
+
+    static void assertJavaEngine(CronetEngine engine) {
+        Assert.assertNotNull(engine);
+        Assert.assertEquals("org.chromium.net.impl.JavaCronetEngine", engine.getClass().getName());
+    }
+
+    static void assertNativeEngine(CronetEngine engine) {
+        Assert.assertNotNull(engine);
+        Assert.assertEquals(
+                "org.chromium.net.impl.CronetUrlRequestContext", engine.getClass().getName());
+    }
+
+    /**
+     * Instantiates a concrete implementation of {@link TestSupport} interface.
+     * The name of the implementation class is determined dynamically by reading
+     * the value of |TestSupportImplClass| from the Android string resource file.
+     *
+     * @throws Exception if the class cannot be instantiated.
+     */
+    private void initTestSupport() throws Exception {
+        Context ctx = InstrumentationRegistry.getTargetContext();
+        String packageName = ctx.getPackageName();
+        int resId = ctx.getResources().getIdentifier(SUPPORT_IMPL_RES_KEY, "string", packageName);
+        String className = ctx.getResources().getString(resId);
+        Class<? extends TestSupport> cl = Class.forName(className).asSubclass(TestSupport.class);
+        mTestSupport = cl.newInstance();
+    }
+}
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/Http2Test.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/Http2Test.java
index c1d680d..af951bc 100644
--- a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/Http2Test.java
+++ b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/Http2Test.java
@@ -4,41 +4,54 @@
 
 package org.chromium.net.smoke;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.net.UrlRequest;
 
 /**
  * HTTP2 Tests.
  */
-public class Http2Test extends NativeCronetTestCase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class Http2Test {
     private TestSupport.TestServer mServer;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mServer = mTestSupport.createTestServer(getContext(), TestSupport.Protocol.HTTP2);
+    @Rule
+    public NativeCronetTestRule mRule = new NativeCronetTestRule();
+
+    @Before
+    public void setUp() throws Exception {
+        mServer = mRule.getTestSupport().createTestServer(
+                InstrumentationRegistry.getTargetContext(), TestSupport.Protocol.HTTP2);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mServer.shutdown();
-        super.tearDown();
     }
 
     // Test that HTTP/2 is enabled by default but QUIC is not.
+    @Test
     @SmallTest
     public void testHttp2() throws Exception {
-        mTestSupport.installMockCertVerifierForTesting(mCronetEngineBuilder);
-        initCronetEngine();
-        assertTrue(mServer.start());
+        mRule.getTestSupport().installMockCertVerifierForTesting(mRule.getCronetEngineBuilder());
+        mRule.initCronetEngine();
+        Assert.assertTrue(mServer.start());
         SmokeTestRequestCallback callback = new SmokeTestRequestCallback();
-        UrlRequest.Builder requestBuilder = mCronetEngine.newUrlRequestBuilder(
+        UrlRequest.Builder requestBuilder = mRule.getCronetEngine().newUrlRequestBuilder(
                 mServer.getSuccessURL(), callback, callback.getExecutor());
         requestBuilder.build().start();
         callback.blockForDone();
 
-        assertSuccessfulNonEmptyResponse(callback, mServer.getSuccessURL());
-        assertEquals("h2", callback.getResponseInfo().getNegotiatedProtocol());
+        CronetSmokeTestRule.assertSuccessfulNonEmptyResponse(callback, mServer.getSuccessURL());
+        Assert.assertEquals("h2", callback.getResponseInfo().getNegotiatedProtocol());
     }
 }
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/MissingNativeLibraryTest.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/MissingNativeLibraryTest.java
index 2595e2b..6e891f9 100644
--- a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/MissingNativeLibraryTest.java
+++ b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/MissingNativeLibraryTest.java
@@ -4,8 +4,17 @@
 
 package org.chromium.net.smoke;
 
+import static org.chromium.net.smoke.CronetSmokeTestRule.assertJavaEngine;
+
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.net.CronetEngine;
 import org.chromium.net.CronetProvider;
 import org.chromium.net.ExperimentalCronetEngine;
@@ -16,23 +25,28 @@
  *  Tests scenarios when the native shared library file is missing in the APK or was built for a
  *  wrong architecture.
  */
-public class MissingNativeLibraryTest extends CronetSmokeTestCase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class MissingNativeLibraryTest {
+    @Rule
+    public CronetSmokeTestRule mRule = new CronetSmokeTestRule();
+
     /**
      * If the ".so" file is missing, instantiating the Cronet engine should throw an exception.
      */
+    @Test
     @SmallTest
     public void testExceptionWhenSoFileIsAbsent() throws Exception {
         ExperimentalCronetEngine.Builder builder =
-                new ExperimentalCronetEngine.Builder(getContext());
+                new ExperimentalCronetEngine.Builder(InstrumentationRegistry.getTargetContext());
         try {
             builder.build();
-            fail("Expected exception since the shared library '.so' file is absent");
+            Assert.fail("Expected exception since the shared library '.so' file is absent");
         } catch (Throwable t) {
             // Find the root cause.
             while (t.getCause() != null) {
                 t = t.getCause();
             }
-            assertEquals(UnsatisfiedLinkError.class, t.getClass());
+            Assert.assertEquals(UnsatisfiedLinkError.class, t.getClass());
         }
     }
 
@@ -40,13 +54,15 @@
      * Tests the embedder ability to select Java (platform) based implementation when
      * the native library is missing or doesn't load for some reason,
      */
+    @Test
     @SmallTest
     public void testForceChoiceOfJavaEngine() throws Exception {
-        List<CronetProvider> availableProviders = CronetProvider.getAllProviders(getContext());
+        List<CronetProvider> availableProviders =
+                CronetProvider.getAllProviders(InstrumentationRegistry.getTargetContext());
         boolean foundNativeProvider = false;
         CronetProvider platformProvider = null;
         for (CronetProvider provider : availableProviders) {
-            assertTrue(provider.isEnabled());
+            Assert.assertTrue(provider.isEnabled());
             if (provider.getName().equals(CronetProvider.PROVIDER_NAME_APP_PACKAGED)) {
                 foundNativeProvider = true;
             } else if (provider.getName().equals(CronetProvider.PROVIDER_NAME_FALLBACK)) {
@@ -54,18 +70,18 @@
             }
         }
 
-        assertTrue("Unable to find the native cronet provider", foundNativeProvider);
-        assertNotNull("Unable to find the platform cronet provider", platformProvider);
+        Assert.assertTrue("Unable to find the native cronet provider", foundNativeProvider);
+        Assert.assertNotNull("Unable to find the platform cronet provider", platformProvider);
 
         CronetEngine.Builder builder = platformProvider.createBuilder();
         CronetEngine engine = builder.build();
         assertJavaEngine(engine);
 
-        assertTrue("It should be always possible to cast the created builder to"
+        Assert.assertTrue("It should be always possible to cast the created builder to"
                         + " ExperimentalCronetEngine.Builder",
                 builder instanceof ExperimentalCronetEngine.Builder);
 
-        assertTrue("It should be always possible to cast the created engine to"
+        Assert.assertTrue("It should be always possible to cast the created engine to"
                         + " ExperimentalCronetEngine.Builder",
                 engine instanceof ExperimentalCronetEngine);
     }
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/NativeCronetTestCase.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/NativeCronetTestRule.java
similarity index 60%
rename from components/cronet/android/test/smoketests/src/org/chromium/net/smoke/NativeCronetTestCase.java
rename to components/cronet/android/test/smoketests/src/org/chromium/net/smoke/NativeCronetTestRule.java
index 6fcb18d..0e116740 100644
--- a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/NativeCronetTestCase.java
+++ b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/NativeCronetTestRule.java
@@ -4,6 +4,11 @@
 
 package org.chromium.net.smoke;
 
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
 import org.chromium.base.ContextUtils;
 import org.chromium.base.PathUtils;
 
@@ -13,29 +18,38 @@
  * Test base class for testing native Engine implementation. This class can import classes from the
  * org.chromium.base package.
  */
-public class NativeCronetTestCase extends CronetSmokeTestCase {
+public class NativeCronetTestRule extends CronetSmokeTestRule {
     private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "cronet_test";
     private static final String LOGFILE_NAME = "cronet-netlog.json";
 
     @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        ContextUtils.initApplicationContext(getContext().getApplicationContext());
+    public Statement apply(final Statement base, Description desc) {
+        return super.apply(new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                ruleSetUp();
+                base.evaluate();
+                ruleTearDown();
+            }
+        }, desc);
+    }
+
+    @Override
+    public void initCronetEngine() {
+        super.initCronetEngine();
+        assertNativeEngine(mCronetEngine);
+        startNetLog();
+    }
+
+    private void ruleSetUp() throws Exception {
+        ContextUtils.initApplicationContext(
+                InstrumentationRegistry.getTargetContext().getApplicationContext());
         PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
         mTestSupport.loadTestNativeLibrary();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    private void ruleTearDown() throws Exception {
         stopAndSaveNetLog();
-        super.tearDown();
-    }
-
-    @Override
-    protected void initCronetEngine() {
-        super.initCronetEngine();
-        assertNativeEngine(mCronetEngine);
-        startNetLog();
     }
 
     private void startNetLog() {
@@ -50,6 +64,6 @@
         mCronetEngine.stopNetLog();
         File netLogFile = new File(PathUtils.getDataDirectory(), LOGFILE_NAME);
         if (!netLogFile.exists()) return;
-        mTestSupport.processNetLog(getContext(), netLogFile);
+        mTestSupport.processNetLog(InstrumentationRegistry.getTargetContext(), netLogFile);
     }
 }
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/PlatformOnlyEngineTest.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/PlatformOnlyEngineTest.java
index 71cd784..f0fe3db 100644
--- a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/PlatformOnlyEngineTest.java
+++ b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/PlatformOnlyEngineTest.java
@@ -4,42 +4,58 @@
 
 package org.chromium.net.smoke;
 
+import static org.chromium.net.smoke.CronetSmokeTestRule.assertJavaEngine;
+import static org.chromium.net.smoke.CronetSmokeTestRule.assertSuccessfulNonEmptyResponse;
+
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.net.UrlRequest;
 
 /**
  * Tests scenario when an app doesn't contain the native Cronet implementation.
  */
-public class PlatformOnlyEngineTest extends CronetSmokeTestCase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class PlatformOnlyEngineTest {
     private String mURL;
     private TestSupport.TestServer mServer;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Rule
+    public CronetSmokeTestRule mRule = new CronetSmokeTestRule();
+
+    @Before
+    public void setUp() throws Exception {
         // Java-only implementation of the Cronet engine only supports Http/1 protocol.
-        mServer = mTestSupport.createTestServer(getContext(), TestSupport.Protocol.HTTP1);
-        assertTrue(mServer.start());
+        mServer = mRule.getTestSupport().createTestServer(
+                InstrumentationRegistry.getTargetContext(), TestSupport.Protocol.HTTP1);
+        Assert.assertTrue(mServer.start());
         mURL = mServer.getSuccessURL();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mServer.shutdown();
-        super.tearDown();
     }
 
     /**
      * Test a successful response when a request is sent by the Java Cronet Engine.
      */
+    @Test
     @SmallTest
     public void testSuccessfulResponse() {
-        initCronetEngine();
-        assertJavaEngine(mCronetEngine);
+        mRule.initCronetEngine();
+        assertJavaEngine(mRule.getCronetEngine());
         SmokeTestRequestCallback callback = new SmokeTestRequestCallback();
-        UrlRequest.Builder requestBuilder =
-                mCronetEngine.newUrlRequestBuilder(mURL, callback, callback.getExecutor());
+        UrlRequest.Builder requestBuilder = mRule.getCronetEngine().newUrlRequestBuilder(
+                mURL, callback, callback.getExecutor());
         requestBuilder.build().start();
         callback.blockForDone();
         assertSuccessfulNonEmptyResponse(callback, mURL);
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java
index 1c0144d..163b974 100644
--- a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java
+++ b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java
@@ -4,12 +4,20 @@
 
 package org.chromium.net.smoke;
 
+import static org.chromium.net.smoke.TestSupport.Protocol.QUIC;
+
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
 import org.json.JSONObject;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-import static org.chromium.net.smoke.TestSupport.Protocol.QUIC;
-
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.net.UrlRequest;
 
 import java.net.URL;
@@ -17,37 +25,41 @@
 /**
  * QUIC Tests.
  */
-public class QuicTest extends NativeCronetTestCase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class QuicTest {
     private TestSupport.TestServer mServer;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mServer = mTestSupport.createTestServer(getContext(), QUIC);
+    @Rule
+    public NativeCronetTestRule mRule = new NativeCronetTestRule();
+
+    @Before
+    public void setUp() throws Exception {
+        mServer = mRule.getTestSupport().createTestServer(
+                InstrumentationRegistry.getTargetContext(), QUIC);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mServer.shutdown();
-        super.tearDown();
     }
 
+    @Test
     @SmallTest
     public void testQuic() throws Exception {
-        assertTrue(mServer.start());
+        Assert.assertTrue(mServer.start());
         final String urlString = mServer.getSuccessURL();
         final URL url = new URL(urlString);
 
-        mCronetEngineBuilder.enableQuic(true);
-        mCronetEngineBuilder.addQuicHint(url.getHost(), url.getPort(), url.getPort());
-        mTestSupport.installMockCertVerifierForTesting(mCronetEngineBuilder);
+        mRule.getCronetEngineBuilder().enableQuic(true);
+        mRule.getCronetEngineBuilder().addQuicHint(url.getHost(), url.getPort(), url.getPort());
+        mRule.getTestSupport().installMockCertVerifierForTesting(mRule.getCronetEngineBuilder());
 
         JSONObject quicParams = new JSONObject();
         JSONObject experimentalOptions = new JSONObject().put("QUIC", quicParams);
-        mTestSupport.addHostResolverRules(experimentalOptions);
-        mCronetEngineBuilder.setExperimentalOptions(experimentalOptions.toString());
+        mRule.getTestSupport().addHostResolverRules(experimentalOptions);
+        mRule.getCronetEngineBuilder().setExperimentalOptions(experimentalOptions.toString());
 
-        initCronetEngine();
+        mRule.initCronetEngine();
 
         // QUIC is not guaranteed to win the race, so try multiple times.
         boolean quicNegotiated = false;
@@ -55,15 +67,16 @@
         for (int i = 0; i < 5; i++) {
             SmokeTestRequestCallback callback = new SmokeTestRequestCallback();
             UrlRequest.Builder requestBuilder =
-                    mCronetEngine.newUrlRequestBuilder(urlString, callback, callback.getExecutor());
+                    mRule.getCronetEngine().newUrlRequestBuilder(
+                            urlString, callback, callback.getExecutor());
             requestBuilder.build().start();
             callback.blockForDone();
-            assertSuccessfulNonEmptyResponse(callback, urlString);
+            NativeCronetTestRule.assertSuccessfulNonEmptyResponse(callback, urlString);
             if (callback.getResponseInfo().getNegotiatedProtocol().startsWith("http/2+quic/")) {
                 quicNegotiated = true;
                 break;
             }
         }
-        assertTrue(quicNegotiated);
+        Assert.assertTrue(quicNegotiated);
     }
 }
diff --git a/components/cronet/cronet_prefs_manager.cc b/components/cronet/cronet_prefs_manager.cc
index 32acc7bb..953cdf6 100644
--- a/components/cronet/cronet_prefs_manager.cc
+++ b/components/cronet/cronet_prefs_manager.cc
@@ -292,11 +292,6 @@
   http_server_properties_manager_->ShutdownOnPrefSequence();
   if (network_qualities_prefs_manager_)
     network_qualities_prefs_manager_->ShutdownOnPrefSequence();
-
-  // TODO(crbug.com/758711): revisit to see whether the logic can be simplified
-  // after SDCH is removed. Destroy |host_cache_persistence_manager_| before the
-  // caller destroys UrlRequestContext.
-  host_cache_persistence_manager_.reset(nullptr);
 }
 
 }  // namespace cronet
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
index 1431d73..0287c95 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
@@ -13,6 +13,7 @@
 #include "base/stl_util.h"
 #include "base/task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/timer/timer.h"
 #include "components/cryptauth/connection_finder.h"
 #include "components/cryptauth/wire_message.h"
 #include "components/proximity_auth/logging/logging.h"
@@ -36,8 +37,11 @@
 // each message gets 3 attempts: the first one, and 2 retries.
 const int kMaxNumberOfRetryAttempts = 2;
 
-// The time to wait in seconds for the server to send its connection response.
-// If not received within this time, the connection will fail.
+// Timeouts for various status types.
+const int kConnectionLatencyTimeoutSeconds = 2;
+const int kGattConnectionTimeoutSeconds = 15;
+const int kGattCharacteristicsTimeoutSeconds = 10;
+const int kNotifySessionTimeoutSeconds = 5;
 const int kConnectionResponseTimeoutSeconds = 2;
 
 }  // namespace
@@ -77,11 +81,51 @@
       remote_device, device_address, adapter, remote_service_uuid);
 }
 
-BluetoothLowEnergyWeaveClientConnection::TimerFactory::~TimerFactory() {}
+// static
+base::TimeDelta BluetoothLowEnergyWeaveClientConnection::GetTimeoutForSubStatus(
+    SubStatus sub_status) {
+  switch (sub_status) {
+    case SubStatus::WAITING_CONNECTION_RESPONSE:
+      return base::TimeDelta::FromSeconds(kConnectionLatencyTimeoutSeconds);
+    case SubStatus::WAITING_CONNECTION_LATENCY:
+      return base::TimeDelta::FromSeconds(kGattConnectionTimeoutSeconds);
+    case SubStatus::WAITING_GATT_CONNECTION:
+      return base::TimeDelta::FromSeconds(kGattCharacteristicsTimeoutSeconds);
+    case SubStatus::WAITING_CHARACTERISTICS:
+      return base::TimeDelta::FromSeconds(kNotifySessionTimeoutSeconds);
+    case SubStatus::WAITING_NOTIFY_SESSION:
+      return base::TimeDelta::FromSeconds(kConnectionResponseTimeoutSeconds);
+    default:
+      // Max signifies that there should be no timeout.
+      return base::TimeDelta::Max();
+  }
+}
 
-std::unique_ptr<base::Timer>
-BluetoothLowEnergyWeaveClientConnection::TimerFactory::CreateTimer() {
-  return base::MakeUnique<base::OneShotTimer>();
+// static
+std::string BluetoothLowEnergyWeaveClientConnection::SubStatusToString(
+    SubStatus sub_status) {
+  switch (sub_status) {
+    case SubStatus::DISCONNECTED:
+      return "[disconnected]";
+    case SubStatus::WAITING_CONNECTION_LATENCY:
+      return "[waiting to set connection latency]";
+    case SubStatus::WAITING_GATT_CONNECTION:
+      return "[waiting for GATT connection to be created]";
+    case SubStatus::WAITING_CHARACTERISTICS:
+      return "[waiting for GATT characteristics to be found]";
+    case SubStatus::CHARACTERISTICS_FOUND:
+      return "[GATT characteristics have been found]";
+    case SubStatus::WAITING_NOTIFY_SESSION:
+      return "[waiting for notify session to begin]";
+    case SubStatus::NOTIFY_SESSION_READY:
+      return "[notify session is ready]";
+    case SubStatus::WAITING_CONNECTION_RESPONSE:
+      return "[waiting for \"connection response\" uWeave packet]";
+    case SubStatus::CONNECTED:
+      return "[connected]";
+    default:
+      return "[invalid state]";
+  }
 }
 
 BluetoothLowEnergyWeaveClientConnection::
@@ -102,8 +146,8 @@
           {device::BluetoothUUID(kTXCharacteristicUUID), std::string()}),
       rx_characteristic_(
           {device::BluetoothUUID(kRXCharacteristicUUID), std::string()}),
-      timer_factory_(base::MakeUnique<TimerFactory>()),
       task_runner_(base::ThreadTaskRunnerHandle::Get()),
+      timer_(base::MakeUnique<base::OneShotTimer>()),
       sub_status_(SubStatus::DISCONNECTED),
       weak_ptr_factory_(this) {
   adapter_->AddObserver(this);
@@ -195,6 +239,16 @@
 void BluetoothLowEnergyWeaveClientConnection::SetSubStatus(
     SubStatus new_sub_status) {
   sub_status_ = new_sub_status;
+  timer_->Stop();
+
+  base::TimeDelta timeout_for_sub_status = GetTimeoutForSubStatus(sub_status_);
+  if (!timeout_for_sub_status.is_max()) {
+    timer_->Start(
+        FROM_HERE, timeout_for_sub_status,
+        base::Bind(
+            &BluetoothLowEnergyWeaveClientConnection::OnTimeoutForSubStatus,
+            weak_ptr_factory_.GetWeakPtr(), sub_status_));
+  }
 
   // Sets the status of base class Connection.
   if (new_sub_status == SubStatus::CONNECTED)
@@ -205,13 +259,23 @@
     SetStatus(Status::IN_PROGRESS);
 }
 
+void BluetoothLowEnergyWeaveClientConnection::OnTimeoutForSubStatus(
+    SubStatus status) {
+  // Ensure that |sub_status| is still the active status.
+  DCHECK(status == sub_status());
+
+  PA_LOG(ERROR) << "Timed out waiting during SubStatus "
+                << SubStatusToString(status) << ". Destroying connection.";
+  DestroyConnection();
+}
+
 void BluetoothLowEnergyWeaveClientConnection::SetupTestDoubles(
     scoped_refptr<base::TaskRunner> test_task_runner,
-    std::unique_ptr<TimerFactory> test_timer_factory,
+    std::unique_ptr<base::Timer> test_timer,
     std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> test_generator,
     std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver> test_receiver) {
   task_runner_ = test_task_runner;
-  timer_factory_ = std::move(test_timer_factory);
+  timer_ = std::move(test_timer);
   packet_generator_ = std::move(test_generator);
   packet_receiver_ = std::move(test_receiver);
 }
@@ -325,7 +389,6 @@
 void BluetoothLowEnergyWeaveClientConnection::CompleteConnection() {
   DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_RESPONSE);
   SetSubStatus(SubStatus::CONNECTED);
-  connection_response_timer_->Stop();
 
   uint16_t max_packet_size = packet_receiver_->GetMaxPacketSize();
   PA_LOG(INFO) << "Received uWeave \"connection response\" packet; connection "
@@ -477,13 +540,6 @@
 
   PA_LOG(INFO) << "Sending \"connection request\" uWeave packet to "
                << GetDeviceInfoLogString();
-  connection_response_timer_ = timer_factory_->CreateTimer();
-  connection_response_timer_->Start(
-      FROM_HERE,
-      base::TimeDelta::FromSeconds(kConnectionResponseTimeoutSeconds),
-      base::Bind(
-          &BluetoothLowEnergyWeaveClientConnection::OnConnectionResponseTimeout,
-          weak_ptr_factory_.GetWeakPtr()));
 
   queued_write_requests_.emplace(base::MakeUnique<WriteRequest>(
       packet_generator_->CreateConnectionRequest(),
@@ -656,14 +712,6 @@
   ProcessNextWriteRequest();
 }
 
-void BluetoothLowEnergyWeaveClientConnection::OnConnectionResponseTimeout() {
-  DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_RESPONSE);
-  PA_LOG(ERROR) << "Timed out waiting for \"connection response\" uWeave "
-                << "packet from " << GetDeviceInfoLogString()
-                << ". Destroying connection.";
-  DestroyConnection();
-}
-
 std::string BluetoothLowEnergyWeaveClientConnection::GetDeviceAddress() {
   // When the remote device is connected, rely on the address given by
   // |gatt_connection_|. Unpaired BLE device addresses are ephemeral and are
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
index 7eb0f4bf..897d7f6 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
@@ -73,15 +73,6 @@
     static Factory* factory_instance_;
   };
 
-  // TODO(thakis): It looks like this could be stack-allocated and passed by
-  // pointer instead of by unique_ptr, removing the need for a virtual dtor.
-  class TimerFactory {
-   public:
-    virtual ~TimerFactory();
-
-    virtual std::unique_ptr<base::Timer> CreateTimer();
-  };
-
   enum SubStatus {
     DISCONNECTED,
     WAITING_CONNECTION_LATENCY,
@@ -119,7 +110,7 @@
 
   void SetupTestDoubles(
       scoped_refptr<base::TaskRunner> test_task_runner,
-      std::unique_ptr<TimerFactory> test_timer_factory,
+      std::unique_ptr<base::Timer> test_timer,
       std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> test_generator,
       std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver> test_receiver);
 
@@ -168,9 +159,16 @@
     int number_of_failed_attempts = 0;
   };
 
+  static std::string SubStatusToString(SubStatus sub_status);
+
+  // Returns the timeout for the given SubStatus. If no timeout is needed for
+  // |sub_status|, base::TimeDelta::Max() is returned.
+  static base::TimeDelta GetTimeoutForSubStatus(SubStatus sub_status);
+
   // Sets the current status; if |status| corresponds to one of Connection's
   // Status types, observers will be notified of the change.
   void SetSubStatus(SubStatus status);
+  void OnTimeoutForSubStatus(SubStatus status);
 
   // These functions are used to set up the connection so that it is ready to
   // send/receive data.
@@ -194,7 +192,6 @@
   // Sends the connection request message (the first message in the uWeave
   // handshake).
   void SendConnectionRequest();
-  void OnConnectionResponseTimeout();
 
   // Completes and updates the status accordingly.
   void CompleteConnection();
@@ -231,9 +228,8 @@
   std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver> packet_receiver_;
   RemoteAttribute tx_characteristic_;
   RemoteAttribute rx_characteristic_;
-  std::unique_ptr<TimerFactory> timer_factory_;
   scoped_refptr<base::TaskRunner> task_runner_;
-  std::unique_ptr<base::Timer> connection_response_timer_;
+  std::unique_ptr<base::Timer> timer_;
 
   // These pointers start out null and are created during the connection
   // process.
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
index dde2225..87333d3 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
@@ -205,21 +205,6 @@
   ReasonForClose reason_to_close_;
 };
 
-class TestTimerFactory final
-    : public BluetoothLowEnergyWeaveClientConnection::TimerFactory {
- public:
-  std::unique_ptr<base::Timer> CreateTimer() override {
-    last_created_timer_ = new base::MockTimer(false /* retains_user_task */,
-                                              false /* is_repeating */);
-    return base::WrapUnique(last_created_timer_);
-  }
-
-  base::MockTimer* last_created_timer() { return last_created_timer_; }
-
- private:
-  base::MockTimer* last_created_timer_;
-};
-
 class TestBluetoothLowEnergyWeaveClientConnection
     : public BluetoothLowEnergyWeaveClientConnection {
  public:
@@ -336,7 +321,7 @@
   ~CryptAuthBluetoothLowEnergyWeaveClientConnectionTest() override {}
 
   void SetUp() override {
-    test_timer_factory_ = nullptr;
+    test_timer_ = nullptr;
     generator_ = nullptr;
     receiver_ = nullptr;
 
@@ -397,12 +382,13 @@
         base::WrapUnique(new MockConnectionObserver(connection.get()));
     connection->AddObserver(connection_observer_.get());
 
-    test_timer_factory_ = new TestTimerFactory();
+    test_timer_ = new base::MockTimer(false /* retains_user_task */,
+                                      false /* is_repeating */);
     generator_ = new NiceMock<MockBluetoothLowEnergyWeavePacketGenerator>();
     receiver_ = new NiceMock<MockBluetoothLowEnergyWeavePacketReceiver>();
-    connection->SetupTestDoubles(
-        task_runner_, base::WrapUnique(test_timer_factory_),
-        base::WrapUnique(generator_), base::WrapUnique(receiver_));
+    connection->SetupTestDoubles(task_runner_, base::WrapUnique(test_timer_),
+                                 base::WrapUnique(generator_),
+                                 base::WrapUnique(receiver_));
 
     return connection;
   }
@@ -575,7 +561,7 @@
   const proximity_auth::ScopedDisableLoggingForTesting disable_logging_;
 
   scoped_refptr<device::MockBluetoothAdapter> adapter_;
-  TestTimerFactory* test_timer_factory_;
+  base::MockTimer* test_timer_;
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
 
   std::unique_ptr<device::MockBluetoothDevice> mock_bluetooth_device_;
@@ -1168,14 +1154,106 @@
 }
 
 TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
-       ConnectionResponseTimeout) {
+       Timeout_ConnectionLatency) {
+  std::unique_ptr<TestBluetoothLowEnergyWeaveClientConnection> connection(
+      CreateConnection());
+
+  EXPECT_CALL(*mock_bluetooth_device_,
+              SetConnectionLatency(
+                  device::BluetoothDevice::CONNECTION_LATENCY_LOW, _, _))
+      .WillOnce(DoAll(SaveArg<1>(&connection_latency_callback_),
+                      SaveArg<2>(&connection_latency_error_callback_)));
+
+  // Call Connect(), which should set the connection latency.
+  connection->Connect();
+  EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_CONNECTION_LATENCY);
+  EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
+  ASSERT_FALSE(connection_latency_callback_.is_null());
+  ASSERT_FALSE(connection_latency_error_callback_.is_null());
+
+  // Simulate a timeout.
+  test_timer_->Fire();
+
+  EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
+  EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
+}
+
+TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
+       Timeout_GattConnection) {
+  std::unique_ptr<TestBluetoothLowEnergyWeaveClientConnection> connection(
+      CreateConnection());
+
+  EXPECT_CALL(*mock_bluetooth_device_,
+              SetConnectionLatency(
+                  device::BluetoothDevice::CONNECTION_LATENCY_LOW, _, _))
+      .WillOnce(DoAll(SaveArg<1>(&connection_latency_callback_),
+                      SaveArg<2>(&connection_latency_error_callback_)));
+
+  // Preparing |connection| for a CreateGattConnection call.
+  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection(_, _))
+      .WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_),
+                      SaveArg<1>(&create_gatt_connection_error_callback_)));
+
+  connection->Connect();
+
+  // Handle setting the connection latency.
+  EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_CONNECTION_LATENCY);
+  EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
+  ASSERT_FALSE(connection_latency_callback_.is_null());
+  ASSERT_FALSE(connection_latency_error_callback_.is_null());
+  connection_latency_callback_.Run();
+
+  EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_GATT_CONNECTION);
+  EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
+
+  // Simulate a timeout.
+  test_timer_->Fire();
+
+  EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
+  EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
+}
+
+TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
+       Timeout_GattCharacteristics) {
+  std::unique_ptr<TestBluetoothLowEnergyWeaveClientConnection> connection(
+      CreateConnection());
+  ConnectGatt(connection.get());
+  EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_CHARACTERISTICS);
+  EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
+
+  // Simulate a timeout.
+  test_timer_->Fire();
+
+  EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
+  EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
+}
+
+TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
+       Timeout_NotifySession) {
+  std::unique_ptr<TestBluetoothLowEnergyWeaveClientConnection> connection(
+      CreateConnection());
+  ConnectGatt(connection.get());
+  CharacteristicsFound(connection.get());
+  EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_NOTIFY_SESSION);
+  EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
+
+  // Simulate a timeout.
+  test_timer_->Fire();
+
+  EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
+  EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
+}
+
+TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
+       Timeout_ConnectionResponse) {
   std::unique_ptr<TestBluetoothLowEnergyWeaveClientConnection> connection(
       CreateConnection());
   ConnectGatt(connection.get());
   CharacteristicsFound(connection.get());
   NotifySessionStarted(connection.get());
 
-  test_timer_factory_->last_created_timer()->Fire();
+  // Simulate a timeout.
+  test_timer_->Fire();
 
   EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
   EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
diff --git a/components/cryptauth/cryptauth_device_manager.cc b/components/cryptauth/cryptauth_device_manager.cc
index b461cd2..6dc5122 100644
--- a/components/cryptauth/cryptauth_device_manager.cc
+++ b/components/cryptauth/cryptauth_device_manager.cc
@@ -46,6 +46,8 @@
     "mobile_hotspot_supported";
 const char kExternalDeviceKeyDeviceType[] = "device_type";
 const char kExternalDeviceKeyBeaconSeeds[] = "beacon_seeds";
+const char kExternalDeviceKeyArcPlusPlus[] = "arc_plus_plus";
+const char kExternalDeviceKeyPixelPhone[] = "pixel_phone";
 const char kExternalDeviceKeyBeaconSeedData[] = "beacon_seed_data";
 const char kExternalDeviceKeyBeaconSeedStartMs[] = "beacon_seed_start_ms";
 const char kExternalDeviceKeyBeaconSeedEndMs[] = "beacon_seed_end_ms";
@@ -156,6 +158,15 @@
                            device.device_type());
   }
 
+  if (device.has_arc_plus_plus()) {
+    dictionary->SetInteger(kExternalDeviceKeyArcPlusPlus,
+                           device.arc_plus_plus());
+  }
+
+  if (device.has_pixel_phone()) {
+    dictionary->SetInteger(kExternalDeviceKeyPixelPhone, device.pixel_phone());
+  }
+
   std::unique_ptr<base::ListValue> beacon_seed_list =
       BeaconSeedsToListValue(device.beacon_seeds());
   dictionary->Set(kExternalDeviceKeyBeaconSeeds, std::move(beacon_seed_list));
@@ -254,14 +265,12 @@
   }
 
   bool unlock_key;
-  if (dictionary.GetBoolean(kExternalDeviceKeyUnlockKey, &unlock_key)) {
+  if (dictionary.GetBoolean(kExternalDeviceKeyUnlockKey, &unlock_key))
     external_device->set_unlock_key(unlock_key);
-  }
 
   bool unlockable;
-  if (dictionary.GetBoolean(kExternalDeviceKeyUnlockable, &unlockable)) {
+  if (dictionary.GetBoolean(kExternalDeviceKeyUnlockable, &unlockable))
     external_device->set_unlockable(unlockable);
-  }
 
   std::string last_update_time_millis_str;
   if (dictionary.GetString(
@@ -291,9 +300,16 @@
 
   const base::ListValue* beacon_seeds = nullptr;
   dictionary.GetList(kExternalDeviceKeyBeaconSeeds, &beacon_seeds);
-  if (beacon_seeds) {
+  if (beacon_seeds)
     AddBeaconSeedsToExternalDevice(*beacon_seeds, *external_device);
-  }
+
+  bool arc_plus_plus;
+  if (dictionary.GetBoolean(kExternalDeviceKeyArcPlusPlus, &arc_plus_plus))
+    external_device->set_arc_plus_plus(arc_plus_plus);
+
+  bool pixel_phone;
+  if (dictionary.GetBoolean(kExternalDeviceKeyPixelPhone, &pixel_phone))
+    external_device->set_pixel_phone(pixel_phone);
 
   return true;
 }
@@ -433,6 +449,17 @@
   return unlock_keys;
 }
 
+std::vector<ExternalDeviceInfo> CryptAuthDeviceManager::GetPixelUnlockKeys()
+    const {
+  std::vector<ExternalDeviceInfo> unlock_keys;
+  for (const auto& device : synced_devices_) {
+    if (device.unlock_key() && device.pixel_phone()) {
+      unlock_keys.push_back(device);
+    }
+  }
+  return unlock_keys;
+}
+
 std::vector<ExternalDeviceInfo> CryptAuthDeviceManager::GetTetherHosts() const {
   std::vector<ExternalDeviceInfo> tether_hosts;
   for (const auto& device : synced_devices_) {
@@ -443,6 +470,17 @@
   return tether_hosts;
 }
 
+std::vector<ExternalDeviceInfo> CryptAuthDeviceManager::GetPixelTetherHosts()
+    const {
+  std::vector<ExternalDeviceInfo> tether_hosts;
+  for (const auto& device : synced_devices_) {
+    if (device.mobile_hotspot_supported() && device.pixel_phone()) {
+      tether_hosts.push_back(device);
+    }
+  }
+  return tether_hosts;
+}
+
 void CryptAuthDeviceManager::OnGetMyDevicesSuccess(
     const GetMyDevicesResponse& response) {
   // Update the synced devices stored in the user's prefs.
diff --git a/components/cryptauth/cryptauth_device_manager.h b/components/cryptauth/cryptauth_device_manager.h
index 72ea69e9..c71995b 100644
--- a/components/cryptauth/cryptauth_device_manager.h
+++ b/components/cryptauth/cryptauth_device_manager.h
@@ -110,9 +110,13 @@
 
   // Returns a list of remote devices that can unlock the user's other devices.
   virtual std::vector<ExternalDeviceInfo> GetUnlockKeys() const;
+  // Like GetUnlockKeys(), but only returns Pixel devices.
+  virtual std::vector<ExternalDeviceInfo> GetPixelUnlockKeys() const;
 
   // Returns a list of remote devices that can host tether hotspots.
   virtual std::vector<ExternalDeviceInfo> GetTetherHosts() const;
+  // Like GetTetherHosts(), but only returns Pixel devices.
+  virtual std::vector<ExternalDeviceInfo> GetPixelTetherHosts() const;
 
  protected:
   // Empty constructor, to be used by tests to mock the device manager. Do not
diff --git a/components/cryptauth/cryptauth_device_manager_unittest.cc b/components/cryptauth/cryptauth_device_manager_unittest.cc
index 276e050..ec960e0 100644
--- a/components/cryptauth/cryptauth_device_manager_unittest.cc
+++ b/components/cryptauth/cryptauth_device_manager_unittest.cc
@@ -53,7 +53,7 @@
 
 // ExternalDeviceInfo fields for the synced unlock key.
 const char kPublicKey1[] = "GOOG";
-const char kDeviceName1[] = "Nexus 5";
+const char kDeviceName1[] = "Pixel XL";
 const char kBluetoothAddress1[] = "aa:bb:cc:ee:dd:ff";
 const bool kUnlockKey1 = true;
 const bool kUnlockable1 = false;
@@ -64,6 +64,8 @@
 const char kBeaconSeed2Data[] = "beaconSeed2Data";
 const int64_t kBeaconSeed2StartTime = 234567;
 const int64_t kBeaconSeed2EndTime = 234568;
+const bool kArcPlusPlus1 = true;
+const bool kPixelPhone1 = true;
 
 // ExternalDeviceInfo fields for a non-synced unlockable device.
 const char kPublicKey2[] = "MSFT";
@@ -77,6 +79,8 @@
 const char kBeaconSeed4Data[] = "beaconSeed4Data";
 const int64_t kBeaconSeed4StartTime = 234567;
 const int64_t kBeaconSeed4EndTime = 234568;
+const bool kArcPlusPlus2 = false;
+const bool kPixelPhone2 = false;
 
 // Validates that |devices| is equal to |expected_devices|.
 void ExpectSyncedDevicesAreEqual(
@@ -351,6 +355,8 @@
     seed2->set_data(kBeaconSeed2Data);
     seed2->set_start_time_millis(kBeaconSeed2StartTime);
     seed2->set_end_time_millis(kBeaconSeed2EndTime);
+    unlock_key.set_arc_plus_plus(kArcPlusPlus1);
+    unlock_key.set_pixel_phone(kPixelPhone1);
     devices_in_response_.push_back(unlock_key);
 
     ExternalDeviceInfo unlockable_device;
@@ -367,6 +373,8 @@
     seed4->set_data(kBeaconSeed4Data);
     seed4->set_start_time_millis(kBeaconSeed4StartTime);
     seed4->set_end_time_millis(kBeaconSeed4EndTime);
+    unlockable_device.set_arc_plus_plus(kArcPlusPlus2);
+    unlockable_device.set_pixel_phone(kPixelPhone2);
     devices_in_response_.push_back(unlockable_device);
   }
 
diff --git a/components/cryptauth/proto/cryptauth_api.proto b/components/cryptauth/proto/cryptauth_api.proto
index 6e2be7e..5672f239 100644
--- a/components/cryptauth/proto/cryptauth_api.proto
+++ b/components/cryptauth/proto/cryptauth_api.proto
@@ -81,6 +81,12 @@
 
   // A list of seeds for EID BLE advertisements targeting this device.
   repeated BeaconSeed beacon_seeds = 9;
+
+  // Whether this device is an ARC++ device enrolled via gmscore.
+  optional bool arc_plus_plus = 10 [default = false];
+
+  // Whether this is a "Pixel Experience" phone.
+  optional bool pixel_phone = 11 [default = false];
 }
 
 // Determine if the calling device is allowed to promote the SmartLock
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
index 0ccabc2e5..7237c278 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -445,10 +445,7 @@
       return BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_4XX;
     }
 
-    // Missing the via header should not trigger bypass if the client is
-    // included in the tamper detection experiment.
-    if (!params::IsIncludedInTamperDetectionExperiment())
-      return BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER;
+    return BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER;
   }
   // There is no bypass event.
   return BYPASS_EVENT_TYPE_MAX;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc
index 81ac820..ee06364 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers_unittest.cc
@@ -620,132 +620,123 @@
 TEST_F(DataReductionProxyHeadersTest, GetDataReductionProxyBypassEventType) {
   const struct {
      const char* headers;
-     bool in_tamper_detection_experiment;
      DataReductionProxyBypassType expected_result;
   } tests[] = {
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: bypass=0\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MEDIUM,
+          BYPASS_EVENT_TYPE_MEDIUM,
       },
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: bypass=1\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_SHORT,
+          BYPASS_EVENT_TYPE_SHORT,
       },
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: bypass=59\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_SHORT,
+          BYPASS_EVENT_TYPE_SHORT,
       },
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: bypass=60\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MEDIUM,
+          BYPASS_EVENT_TYPE_MEDIUM,
       },
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: bypass=300\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MEDIUM,
+          BYPASS_EVENT_TYPE_MEDIUM,
       },
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: bypass=301\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_LONG,
+          BYPASS_EVENT_TYPE_LONG,
       },
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: block-once\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_CURRENT,
+          BYPASS_EVENT_TYPE_CURRENT,
       },
       {
           "HTTP/1.1 500 Internal Server Error\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR,
+          BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR,
       },
       {
           "HTTP/1.1 501 Not Implemented\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MAX,
+          BYPASS_EVENT_TYPE_MAX,
       },
       {
           "HTTP/1.1 502 Bad Gateway\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY,
+          BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY,
       },
       {
           "HTTP/1.1 503 Service Unavailable\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE,
+          BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE,
       },
       {
           "HTTP/1.1 504 Gateway Timeout\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MAX,
+          BYPASS_EVENT_TYPE_MAX,
       },
       {
           "HTTP/1.1 505 HTTP Version Not Supported\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MAX,
+          BYPASS_EVENT_TYPE_MAX,
       },
       {
-          "HTTP/1.1 304 Not Modified\n", false, BYPASS_EVENT_TYPE_MAX,
+          "HTTP/1.1 304 Not Modified\n", BYPASS_EVENT_TYPE_MAX,
       },
       {
-          "HTTP/1.1 200 OK\n", false,
-          BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER,
+          "HTTP/1.1 200 OK\n", BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER,
       },
       {
           "HTTP/1.1 200 OK\n"
           "Chrome-Proxy: bypass=59\n",
-          false, BYPASS_EVENT_TYPE_SHORT,
+          BYPASS_EVENT_TYPE_SHORT,
       },
       {
-          "HTTP/1.1 502 Bad Gateway\n", false,
+          "HTTP/1.1 502 Bad Gateway\n",
           BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY,
       },
       {
           "HTTP/1.1 502 Bad Gateway\n"
           "Chrome-Proxy: bypass=59\n",
-          false, BYPASS_EVENT_TYPE_SHORT,
+          BYPASS_EVENT_TYPE_SHORT,
       },
       {
           "HTTP/1.1 502 Bad Gateway\n"
           "Chrome-Proxy: bypass=59\n",
-          false, BYPASS_EVENT_TYPE_SHORT,
+          BYPASS_EVENT_TYPE_SHORT,
       },
       {
-          "HTTP/1.1 414 Request-URI Too Long\n", false,
+          "HTTP/1.1 414 Request-URI Too Long\n",
           BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_4XX,
       },
       {
           "HTTP/1.1 414 Request-URI Too Long\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MAX,
+          BYPASS_EVENT_TYPE_MAX,
       },
       {
-          "HTTP/1.1 407 Proxy Authentication Required\n", false,
+          "HTTP/1.1 407 Proxy Authentication Required\n",
           BYPASS_EVENT_TYPE_MALFORMED_407,
       },
       {
           "HTTP/1.1 407 Proxy Authentication Required\n"
           "Proxy-Authenticate: Basic\n"
           "Via: 1.1 Chrome-Compression-Proxy\n",
-          false, BYPASS_EVENT_TYPE_MAX,
-      },
-      {
-          "HTTP/1.1 200 OK\n", true, BYPASS_EVENT_TYPE_MAX,
-      },
-      {
-          "HTTP/1.1 414 Request-URI Too Long\n", true,
-          BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_4XX,
+          BYPASS_EVENT_TYPE_MAX,
       }};
   for (size_t i = 0; i < arraysize(tests); ++i) {
     std::string headers(tests[i].headers);
@@ -754,12 +745,6 @@
         new net::HttpResponseHeaders(headers));
     DataReductionProxyInfo chrome_proxy_info;
 
-    base::FieldTrialList trial_list(nullptr);
-    base::FieldTrialList::CreateFieldTrial(
-        "DataReductionProxyServerExperiments",
-        tests[i].in_tamper_detection_experiment ? "TamperDetection_Enabled"
-                                                : "TamperDetection_Disabled");
-
     EXPECT_EQ(tests[i].expected_result,
               GetDataReductionProxyBypassType(std::vector<GURL>(), *parsed,
                                               &chrome_proxy_info));
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
index 34b5d9f..35e47f7 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -148,12 +148,6 @@
          base::FieldTrialList::FindFullName(kServerExperimentsFieldTrial)
                  .find(kDisabled) != 0;
 }
-bool IsIncludedInTamperDetectionExperiment() {
-  return IsIncludedInServerExperimentsFieldTrial() &&
-         base::StartsWith(
-             base::FieldTrialList::FindFullName(kServerExperimentsFieldTrial),
-             "TamperDetection_Enabled", base::CompareCase::SENSITIVE);
-}
 
 bool FetchWarmupURLEnabled() {
   // Fetching of the warmup URL can be enabled only for Enabled* and Control*
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
index 73c9498..c79e62b 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -64,9 +64,6 @@
 // server experiments for the data reduction proxy.
 bool IsIncludedInServerExperimentsFieldTrial();
 
-// Returns true if this client is part of the tamper detection experiment.
-bool IsIncludedInTamperDetectionExperiment();
-
 // Returns true if this client has any of the values to enable Lo-Fi mode for
 // the "data-reduction-proxy-lo-fi" command line switch. This includes the
 // "always-on", "cellular-only", and "slow-connections-only" values.
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
index 4eb560f9..9a18e34b 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -205,48 +205,6 @@
   }
 }
 
-TEST_F(DataReductionProxyParamsTest, IsTamperDetectionEnabled) {
-  const struct {
-    std::string test_case;
-    std::string trial_group_value;
-    bool disable_flag_set;
-    bool expected;
-  } tests[] = {
-      {
-          "Field trial not set", "", false, false,
-      },
-      {
-          "Field trial not set, flag set", "", true, false,
-      },
-      {
-          "Enabled", "Enabled", false, false,
-      },
-      {
-          "TamperDetection_Enabled but disabled via flag",
-          "TamperDetection_Enabled", true, false,
-      },
-      {
-          "TamperDetection_Enabled", "TamperDetection_Enabled", false, true,
-      },
-  };
-
-  for (const auto& test : tests) {
-    base::FieldTrialList field_trial_list(nullptr);
-    if (!test.trial_group_value.empty()) {
-      ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
-          "DataReductionProxyServerExperiments", test.trial_group_value));
-    }
-
-    base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
-    if (test.disable_flag_set) {
-      base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-          switches::kDataReductionProxyServerExperimentsDisabled, "");
-    }
-    EXPECT_EQ(test.expected, params::IsIncludedInTamperDetectionExperiment())
-        << test.test_case;
-  }
-}
-
 // Tests if the QUIC field trial is set correctly.
 TEST_F(DataReductionProxyParamsTest, QuicFieldTrial) {
   const struct {
diff --git a/components/metrics/proto/cast_logs.proto b/components/metrics/proto/cast_logs.proto
index 738f7047..055929a 100644
--- a/components/metrics/proto/cast_logs.proto
+++ b/components/metrics/proto/cast_logs.proto
@@ -15,7 +15,7 @@
 // Next tag: 7
 message CastLogsProto {
   // Cast specific device information.
-  // Next tag: 6
+  // Next tag: 7
   message CastDeviceInfo {
     // The product type of Cast device sent from Cast-enabled devices.
     // Next tag: 8
@@ -43,6 +43,15 @@
 
     // The serial number.
     optional string serial_number = 5;
+
+    // Hardware information of the device.
+    message HardwareInfo {
+      optional string color = 1;
+      optional string mic = 2;
+      optional string memory = 3;
+      optional string nand = 4;
+    }
+    optional HardwareInfo hardware_info = 6;
   }
   // The device sends this information at least once per day.
   optional CastDeviceInfo cast_device_info = 1;
diff --git a/components/offline_pages/core/BUILD.gn b/components/offline_pages/core/BUILD.gn
index 330af844..0f7c93c 100644
--- a/components/offline_pages/core/BUILD.gn
+++ b/components/offline_pages/core/BUILD.gn
@@ -18,6 +18,8 @@
     "client_policy_controller.h",
     "model/add_page_task.cc",
     "model/add_page_task.h",
+    "model/create_archive_task.cc",
+    "model/create_archive_task.h",
     "model/offline_store_utils.cc",
     "model/offline_store_utils.h",
     "offline_event_logger.cc",
@@ -107,6 +109,7 @@
   sources = [
     "archive_manager_unittest.cc",
     "client_policy_controller_unittest.cc",
+    "model/create_archive_task_unittest.cc",
     "offline_event_logger_unittest.cc",
     "offline_page_metadata_store_unittest.cc",
     "offline_page_model_event_logger_unittest.cc",
diff --git a/components/offline_pages/core/model/create_archive_task.cc b/components/offline_pages/core/model/create_archive_task.cc
new file mode 100644
index 0000000..33ff3b6
--- /dev/null
+++ b/components/offline_pages/core/model/create_archive_task.cc
@@ -0,0 +1,95 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/offline_pages/core/model/create_archive_task.h"
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/time/default_clock.h"
+#include "components/offline_pages/core/model/offline_store_utils.h"
+#include "components/offline_pages/core/offline_page_model.h"
+
+namespace offline_pages {
+
+using ArchiverResult = OfflinePageArchiver::ArchiverResult;
+
+CreateArchiveTask::CreateArchiveTask(
+    const base::FilePath& archives_dir,
+    const OfflinePageModel::SavePageParams& save_page_params,
+    OfflinePageArchiver* archiver,
+    const CreateArchiveTaskCallback& callback)
+    : archives_dir_(archives_dir),
+      save_page_params_(save_page_params),
+      archiver_(archiver),
+      callback_(callback),
+      clock_(new base::DefaultClock()),
+      skip_clearing_original_url_for_testing_(false) {}
+
+CreateArchiveTask::~CreateArchiveTask() {}
+
+void CreateArchiveTask::Run() {
+  CreateArchive();
+}
+
+void CreateArchiveTask::CreateArchive() {
+  OfflinePageItem proposed_page;
+  // Skip saving the page that is not intended to be saved, like local file
+  // page.
+  if (!OfflinePageModel::CanSaveURL(save_page_params_.url)) {
+    InformCreateArchiveFailed(ArchiverResult::ERROR_SKIPPED);
+    return;
+  }
+
+  // The web contents is not available if archiver is not created and passed.
+  if (!archiver_) {
+    InformCreateArchiveFailed(ArchiverResult::ERROR_CONTENT_UNAVAILABLE);
+    return;
+  }
+
+  // If we already have an offline id, use it. If not, generate one.
+  int64_t offline_id = save_page_params_.proposed_offline_id;
+  if (offline_id == OfflinePageModel::kInvalidOfflineId)
+    offline_id = OfflineStoreUtils::GenerateOfflineId();
+
+  // Create a proposed OfflinePageItem to pass in callback, the page will be
+  // missing fields, which are going to be filled when the archive creation
+  // finishes.
+  proposed_page.url = save_page_params_.url;
+  proposed_page.offline_id = offline_id;
+  proposed_page.client_id = save_page_params_.client_id;
+  proposed_page.creation_time = clock_->Now();
+  proposed_page.request_origin = save_page_params_.request_origin;
+
+  // Don't record the original URL if it is identical to the final URL. This is
+  // because some websites might route the redirect finally back to itself upon
+  // the completion of certain action, i.e., authentication, in the middle.
+  if (skip_clearing_original_url_for_testing_ ||
+      save_page_params_.original_url != proposed_page.url) {
+    proposed_page.original_url = save_page_params_.original_url;
+  }
+
+  OfflinePageArchiver::CreateArchiveParams create_archive_params;
+  // If the page is being saved in the background, we should try to remove the
+  // popup overlay that obstructs viewing the normal content.
+  create_archive_params.remove_popup_overlay = save_page_params_.is_background;
+  create_archive_params.use_page_problem_detectors =
+      save_page_params_.use_page_problem_detectors;
+  archiver_->CreateArchive(archives_dir_, create_archive_params,
+                           base::Bind(callback_, proposed_page));
+
+  // The task will complete here, and the callback will be called once the
+  // |archiver_| is done with the archive creation. This enables multiple
+  // archive creation going on by not blocking the TaskQueue waiting for the
+  // completion.
+  TaskComplete();
+}
+
+void CreateArchiveTask::InformCreateArchiveFailed(ArchiverResult result) {
+  callback_.Run(OfflinePageItem(), archiver_, result, GURL(), base::FilePath(),
+                base::string16(), 0);
+  TaskComplete();
+}
+
+}  // namespace offline_pages
diff --git a/components/offline_pages/core/model/create_archive_task.h b/components/offline_pages/core/model/create_archive_task.h
new file mode 100644
index 0000000..38f1806b
--- /dev/null
+++ b/components/offline_pages/core/model/create_archive_task.h
@@ -0,0 +1,92 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OFFLINE_PAGES_CORE_MODEL_CREATE_ARCHIVE_TASK_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_MODEL_CREATE_ARCHIVE_TASK_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/time/clock.h"
+#include "components/offline_pages/core/offline_page_archiver.h"
+#include "components/offline_pages/core/offline_page_model.h"
+#include "components/offline_pages/core/offline_page_types.h"
+#include "components/offline_pages/core/task.h"
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+namespace offline_pages {
+
+// Task that start an archive creation using the OfflinePageArchiver passed in,
+// along with the SavePageParams.
+// The task will complete before the archive creation actually finishes, in
+// order to allow multiple archivers to work in parallel.
+// The lifetime of the archiver needs to be managed by the caller, this task
+// will not own the archiver. The ownership of the callback passed in will be
+// transferred to the archiver, so that it can still get executed after this
+// task gets destroyed.
+// TODO(romax): Verify that this task is actually needed. If we don't access the
+// database, making this a task seems to much, and it can be simplified as a
+// method.
+class CreateArchiveTask : public Task {
+ public:
+  // The arguments of the callback are (in order):
+  // - Proposed OfflinePageItem, filled with information from SavePageParams,
+  // - Pointer to the archiver.
+  // - ArchiverResult of the archive creation,
+  // - The saved url, which is acquired from the WebContent of the archiver,
+  // - The file path to the saved archive,
+  // - Title of the saved page,
+  // - Size of the saved file.
+  // TODO(romax): simplify the callback and related interface if possible. The
+  // url, path, title and file size can be filled into the OfflinePageItem
+  // during archive creation.
+  typedef base::Callback<void(OfflinePageItem,
+                              OfflinePageArchiver*,
+                              OfflinePageArchiver::ArchiverResult,
+                              const GURL&,
+                              const base::FilePath&,
+                              const base::string16&,
+                              int64_t)>
+      CreateArchiveTaskCallback;
+
+  CreateArchiveTask(const base::FilePath& archives_dir,
+                    const OfflinePageModel::SavePageParams& save_page_params,
+                    OfflinePageArchiver* archiver,
+                    const CreateArchiveTaskCallback& callback);
+  ~CreateArchiveTask() override;
+
+  // Task implementation.
+  void Run() override;
+
+  void set_clock_for_testing(std::unique_ptr<base::Clock> clock) {
+    clock_ = std::move(clock);
+  }
+
+  void set_skip_clearing_original_url_for_testing() {
+    skip_clearing_original_url_for_testing_ = true;
+  }
+
+ private:
+  void CreateArchive();
+  void InformCreateArchiveFailed(OfflinePageArchiver::ArchiverResult result);
+
+  // The directory to save the archive.
+  base::FilePath archives_dir_;
+  OfflinePageModel::SavePageParams save_page_params_;
+  // The archiver used in the task. Not owned.
+  OfflinePageArchiver* archiver_;
+  CreateArchiveTaskCallback callback_;
+  std::unique_ptr<base::Clock> clock_;
+
+  bool skip_clearing_original_url_for_testing_;
+
+  DISALLOW_COPY_AND_ASSIGN(CreateArchiveTask);
+};
+
+}  // namespace offline_pages
+
+#endif  // COMPONENTS_OFFLINE_PAGES_CORE_MODEL_CREATE_ARCHIVE_TASK_H_
diff --git a/components/offline_pages/core/model/create_archive_task_unittest.cc b/components/offline_pages/core/model/create_archive_task_unittest.cc
new file mode 100644
index 0000000..72b76a3
--- /dev/null
+++ b/components/offline_pages/core/model/create_archive_task_unittest.cc
@@ -0,0 +1,412 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/offline_pages/core/model/create_archive_task.h"
+
+#include "base/bind.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/weak_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/offline_pages/core/offline_page_item.h"
+#include "components/offline_pages/core/offline_page_test_archiver.h"
+#include "components/offline_pages/core/offline_page_test_store.h"
+#include "components/offline_pages/core/offline_page_types.h"
+#include "components/offline_pages/core/test_task.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+using ArchiverResult = OfflinePageArchiver::ArchiverResult;
+using SavePageParams = OfflinePageModel::SavePageParams;
+
+namespace {
+const char kTestClientNamespace[] = "default";
+const GURL kTestUrl("http://example.com");
+const GURL kTestUrl2("http://other.page.com");
+const GURL kFileUrl("file:///foo");
+const ClientId kTestClientId1(kTestClientNamespace, "1234");
+const int64_t kTestFileSize = 876543LL;
+const base::string16 kTestTitle = base::UTF8ToUTF16("a title");
+const std::string kRequestOrigin("abc.xyz");
+}  // namespace
+
+class CreateArchiveTaskTest
+    : public testing::Test,
+      public OfflinePageTestArchiver::Observer,
+      public base::SupportsWeakPtr<CreateArchiveTaskTest> {
+ public:
+  CreateArchiveTaskTest();
+  ~CreateArchiveTaskTest() override;
+
+  void SetUp() override;
+
+  // OfflinePageTestArchiver::Observer implementation.
+  void SetLastPathCreatedByArchiver(const base::FilePath& file_path) override;
+
+  void PumpLoop();
+  void ResetResults();
+  void OnCreateArchiveDone(OfflinePageItem offline_page,
+                           OfflinePageArchiver* archiver,
+                           ArchiverResult result,
+                           const GURL& saved_url,
+                           const base::FilePath& file_path,
+                           const base::string16& title,
+                           int64_t file_size);
+  std::unique_ptr<OfflinePageTestArchiver> BuildArchiver(const GURL& url,
+                                                         ArchiverResult result);
+  void CreateArchiveWithParams(const SavePageParams& save_page_params,
+                               OfflinePageArchiver* archiver);
+
+  void CreateArchiveWithArchiver(const GURL& gurl,
+                                 const ClientId& client_id,
+                                 const GURL& original_url,
+                                 const std::string& request_origin,
+                                 OfflinePageArchiver* archiver);
+
+  void CreateArchiveWithResult(const GURL& gurl,
+                               const ClientId& client_id,
+                               const GURL& original_url,
+                               const std::string& request_origin,
+                               ArchiverResult expected_result);
+
+  const base::FilePath& archives_dir() { return temp_dir_.GetPath(); }
+  const OfflinePageItem& last_page_of_archive() {
+    return last_page_of_archive_;
+  }
+  OfflinePageArchiver* last_saved_archiver() { return last_saved_archiver_; }
+  ArchiverResult last_create_archive_result() {
+    return last_create_archive_result_;
+  }
+  const base::FilePath& last_archiver_path() { return last_archiver_path_; }
+  const GURL& last_saved_url() { return last_saved_url_; }
+  const base::FilePath& last_saved_file_path() { return last_saved_file_path_; }
+  const base::string16& last_saved_title() { return last_saved_title_; }
+  int64_t last_saved_file_size() { return last_saved_file_size_; }
+
+ private:
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  base::ThreadTaskRunnerHandle task_runner_handle_;
+  base::ScopedTempDir temp_dir_;
+
+  OfflinePageItem last_page_of_archive_;
+  OfflinePageArchiver* last_saved_archiver_;
+  ArchiverResult last_create_archive_result_;
+  base::FilePath last_archiver_path_;
+  GURL last_saved_url_;
+  base::FilePath last_saved_file_path_;
+  base::string16 last_saved_title_;
+  int64_t last_saved_file_size_;
+  // Owning a task to prevent it being destroyed in the heap when calling
+  // CreateArchiveWithParams, which will lead to a heap-use-after-free on
+  // trybots.
+  std::unique_ptr<CreateArchiveTask> task_;
+};
+
+CreateArchiveTaskTest::CreateArchiveTaskTest()
+    : task_runner_(new base::TestSimpleTaskRunner()),
+      task_runner_handle_(task_runner_) {}
+
+CreateArchiveTaskTest::~CreateArchiveTaskTest() {}
+
+void CreateArchiveTaskTest::SetUp() {
+  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+}
+
+void CreateArchiveTaskTest::SetLastPathCreatedByArchiver(
+    const base::FilePath& file_path) {
+  last_archiver_path_ = file_path;
+}
+
+void CreateArchiveTaskTest::PumpLoop() {
+  task_runner_->RunUntilIdle();
+}
+
+void CreateArchiveTaskTest::ResetResults() {
+  last_create_archive_result_ = ArchiverResult::ERROR_CANCELED;
+  last_page_of_archive_ = OfflinePageItem();
+  last_saved_url_ = GURL();
+  last_saved_file_path_ = base::FilePath();
+  last_saved_title_ = base::string16();
+  last_saved_file_size_ = 0;
+  last_archiver_path_.clear();
+}
+void CreateArchiveTaskTest::OnCreateArchiveDone(OfflinePageItem offline_page,
+                                                OfflinePageArchiver* archiver,
+                                                ArchiverResult result,
+                                                const GURL& saved_url,
+                                                const base::FilePath& file_path,
+                                                const base::string16& title,
+                                                int64_t file_size) {
+  last_page_of_archive_ = offline_page;
+  last_saved_archiver_ = archiver;
+  last_create_archive_result_ = result;
+  last_saved_url_ = saved_url;
+  last_saved_file_path_ = file_path;
+  last_saved_title_ = title;
+  last_saved_file_size_ = file_size;
+}
+
+std::unique_ptr<OfflinePageTestArchiver> CreateArchiveTaskTest::BuildArchiver(
+    const GURL& url,
+    ArchiverResult result) {
+  return std::unique_ptr<OfflinePageTestArchiver>(
+      new OfflinePageTestArchiver(this, url, result, kTestTitle, kTestFileSize,
+                                  base::ThreadTaskRunnerHandle::Get()));
+}
+
+void CreateArchiveTaskTest::CreateArchiveWithParams(
+    const SavePageParams& save_page_params,
+    OfflinePageArchiver* archiver) {
+  task_ = base::MakeUnique<CreateArchiveTask>(
+      archives_dir(), save_page_params, archiver,
+      base::Bind(&CreateArchiveTaskTest::OnCreateArchiveDone, AsWeakPtr()));
+  task_->Run();
+  PumpLoop();
+  // Check if the archiver is the same with the one in the callback.
+  EXPECT_EQ(archiver, last_saved_archiver());
+}
+
+void CreateArchiveTaskTest::CreateArchiveWithArchiver(
+    const GURL& gurl,
+    const ClientId& client_id,
+    const GURL& original_url,
+    const std::string& request_origin,
+    OfflinePageArchiver* archiver) {
+  OfflinePageModel::SavePageParams save_page_params;
+  save_page_params.url = gurl;
+  save_page_params.client_id = client_id;
+  save_page_params.original_url = original_url;
+  save_page_params.is_background = false;
+  save_page_params.request_origin = request_origin;
+  CreateArchiveWithParams(save_page_params, archiver);
+}
+
+void CreateArchiveTaskTest::CreateArchiveWithResult(
+    const GURL& gurl,
+    const ClientId& client_id,
+    const GURL& original_url,
+    const std::string& request_origin,
+    ArchiverResult expected_result) {
+  std::unique_ptr<OfflinePageTestArchiver> archiver(
+      BuildArchiver(gurl, expected_result));
+  CreateArchiveWithArchiver(gurl, client_id, original_url, request_origin,
+                            archiver.get());
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveSuccessful) {
+  CreateArchiveWithResult(
+      kTestUrl, kTestClientId1, kTestUrl2, "",
+      OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED);
+
+  // Check the last result to be successful.
+  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
+  const OfflinePageItem& offline_page = last_page_of_archive();
+
+  // The values will be set during archive creation.
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ(kTestUrl2, offline_page.original_url);
+  EXPECT_EQ("", offline_page.request_origin);
+
+  // The values that will not be set during archive creation, but will be set to
+  // default value in the constructor of OfflinePageItem.
+  EXPECT_EQ(0, offline_page.access_count);
+  EXPECT_EQ(0, offline_page.flags);
+
+  // The values that will not be set during archive creation, but will be in the
+  // CreateArchiveTaskCallback.
+  EXPECT_EQ(last_archiver_path(), last_saved_file_path());
+  EXPECT_EQ(kTestFileSize, last_saved_file_size());
+  EXPECT_EQ(kTestTitle, last_saved_title());
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveSuccessfulWithSameOriginalURL) {
+  // Pass the original URL same as the final URL, the original will be empty in
+  // this case.
+  CreateArchiveWithResult(
+      kTestUrl, kTestClientId1, kTestUrl, "",
+      OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED);
+
+  // Check the last result to be successful.
+  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
+  const OfflinePageItem& offline_page = last_page_of_archive();
+
+  // The original URL should be empty.
+  EXPECT_TRUE(offline_page.original_url.is_empty());
+
+  // The values will be set during archive creation.
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ("", offline_page.request_origin);
+
+  // The values that will not be set during archive creation, but will be set to
+  // default value in the constructor of OfflinePageItem.
+  EXPECT_EQ(0, offline_page.access_count);
+  EXPECT_EQ(0, offline_page.flags);
+
+  // The values that will not be set during archive creation, but will be in the
+  // CreateArchiveTaskCallback.
+  EXPECT_EQ(last_archiver_path(), last_saved_file_path());
+  EXPECT_EQ(kTestFileSize, last_saved_file_size());
+  EXPECT_EQ(kTestTitle, last_saved_title());
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveSuccessfulWithRequestOrigin) {
+  CreateArchiveWithResult(
+      kTestUrl, kTestClientId1, kTestUrl2, kRequestOrigin,
+      OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED);
+
+  // Check the last result to be successful.
+  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
+  const OfflinePageItem& offline_page = last_page_of_archive();
+
+  // The values will be set during archive creation.
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ(kTestUrl2, offline_page.original_url);
+  EXPECT_EQ(kRequestOrigin, offline_page.request_origin);
+
+  // The values that will not be set during archive creation, but will be set to
+  // default value in the constructor of OfflinePageItem.
+  EXPECT_EQ(0, offline_page.access_count);
+  EXPECT_EQ(0, offline_page.flags);
+
+  // The values that will not be set during archive creation, but will be in the
+  // CreateArchiveTaskCallback.
+  EXPECT_EQ(last_archiver_path(), last_saved_file_path());
+  EXPECT_EQ(kTestFileSize, last_saved_file_size());
+  EXPECT_EQ(kTestTitle, last_saved_title());
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverCanceled) {
+  CreateArchiveWithResult(kTestUrl, kTestClientId1, GURL(), "",
+                          OfflinePageArchiver::ArchiverResult::ERROR_CANCELED);
+  EXPECT_EQ(ArchiverResult::ERROR_CANCELED, last_create_archive_result());
+
+  // The values will be set during archive creation.
+  const OfflinePageItem& offline_page = last_page_of_archive();
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ(GURL(), offline_page.original_url);
+  EXPECT_EQ("", offline_page.request_origin);
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverDeviceFull) {
+  CreateArchiveWithResult(
+      kTestUrl, kTestClientId1, GURL(), "",
+      OfflinePageArchiver::ArchiverResult::ERROR_DEVICE_FULL);
+  EXPECT_EQ(ArchiverResult::ERROR_DEVICE_FULL, last_create_archive_result());
+
+  // The values will be set during archive creation.
+  const OfflinePageItem& offline_page = last_page_of_archive();
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ(GURL(), offline_page.original_url);
+  EXPECT_EQ("", offline_page.request_origin);
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverContentUnavailable) {
+  CreateArchiveWithResult(
+      kTestUrl, kTestClientId1, GURL(), "",
+      OfflinePageArchiver::ArchiverResult::ERROR_CONTENT_UNAVAILABLE);
+  EXPECT_EQ(ArchiverResult::ERROR_CONTENT_UNAVAILABLE,
+            last_create_archive_result());
+
+  // The values will be set during archive creation.
+  const OfflinePageItem& offline_page = last_page_of_archive();
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ(GURL(), offline_page.original_url);
+  EXPECT_EQ("", offline_page.request_origin);
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveWithCreationFailed) {
+  CreateArchiveWithResult(
+      kTestUrl, kTestClientId1, GURL(), "",
+      OfflinePageArchiver::ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED);
+  EXPECT_EQ(ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED,
+            last_create_archive_result());
+
+  // The values will be set during archive creation.
+  const OfflinePageItem& offline_page = last_page_of_archive();
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ(GURL(), offline_page.original_url);
+  EXPECT_EQ("", offline_page.request_origin);
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverReturnedWrongUrl) {
+  GURL test_url("http://other.random.url.com");
+  std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
+      test_url, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
+  CreateArchiveWithArchiver(kTestUrl, kTestClientId1, GURL(), "",
+                            archiver.get());
+
+  // Since the task will not judge the result even if the |saved_url| in the
+  // callback is not the same with the SavePageParams.url, so the result will be
+  // SUCCESSFULLY_CREATED, but the |last_saved_url()| will be |test_url|. The
+  // creator of the task will be responsible to detect this failure case.
+  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
+  EXPECT_EQ(test_url, last_saved_url());
+
+  // The values will be set during archive creation.
+  const OfflinePageItem& offline_page = last_page_of_archive();
+  EXPECT_EQ(kTestUrl, offline_page.url);
+  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
+  EXPECT_EQ(kTestClientId1, offline_page.client_id);
+  EXPECT_EQ(GURL(), offline_page.original_url);
+  EXPECT_EQ("", offline_page.request_origin);
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveLocalFileFailed) {
+  // Don't create archiver since it will not be needed for pages that are not
+  // going to be saved.
+  CreateArchiveWithArchiver(kFileUrl, kTestClientId1, GURL(), "", nullptr);
+  EXPECT_EQ(ArchiverResult::ERROR_SKIPPED, last_create_archive_result());
+
+  // Since the return happens before setting the fields, the OfflinePageItem
+  // returned in the callback will be constructed by default ctor.
+  EXPECT_EQ(OfflinePageItem(), last_page_of_archive());
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveFailedWithNullptr) {
+  // Passing in a nullptr intentionally for test.
+  CreateArchiveWithArchiver(kTestUrl, kTestClientId1, GURL(), "", nullptr);
+  EXPECT_EQ(ArchiverResult::ERROR_CONTENT_UNAVAILABLE,
+            last_create_archive_result());
+
+  // Since the return happens before setting the fields, the OfflinePageItem
+  // returned in the callback will be constructed by default ctor.
+  EXPECT_EQ(OfflinePageItem(), last_page_of_archive());
+}
+
+TEST_F(CreateArchiveTaskTest, CreateArchiveInBackground) {
+  std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
+      kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
+  OfflinePageTestArchiver* archiver_ptr = archiver.get();
+
+  OfflinePageModel::SavePageParams save_page_params;
+  save_page_params.url = kTestUrl;
+  save_page_params.client_id = kTestClientId1;
+  save_page_params.is_background = true;
+  save_page_params.use_page_problem_detectors = false;
+
+  CreateArchiveWithParams(save_page_params, archiver_ptr);
+
+  EXPECT_TRUE(archiver_ptr->create_archive_called());
+  // |remove_popup_overlay| should be turned on on background mode.
+  EXPECT_TRUE(archiver_ptr->create_archive_params().remove_popup_overlay);
+}
+
+}  // namespace offline_pages
diff --git a/components/offline_pages/core/model/offline_store_utils.cc b/components/offline_pages/core/model/offline_store_utils.cc
index b1aabdd0..4ca9fa0 100644
--- a/components/offline_pages/core/model/offline_store_utils.cc
+++ b/components/offline_pages/core/model/offline_store_utils.cc
@@ -4,7 +4,10 @@
 
 #include "components/offline_pages/core/model/offline_store_utils.h"
 
+#include <limits>
+
 #include "base/files/file_path.h"
+#include "base/rand_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 
@@ -35,4 +38,9 @@
   }
 }
 
+// static
+int64_t OfflineStoreUtils::GenerateOfflineId() {
+  return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1;
+}
+
 }  // namespace offline_pages
diff --git a/components/offline_pages/core/model/offline_store_utils.h b/components/offline_pages/core/model/offline_store_utils.h
index 2b6c5a35..d5cf55c 100644
--- a/components/offline_pages/core/model/offline_store_utils.h
+++ b/components/offline_pages/core/model/offline_store_utils.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_OFFLINE_PAGES_CORE_MODEL_OFFLINE_STORE_UTILS_H_
 #define COMPONENTS_OFFLINE_PAGES_CORE_MODEL_OFFLINE_STORE_UTILS_H_
 
+#include <stdint.h>
 #include <string>
 
 #include "components/offline_pages/core/offline_page_types.h"
@@ -23,6 +24,9 @@
 
   // Converts an ItemActionStatus to AddPageResult.
   static AddPageResult ItemActionStatusToAddPageResult(ItemActionStatus status);
+
+  // Generates a random offline id;
+  static int64_t GenerateOfflineId();
 };
 
 }  // namespace offline_pages
diff --git a/components/offline_pages/core/offline_page_archiver.h b/components/offline_pages/core/offline_page_archiver.h
index 30dd294..cc5d57c 100644
--- a/components/offline_pages/core/offline_page_archiver.h
+++ b/components/offline_pages/core/offline_page_archiver.h
@@ -36,7 +36,7 @@
 // does not happen.
 //
 // If the page is not completely loaded, it is up to the implementation of the
-// archiver whether to respond with ERROR_CONTENT_UNAVAILBLE, wait longer to
+// archiver whether to respond with ERROR_CONTENT_UNAVAILABLE, wait longer to
 // actually snapshot a complete page, or snapshot whatever is available at that
 // point in time (what the user sees).
 class OfflinePageArchiver {
@@ -52,6 +52,8 @@
                                     // there was a security error.
     ERROR_ERROR_PAGE,               // We detected an error page.
     ERROR_INTERSTITIAL_PAGE,        // We detected an interstitial page.
+    ERROR_SKIPPED,                  // Page shouldn't be archived like NTP or
+                                    // file urls.
   };
 
   // Describes the parameters to control how to create an archive.
diff --git a/components/offline_pages/core/offline_page_item.cc b/components/offline_pages/core/offline_page_item.cc
index 77f5d71..8bfce574 100644
--- a/components/offline_pages/core/offline_page_item.cc
+++ b/components/offline_pages/core/offline_page_item.cc
@@ -7,7 +7,8 @@
 namespace offline_pages {
 
 OfflinePageItem::OfflinePageItem()
-    : file_size(0),
+    : offline_id(0),
+      file_size(0),
       access_count(0),
       flags(NO_FLAG),
       system_download_id(0),
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc
index 8c4542f9..efbb68cd 100644
--- a/components/omnibox/browser/autocomplete_match.cc
+++ b/components/omnibox/browser/autocomplete_match.cc
@@ -514,7 +514,8 @@
   // passed to url::Parsed::CountCharactersBefore has no effect for the PATH.
   size_t path_pos = parsed.CountCharactersBefore(url::Parsed::PATH, false) + 1;
 
-  bool has_subdomain = domain_length < url.host_piece().length();
+  bool has_subdomain =
+      domain_length > 0 && domain_length < url.host_piece().length();
   // Subtract an extra character from the domain start to exclude the '.'
   // delimiter between subdomain and domain.
   size_t subdomain_end =
@@ -523,18 +524,21 @@
 
   for (auto& position : match_positions) {
     // Only flag |match_in_scheme| if the match starts at the very beginning.
-    if (position.first == 0)
+    if (position.first == 0 && parsed.scheme.is_nonempty())
       *match_in_scheme = true;
 
     // Subdomain matches must begin before the domain, and end somewhere within
     // the host or later.
     if (has_subdomain && position.first < subdomain_end &&
-        position.second > host_pos) {
+        position.second > host_pos && parsed.host.is_nonempty()) {
       *match_in_subdomain = true;
     }
 
-    if (position.second > path_pos)
+    if (position.second > path_pos &&
+        (parsed.path.is_nonempty() || parsed.query.is_nonempty() ||
+         parsed.ref.is_nonempty())) {
       *match_after_host = true;
+    }
   }
 }
 
diff --git a/components/omnibox/browser/autocomplete_match.h b/components/omnibox/browser/autocomplete_match.h
index 237f98b..477af10 100644
--- a/components/omnibox/browser/autocomplete_match.h
+++ b/components/omnibox/browser/autocomplete_match.h
@@ -211,7 +211,8 @@
 
   // Sets the |match_in_scheme|, |match_in_subdomain|, and |match_after_host|
   // flags based on the provided |url| and list of substring |match_positions|.
-  // |match_positions| is the [begin, end) positions of a match within a string.
+  // |match_positions| is the [begin, end) positions of a match within the
+  // unstripped URL spec.
   using MatchPosition = std::pair<size_t, size_t>;
   static void GetMatchComponents(
       const GURL& url,
diff --git a/components/omnibox/browser/autocomplete_match_unittest.cc b/components/omnibox/browser/autocomplete_match_unittest.cc
index 0c1b34f..eff7ea9 100644
--- a/components/omnibox/browser/autocomplete_match_unittest.cc
+++ b/components/omnibox/browser/autocomplete_match_unittest.cc
@@ -227,8 +227,10 @@
 
       // Match within the subdomain.
       {"http://www.google.com", {"www"}, false, true, false},
+      {"http://www.google.com", {"www."}, false, true, false},
       // Don't consider matches on the '.' delimiter as a match_in_subdomain.
       {"http://www.google.com", {"."}, false, false, false},
+      {"http://www.google.com", {".goo"}, false, false, false},
       // Matches within the domain.
       {"http://www.google.com", {"goo"}, false, false, false},
       // Verify that in private registries, we detect matches in subdomains.
@@ -248,6 +250,9 @@
       {"http://google.com/abc?def=ghi#jkl", {"bc?def=g"}, false, false, true},
       // Don't consider the '/' delimiter as a match_in_path.
       {"http://google.com/abc?def=ghi#jkl", {"com/"}, false, false, false},
+      // Match on the query and ref only
+      {"http://google.com?def", {"def"}, false, false, true},
+      {"http://google.com#jkl", {"jkl"}, false, false, true},
 
       // Matches spanning the subdomain and path.
       {"http://www.google.com/abc", {"www.google.com/ab"}, false, true, true},
@@ -260,6 +265,14 @@
        true,
        true},
       {"http://www.google.com/abc", {"ht", "ww", "ab"}, true, true, true},
+
+      // Intranet sites.
+      {"http://foobar/biz", {"foobar"}, false, false, false},
+      {"http://foobar/biz", {"biz"}, false, false, true},
+
+      // Ensure something sane happens when the URL input is invalid.
+      {"", {""}, false, false, false},
+      {"foobar", {"bar"}, false, false, false},
   };
   for (auto& test_case : test_cases) {
     SCOPED_TRACE(testing::Message()
diff --git a/components/omnibox/browser/search_suggestion_parser.cc b/components/omnibox/browser/search_suggestion_parser.cc
index 028e9a3..6da449d9 100644
--- a/components/omnibox/browser/search_suggestion_parser.cc
+++ b/components/omnibox/browser/search_suggestion_parser.cc
@@ -282,7 +282,7 @@
   bool match_in_subdomain = false;
   bool match_after_host = false;
   AutocompleteMatch::GetMatchComponents(
-      url_, {{match_start, match_start + input_text.length()}},
+      GURL(formatted_url_), {{match_start, match_start + input_text.length()}},
       &match_in_scheme, &match_in_subdomain, &match_after_host);
   auto format_types = AutocompleteMatch::GetFormatTypes(
       match_in_scheme, match_in_subdomain, match_after_host);
diff --git a/components/onc/docs/onc_spec.md b/components/onc/docs/onc_spec.md
index 4c3e961..4dda4d0 100644
--- a/components/onc/docs/onc_spec.md
+++ b/components/onc/docs/onc_spec.md
@@ -362,6 +362,24 @@
       should not start with a dot. Example: `["corp.acme.org", "acme.org" ]`.
       If not specified, DHCP values will be used.
 
+* **IncludedRoutes**
+    * (optional) - **array of string**
+    * An array of strings, each of which is an IP block in CIDR notation,
+      whose traffic should be handled by the network. Example:
+      `["10.0.0.0/8", "192.168.5.0/24"]`. If **IncludedRoutes** or
+      **ExcludedRoutes** are not specified, this network
+      will be used to handle traffic for all IPs by default. Currently this
+      property only has an effect if the Network **Type** is *VPN* and the
+      VPN **Type** is *ARCVPN*.
+
+* **ExcludedRoutes**
+    * (optional) - **array of string**
+    * An array of strings, each of which is an IP block in CIDR notation,
+      whose traffic should **not** be handled by the network. Example:
+      `["10.0.0.0/8", "192.168.5.0/24"]`. Currently this
+      only has an effect if the Network **Type** is *VPN* and the VPN
+      **Type** is *ARCVPN*.
+
 * **WebProxyAutoDiscoveryUrl**
     * (optional if part of **IPConfigs**, read-only) - **string**
     * The Web Proxy Auto-Discovery URL for this network as reported over DHCP.
diff --git a/components/onc/onc_constants.cc b/components/onc/onc_constants.cc
index 80a95ef..c3f6cd51 100644
--- a/components/onc/onc_constants.cc
+++ b/components/onc/onc_constants.cc
@@ -209,6 +209,8 @@
 const char kNameServers[] = "NameServers";
 const char kRoutingPrefix[] = "RoutingPrefix";
 const char kSearchDomains[] = "SearchDomains";
+const char kIncludedRoutes[] = "IncludedRoutes";
+const char kExcludedRoutes[] = "ExcludedRoutes";
 const char kType[] = "Type";
 const char kWebProxyAutoDiscoveryUrl[] = "WebProxyAutoDiscoveryUrl";
 }  // namespace ipconfig
diff --git a/components/onc/onc_constants.h b/components/onc/onc_constants.h
index 20ece16..94b3e7c 100644
--- a/components/onc/onc_constants.h
+++ b/components/onc/onc_constants.h
@@ -208,6 +208,8 @@
 ONC_EXPORT extern const char kNameServers[];
 ONC_EXPORT extern const char kRoutingPrefix[];
 ONC_EXPORT extern const char kSearchDomains[];
+ONC_EXPORT extern const char kIncludedRoutes[];
+ONC_EXPORT extern const char kExcludedRoutes[];
 ONC_EXPORT extern const char kType[];
 ONC_EXPORT extern const char kWebProxyAutoDiscoveryUrl[];
 }  // namespace ipconfig
diff --git a/components/sync/syncable/write_transaction_info.cc b/components/sync/syncable/write_transaction_info.cc
index 39edc6f..ac0980c 100644
--- a/components/sync/syncable/write_transaction_info.cc
+++ b/components/sync/syncable/write_transaction_info.cc
@@ -17,10 +17,7 @@
     base::Location location,
     WriterTag writer,
     ImmutableEntryKernelMutationMap mutations)
-    : id(id),
-      location_string(location.ToString()),
-      writer(writer),
-      mutations(mutations) {}
+    : id(id), location_(location), writer(writer), mutations(mutations) {}
 
 WriteTransactionInfo::WriteTransactionInfo() : id(-1), writer(INVALID) {}
 
@@ -33,7 +30,7 @@
     size_t max_mutations_size) const {
   auto dict = std::make_unique<base::DictionaryValue>();
   dict->SetString("id", base::Int64ToString(id));
-  dict->SetString("location", location_string);
+  dict->SetString("location", location_.ToString());
   dict->SetString("writer", WriterTagToString(writer));
   std::unique_ptr<base::Value> mutations_value;
   const size_t mutations_size = mutations.Get().size();
diff --git a/components/sync/syncable/write_transaction_info.h b/components/sync/syncable/write_transaction_info.h
index 1830514..cb83214 100644
--- a/components/sync/syncable/write_transaction_info.h
+++ b/components/sync/syncable/write_transaction_info.h
@@ -32,9 +32,7 @@
       size_t max_mutations_size) const;
 
   int64_t id;
-  // If base::Location becomes assignable, we can use that
-  // instead.
-  std::string location_string;
+  base::Location location_;
   WriterTag writer;
   ImmutableEntryKernelMutationMap mutations;
 };
diff --git a/components/visitedlink/browser/visitedlink_master.cc b/components/visitedlink/browser/visitedlink_master.cc
index daf919df..66463979 100644
--- a/components/visitedlink/browser/visitedlink_master.cc
+++ b/components/visitedlink/browser/visitedlink_master.cc
@@ -228,9 +228,7 @@
       delegate_(delegate),
       listener_(base::MakeUnique<VisitedLinkEventListener>(browser_context)),
       persist_to_disk_(persist_to_disk),
-      table_is_loading_from_file_(false),
       weak_ptr_factory_(this) {
-  InitMembers();
 }
 
 VisitedLinkMaster::VisitedLinkMaster(Listener* listener,
@@ -239,14 +237,11 @@
                                      bool suppress_rebuild,
                                      const base::FilePath& filename,
                                      int32_t default_table_size)
-    : browser_context_(NULL),
-      delegate_(delegate),
+    : delegate_(delegate),
       persist_to_disk_(persist_to_disk),
-      table_is_loading_from_file_(false),
       weak_ptr_factory_(this) {
   listener_.reset(listener);
   DCHECK(listener_.get());
-  InitMembers();
 
   database_name_override_ = filename;
   table_size_override_ = default_table_size;
@@ -277,15 +272,6 @@
   }
 }
 
-void VisitedLinkMaster::InitMembers() {
-  file_ = NULL;
-  shared_memory_serial_ = 0;
-  used_items_ = 0;
-  table_size_override_ = 0;
-  suppress_rebuild_ = false;
-  sequence_token_ = base::SequencedWorkerPool::GetSequenceToken();
-}
-
 bool VisitedLinkMaster::Init() {
   // Create the temporary table. If the table is rebuilt that temporary table
   // will be became the main table.
@@ -357,8 +343,7 @@
 void VisitedLinkMaster::PostIOTask(const base::Location& from_here,
                                    const base::Closure& task) {
   DCHECK(persist_to_disk_);
-  BrowserThread::GetBlockingPool()->PostSequencedWorkerTask(sequence_token_,
-                                                            from_here, task);
+  file_task_runner_->PostTask(from_here, task);
 }
 
 void VisitedLinkMaster::AddURL(const GURL& url) {
diff --git a/components/visitedlink/browser/visitedlink_master.h b/components/visitedlink/browser/visitedlink_master.h
index 12c0d82..fd30484 100644
--- a/components/visitedlink/browser/visitedlink_master.h
+++ b/components/visitedlink/browser/visitedlink_master.h
@@ -19,7 +19,8 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task_scheduler/post_task.h"
 #include "build/build_config.h"
 #include "components/visitedlink/common/visitedlink_common.h"
 #include "mojo/public/cpp/system/buffer.h"
@@ -208,9 +209,6 @@
   // we will write the whole table to disk at once instead of individual items.
   static const size_t kBigDeleteThreshold;
 
-  // Backend for the constructors initializing the members.
-  void InitMembers();
-
   // If a rebuild is in progress, we save the URL in the temporary list.
   // Otherwise, we add this to the table. Returns the index of the
   // inserted fingerprint or null_hash_ on failure.
@@ -397,7 +395,7 @@
 
   // Reference to the browser context that this object belongs to
   // (it knows the path to where the data is stored)
-  content::BrowserContext* browser_context_;
+  content::BrowserContext* browser_context_ = nullptr;
 
   // Client owns the delegate and is responsible for it being valid through
   // the life time this VisitedLinkMaster.
@@ -406,8 +404,11 @@
   // VisitedLinkEventListener to handle incoming events.
   std::unique_ptr<Listener> listener_;
 
-  // Lazily initialized sequence token for posting file tasks.
-  base::SequencedWorkerPool::SequenceToken sequence_token_;
+  // Task runner for posting file tasks.
+  scoped_refptr<base::SequencedTaskRunner> file_task_runner_ =
+      base::CreateSequencedTaskRunnerWithTraits(
+          {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
 
   // When non-NULL, indicates we are in database rebuild mode and points to
   // the class collecting fingerprint information from the history system.
@@ -433,7 +434,7 @@
   // guaranteed to be executed after the opening.
   // The class owns both the |file_| pointer and the pointer pointed
   // by |*file_|.
-  FILE** file_;
+  FILE** file_ = nullptr;
 
   // If true, will try to persist the hash table to disk. Will rebuild from
   // VisitedLinkDelegate::RebuildTable if there are disk corruptions.
@@ -449,13 +450,13 @@
 
   // When we generate new tables, we increment the serial number of the
   // shared memory object.
-  int32_t shared_memory_serial_;
+  int32_t shared_memory_serial_ = 0;
 
   // Number of non-empty items in the table, used to compute fullness.
-  int32_t used_items_;
+  int32_t used_items_ = 0;
 
   // We set this to true to avoid writing to the database file.
-  bool table_is_loading_from_file_;
+  bool table_is_loading_from_file_ = false;
 
   // Testing values -----------------------------------------------------------
   //
@@ -469,7 +470,7 @@
   base::FilePath database_name_override_;
 
   // When nonzero, overrides the table size for new databases for testing
-  int32_t table_size_override_;
+  int32_t table_size_override_ = 0;
 
   // When set, indicates the task that should be run after the next rebuild from
   // history is complete.
@@ -478,7 +479,7 @@
   // Set to prevent us from attempting to rebuild the database from global
   // history if we have an error opening the file. This is used for testing,
   // will be false in production.
-  bool suppress_rebuild_;
+  bool suppress_rebuild_ = false;
 
   base::WeakPtrFactory<VisitedLinkMaster> weak_ptr_factory_;
 
diff --git a/components/webcrypto/fuzzer_support.cc b/components/webcrypto/fuzzer_support.cc
index f0d1191..a9b278b 100644
--- a/components/webcrypto/fuzzer_support.cc
+++ b/components/webcrypto/fuzzer_support.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
+#include "base/message_loop/message_loop.h"
 #include "base/numerics/safe_conversions.h"
 #include "components/webcrypto/algorithm_dispatch.h"
 #include "components/webcrypto/crypto_data.h"
@@ -28,6 +29,9 @@
     blink::Platform::Initialize(this);
   }
   ~InitOnce() override {}
+
+ private:
+  base::MessageLoop loop_;
 };
 
 base::LazyInstance<InitOnce>::Leaky g_once = LAZY_INSTANCE_INITIALIZER;
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index d1f28b6..d573079 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -629,23 +629,7 @@
 }
 
 STDMETHODIMP BrowserAccessibilityComWin::removeSelection(LONG selection_index) {
-  WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_REMOVE_SELECTION);
-  AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-  if (!owner())
-    return E_FAIL;
-
-  if (selection_index != 0)
-    return E_INVALIDARG;
-
-  // Simply collapse the selection to the position of the caret if a caret is
-  // visible, otherwise set the selection to 0.
-  LONG caret_offset = 0;
-  int selection_start, selection_end;
-  GetSelectionOffsets(&selection_start, &selection_end);
-  if (owner()->HasCaret() && selection_end >= 0)
-    caret_offset = selection_end;
-  SetIA2HypertextSelection(caret_offset, caret_offset);
-  return S_OK;
+  return AXPlatformNodeWin::removeSelection(selection_index);
 }
 
 STDMETHODIMP BrowserAccessibilityComWin::setCaretOffset(LONG offset) {
diff --git a/content/browser/android/content_feature_list.cc b/content/browser/android/content_feature_list.cc
index eb196572..25c4026 100644
--- a/content/browser/android/content_feature_list.cc
+++ b/content/browser/android/content_feature_list.cc
@@ -39,7 +39,7 @@
 
 // Alphabetical:
 const base::Feature kRequestUnbufferedDispatch{
-    "RequestUnbufferedDispatch", base::FEATURE_DISABLED_BY_DEFAULT};
+    "RequestUnbufferedDispatch", base::FEATURE_ENABLED_BY_DEFAULT};
 
 static jboolean IsEnabled(JNIEnv* env,
                           const JavaParamRef<jclass>& clazz,
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 7c84a5e8..c703bd5b 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -1446,8 +1446,9 @@
       memory_instrumentation::mojom::ProcessType::BROWSER);
   memory_instrumentation::ClientProcessImpl::CreateInstance(config);
 
+  const bool is_mus = IsUsingMus();
 #if defined(USE_AURA)
-  if (IsUsingMus()) {
+  if (is_mus) {
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kIsRunningInMash);
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
@@ -1485,7 +1486,7 @@
   established_gpu_channel = true;
   if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor() ||
       parsed_command_line_.HasSwitch(switches::kDisableGpuEarlyInit) ||
-      IsUsingMus()) {
+      is_mus) {
     established_gpu_channel = always_uses_gpu = false;
   }
   gpu::GpuChannelEstablishFactory* factory =
@@ -1495,7 +1496,7 @@
     factory = BrowserGpuChannelHostFactory::instance();
   }
 #if !defined(OS_ANDROID)
-  if (!IsUsingMus()) {
+  if (!is_mus) {
     // TODO(kylechar): Remove flag along with surface sequences.
     // See https://crbug.com/676384.
     auto surface_lifetime_type =
@@ -1516,8 +1517,11 @@
 #endif
 
   DCHECK(factory);
-  ImageTransportFactory::Initialize(GetResizeTaskRunner());
-  ImageTransportFactory::GetInstance()->SetGpuChannelEstablishFactory(factory);
+  if (!is_mus) {
+    ImageTransportFactory::Initialize(GetResizeTaskRunner());
+    ImageTransportFactory::GetInstance()->SetGpuChannelEstablishFactory(
+        factory);
+  }
 #if defined(USE_AURA)
   if (env_->mode() == aura::Env::Mode::LOCAL) {
     env_->set_context_factory(GetContextFactory());
@@ -1619,7 +1623,7 @@
   // ChildProcess instance which is created by the renderer thread.
   if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
       !established_gpu_channel && always_uses_gpu && !UsingInProcessGpu() &&
-      !IsUsingMus()) {
+      !is_mus) {
     TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
                          TRACE_EVENT_SCOPE_THREAD);
     BrowserThread::PostTask(
diff --git a/content/browser/download/download_stats.cc b/content/browser/download/download_stats.cc
index 2e6952a..78d0f31 100644
--- a/content/browser/download/download_stats.cc
+++ b/content/browser/download/download_stats.cc
@@ -559,6 +559,18 @@
 
 namespace {
 
+int GetMimeTypeMatch(const std::string& mime_type_string,
+                     std::map<std::string, int> mime_type_map) {
+  for (const auto& entry : mime_type_map) {
+    if (entry.first == mime_type_string) {
+      return entry.second;
+    }
+  }
+  return 0;
+}
+
+// NOTE: Keep in sync with DownloadContentType in
+// tools/metrics/histograms/enums.xml.
 enum DownloadContent {
   DOWNLOAD_CONTENT_UNRECOGNIZED = 0,
   DOWNLOAD_CONTENT_TEXT = 1,
@@ -567,38 +579,73 @@
   DOWNLOAD_CONTENT_VIDEO = 4,
   DOWNLOAD_CONTENT_OCTET_STREAM = 5,
   DOWNLOAD_CONTENT_PDF = 6,
-  DOWNLOAD_CONTENT_DOC = 7,
-  DOWNLOAD_CONTENT_XLS = 8,
-  DOWNLOAD_CONTENT_PPT = 9,
+  DOWNLOAD_CONTENT_DOCUMENT = 7,
+  DOWNLOAD_CONTENT_SPREADSHEET = 8,
+  DOWNLOAD_CONTENT_PRESENTATION = 9,
   DOWNLOAD_CONTENT_ARCHIVE = 10,
-  DOWNLOAD_CONTENT_EXE = 11,
+  DOWNLOAD_CONTENT_EXECUTABLE = 11,
   DOWNLOAD_CONTENT_DMG = 12,
   DOWNLOAD_CONTENT_CRX = 13,
-  DOWNLOAD_CONTENT_MAX = 14,
+  DOWNLOAD_CONTENT_WEB = 14,
+  DOWNLOAD_CONTENT_EBOOK = 15,
+  DOWNLOAD_CONTENT_FONT = 16,
+  DOWNLOAD_CONTENT_APK = 17,
+  DOWNLOAD_CONTENT_MAX = 18,
 };
 
-struct MimeTypeToDownloadContent {
-  const char* mime_type;
-  DownloadContent download_content;
-};
+static std::map<std::string, int> getMimeTypeToDownloadContentMap() {
+  return {
+      {"application/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM},
+      {"binary/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM},
+      {"application/pdf", DOWNLOAD_CONTENT_PDF},
+      {"application/msword", DOWNLOAD_CONTENT_DOCUMENT},
+      {"application/"
+       "vnd.openxmlformats-officedocument.wordprocessingml.document",
+       DOWNLOAD_CONTENT_DOCUMENT},
+      {"application/rtf", DOWNLOAD_CONTENT_DOCUMENT},
+      {"application/vnd.oasis.opendocument.text", DOWNLOAD_CONTENT_DOCUMENT},
+      {"application/vnd.google-apps.document", DOWNLOAD_CONTENT_DOCUMENT},
+      {"application/vnd.ms-excel", DOWNLOAD_CONTENT_SPREADSHEET},
+      {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+       DOWNLOAD_CONTENT_SPREADSHEET},
+      {"application/vnd.oasis.opendocument.spreadsheet",
+       DOWNLOAD_CONTENT_SPREADSHEET},
+      {"application/vnd.google-apps.spreadsheet", DOWNLOAD_CONTENT_SPREADSHEET},
+      {"application/vns.ms-powerpoint", DOWNLOAD_CONTENT_PRESENTATION},
+      {"application/"
+       "vnd.openxmlformats-officedocument.presentationml.presentation",
+       DOWNLOAD_CONTENT_PRESENTATION},
+      {"application/vnd.oasis.opendocument.presentation",
+       DOWNLOAD_CONTENT_PRESENTATION},
+      {"application/vnd.google-apps.presentation",
+       DOWNLOAD_CONTENT_PRESENTATION},
+      {"application/zip", DOWNLOAD_CONTENT_ARCHIVE},
+      {"application/x-gzip", DOWNLOAD_CONTENT_ARCHIVE},
+      {"application/x-rar-compressed", DOWNLOAD_CONTENT_ARCHIVE},
+      {"application/x-tar", DOWNLOAD_CONTENT_ARCHIVE},
+      {"application/x-bzip", DOWNLOAD_CONTENT_ARCHIVE},
+      {"application/x-bzip2", DOWNLOAD_CONTENT_ARCHIVE},
+      {"application/x-7z-compressed", DOWNLOAD_CONTENT_ARCHIVE},
+      {"application/x-exe", DOWNLOAD_CONTENT_EXECUTABLE},
+      {"application/java-archive", DOWNLOAD_CONTENT_EXECUTABLE},
+      {"application/vnd.apple.installer+xml", DOWNLOAD_CONTENT_EXECUTABLE},
+      {"application/x-csh", DOWNLOAD_CONTENT_EXECUTABLE},
+      {"application/x-sh", DOWNLOAD_CONTENT_EXECUTABLE},
+      {"application/x-apple-diskimage", DOWNLOAD_CONTENT_DMG},
+      {"application/x-chrome-extension", DOWNLOAD_CONTENT_CRX},
+      {"application/xhtml+xml", DOWNLOAD_CONTENT_WEB},
+      {"application/xml", DOWNLOAD_CONTENT_WEB},
+      {"application/javascript", DOWNLOAD_CONTENT_WEB},
+      {"application/json", DOWNLOAD_CONTENT_WEB},
+      {"application/typescript", DOWNLOAD_CONTENT_WEB},
+      {"application/vnd.mozilla.xul+xml", DOWNLOAD_CONTENT_WEB},
+      {"application/vnd.amazon.ebook", DOWNLOAD_CONTENT_EBOOK},
+      {"application/epub+zip", DOWNLOAD_CONTENT_EBOOK},
+      {"application/vnd.android.package-archive", DOWNLOAD_CONTENT_APK}};
+}
 
-static MimeTypeToDownloadContent kMapMimeTypeToDownloadContent[] = {
-  {"application/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM},
-  {"binary/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM},
-  {"application/pdf", DOWNLOAD_CONTENT_PDF},
-  {"application/msword", DOWNLOAD_CONTENT_DOC},
-  {"application/vnd.ms-excel", DOWNLOAD_CONTENT_XLS},
-  {"application/vns.ms-powerpoint", DOWNLOAD_CONTENT_PPT},
-  {"application/zip", DOWNLOAD_CONTENT_ARCHIVE},
-  {"application/x-gzip", DOWNLOAD_CONTENT_ARCHIVE},
-  {"application/x-rar-compressed", DOWNLOAD_CONTENT_ARCHIVE},
-  {"application/x-tar", DOWNLOAD_CONTENT_ARCHIVE},
-  {"application/x-bzip", DOWNLOAD_CONTENT_ARCHIVE},
-  {"application/x-exe", DOWNLOAD_CONTENT_EXE},
-  {"application/x-apple-diskimage", DOWNLOAD_CONTENT_DMG},
-  {"application/x-chrome-extension", DOWNLOAD_CONTENT_CRX},
-};
-
+// NOTE: Keep in sync with DownloadImageType in
+// tools/metrics/histograms/enums.xml.
 enum DownloadImage {
   DOWNLOAD_IMAGE_UNRECOGNIZED = 0,
   DOWNLOAD_IMAGE_GIF = 1,
@@ -607,68 +654,158 @@
   DOWNLOAD_IMAGE_TIFF = 4,
   DOWNLOAD_IMAGE_ICON = 5,
   DOWNLOAD_IMAGE_WEBP = 6,
-  DOWNLOAD_IMAGE_MAX = 7,
+  DOWNLOAD_IMAGE_PSD = 7,
+  DOWNLOAD_IMAGE_SVG = 8,
+  DOWNLOAD_IMAGE_MAX = 9,
 };
 
-struct MimeTypeToDownloadImage {
-  const char* mime_type;
-  DownloadImage download_image;
-};
-
-static MimeTypeToDownloadImage kMapMimeTypeToDownloadImage[] = {
-  {"image/gif", DOWNLOAD_IMAGE_GIF},
-  {"image/jpeg", DOWNLOAD_IMAGE_JPEG},
-  {"image/png", DOWNLOAD_IMAGE_PNG},
-  {"image/tiff", DOWNLOAD_IMAGE_TIFF},
-  {"image/vnd.microsoft.icon", DOWNLOAD_IMAGE_ICON},
-  {"image/webp", DOWNLOAD_IMAGE_WEBP},
-};
+static std::map<std::string, int> getMimeTypeToDownloadImageMap() {
+  return {{"image/gif", DOWNLOAD_IMAGE_GIF},
+          {"image/jpeg", DOWNLOAD_IMAGE_JPEG},
+          {"image/png", DOWNLOAD_IMAGE_PNG},
+          {"image/tiff", DOWNLOAD_IMAGE_TIFF},
+          {"image/vnd.microsoft.icon", DOWNLOAD_IMAGE_ICON},
+          {"image/x-icon", DOWNLOAD_IMAGE_ICON},
+          {"image/webp", DOWNLOAD_IMAGE_WEBP},
+          {"image/vnd.adobe.photoshop", DOWNLOAD_IMAGE_PSD},
+          {"image/svg+xml", DOWNLOAD_IMAGE_SVG}};
+}
 
 void RecordDownloadImageType(const std::string& mime_type_string) {
-  DownloadImage download_image = DOWNLOAD_IMAGE_UNRECOGNIZED;
-
-  // Look up exact matches.
-  for (size_t i = 0; i < arraysize(kMapMimeTypeToDownloadImage); ++i) {
-    const MimeTypeToDownloadImage& entry = kMapMimeTypeToDownloadImage[i];
-    if (mime_type_string == entry.mime_type) {
-      download_image = entry.download_image;
-      break;
-    }
-  }
-
-  UMA_HISTOGRAM_ENUMERATION("Download.ContentImageType", download_image,
+  DownloadImage download_image = DownloadImage(
+      GetMimeTypeMatch(mime_type_string, getMimeTypeToDownloadImageMap()));
+  UMA_HISTOGRAM_ENUMERATION("Download.ContentType.Image", download_image,
                             DOWNLOAD_IMAGE_MAX);
 }
 
-DownloadContent DownloadContentFromMimeType(const std::string& mime_type_string,
-                                            bool record_image_type) {
-  DownloadContent download_content = DOWNLOAD_CONTENT_UNRECOGNIZED;
+/** Text categories **/
 
-  // Look up exact matches.
-  for (size_t i = 0; i < arraysize(kMapMimeTypeToDownloadContent); ++i) {
-    const MimeTypeToDownloadContent& entry = kMapMimeTypeToDownloadContent[i];
-    if (mime_type_string == entry.mime_type) {
-      download_content = entry.download_content;
-      break;
-    }
-  }
+// NOTE: Keep in sync with DownloadTextType in
+// tools/metrics/histograms/enums.xml.
+enum DownloadText {
+  DOWNLOAD_TEXT_UNRECOGNIZED = 0,
+  DOWNLOAD_TEXT_PLAIN = 1,
+  DOWNLOAD_TEXT_CSS = 2,
+  DOWNLOAD_TEXT_CSV = 3,
+  DOWNLOAD_TEXT_HTML = 4,
+  DOWNLOAD_TEXT_CALENDAR = 5,
+  DOWNLOAD_TEXT_MAX = 6,
+};
+
+static std::map<std::string, int> getMimeTypeToDownloadTextMap() {
+  return {{"text/plain", DOWNLOAD_TEXT_PLAIN},
+          {"text/css", DOWNLOAD_TEXT_CSS},
+          {"text/csv", DOWNLOAD_TEXT_CSV},
+          {"text/html", DOWNLOAD_TEXT_HTML},
+          {"text/calendar", DOWNLOAD_TEXT_CALENDAR}};
+}
+
+void RecordDownloadTextType(const std::string& mime_type_string) {
+  DownloadText download_text = DownloadText(
+      GetMimeTypeMatch(mime_type_string, getMimeTypeToDownloadTextMap()));
+  UMA_HISTOGRAM_ENUMERATION("Download.ContentType.Text", download_text,
+                            DOWNLOAD_TEXT_MAX);
+}
+
+/* Audio categories */
+
+// NOTE: Keep in sync with DownloadAudioType in
+// tools/metrics/histograms/enums.xml.
+enum DownloadAudio {
+  DOWNLOAD_AUDIO_UNRECOGNIZED = 0,
+  DOWNLOAD_AUDIO_AAC = 1,
+  DOWNLOAD_AUDIO_MIDI = 2,
+  DOWNLOAD_AUDIO_OGA = 3,
+  DOWNLOAD_AUDIO_WAV = 4,
+  DOWNLOAD_AUDIO_WEBA = 5,
+  DOWNLOAD_AUDIO_3GP = 6,
+  DOWNLOAD_AUDIO_3G2 = 7,
+  DOWNLOAD_AUDIO_MP3 = 8,
+  DOWNLOAD_AUDIO_MAX = 9,
+};
+
+static std::map<std::string, int> getMimeTypeToDownloadAudioMap() {
+  return {
+      {"audio/aac", DOWNLOAD_AUDIO_AAC},   {"audio/midi", DOWNLOAD_AUDIO_MIDI},
+      {"audio/ogg", DOWNLOAD_AUDIO_OGA},   {"audio/x-wav", DOWNLOAD_AUDIO_WAV},
+      {"audio/webm", DOWNLOAD_AUDIO_WEBA}, {"audio/3gpp", DOWNLOAD_AUDIO_3GP},
+      {"audio/3gpp2", DOWNLOAD_AUDIO_3G2}, {"audio/mp3", DOWNLOAD_AUDIO_MP3}};
+}
+
+void RecordDownloadAudioType(const std::string& mime_type_string) {
+  DownloadAudio download_audio = DownloadAudio(
+      GetMimeTypeMatch(mime_type_string, getMimeTypeToDownloadAudioMap()));
+  UMA_HISTOGRAM_ENUMERATION("Download.ContentType.Audio", download_audio,
+                            DOWNLOAD_AUDIO_MAX);
+}
+
+/* Video categories */
+
+// NOTE: Keep in sync with DownloadVideoType in
+// tools/metrics/histograms/enums.xml.
+enum DownloadVideo {
+  DOWNLOAD_VIDEO_UNRECOGNIZED = 0,
+  DOWNLOAD_VIDEO_AVI = 1,
+  DOWNLOAD_VIDEO_MPEG = 2,
+  DOWNLOAD_VIDEO_OGV = 3,
+  DOWNLOAD_VIDEO_WEBM = 4,
+  DOWNLOAD_VIDEO_3GP = 5,
+  DOWNLOAD_VIDEO_3G2 = 6,
+  DOWNLOAD_VIDEO_MP4 = 7,
+  DOWNLOAD_VIDEO_MOV = 8,
+  DOWNLOAD_VIDEO_WMV = 9,
+  DOWNLOAD_VIDEO_MAX = 10,
+};
+
+static std::map<std::string, int> getMimeTypeToDownloadVideoMap() {
+  return {{"video/x-msvideo", DOWNLOAD_VIDEO_AVI},
+          {"video/mpeg", DOWNLOAD_VIDEO_MPEG},
+          {"video/ogg", DOWNLOAD_VIDEO_OGV},
+          {"video/webm", DOWNLOAD_VIDEO_WEBM},
+          {"video/3gpp", DOWNLOAD_VIDEO_3GP},
+          {"video/3ggp2", DOWNLOAD_VIDEO_3G2},
+          {"video/mp4", DOWNLOAD_VIDEO_MP4},
+          {"video/quicktime", DOWNLOAD_VIDEO_MOV},
+          {"video/x-ms-wmv", DOWNLOAD_VIDEO_WMV}};
+}
+
+void RecordDownloadVideoType(const std::string& mime_type_string) {
+  DownloadVideo download_video = DownloadVideo(
+      GetMimeTypeMatch(mime_type_string, getMimeTypeToDownloadVideoMap()));
+  UMA_HISTOGRAM_ENUMERATION("Download.ContentType.Video", download_video,
+                            DOWNLOAD_VIDEO_MAX);
+}
+
+DownloadContent DownloadContentFromMimeType(const std::string& mime_type_string,
+                                            bool record_content_subcategory) {
+  DownloadContent download_content = DownloadContent(
+      GetMimeTypeMatch(mime_type_string, getMimeTypeToDownloadContentMap()));
 
   // Do partial matches.
   if (download_content == DOWNLOAD_CONTENT_UNRECOGNIZED) {
     if (base::StartsWith(mime_type_string, "text/",
                          base::CompareCase::SENSITIVE)) {
       download_content = DOWNLOAD_CONTENT_TEXT;
+      if (record_content_subcategory)
+        RecordDownloadTextType(mime_type_string);
     } else if (base::StartsWith(mime_type_string, "image/",
                                 base::CompareCase::SENSITIVE)) {
       download_content = DOWNLOAD_CONTENT_IMAGE;
-      if (record_image_type)
+      if (record_content_subcategory)
         RecordDownloadImageType(mime_type_string);
     } else if (base::StartsWith(mime_type_string, "audio/",
                                 base::CompareCase::SENSITIVE)) {
       download_content = DOWNLOAD_CONTENT_AUDIO;
+      if (record_content_subcategory)
+        RecordDownloadAudioType(mime_type_string);
     } else if (base::StartsWith(mime_type_string, "video/",
                                 base::CompareCase::SENSITIVE)) {
       download_content = DOWNLOAD_CONTENT_VIDEO;
+      if (record_content_subcategory)
+        RecordDownloadVideoType(mime_type_string);
+    } else if (base::StartsWith(mime_type_string, "font/",
+                                base::CompareCase::SENSITIVE)) {
+      download_content = DOWNLOAD_CONTENT_FONT;
     }
   }
 
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
index adca53ed..3904248 100644
--- a/content/browser/frame_host/frame_tree_node.cc
+++ b/content/browser/frame_host/frame_tree_node.cc
@@ -478,7 +478,12 @@
   CHECK(IsBrowserSideNavigationEnabled());
   if (!navigation_request_)
     return;
-  bool was_renderer_initiated = !navigation_request_->browser_initiated();
+
+  // The renderer should be informed if the caller allows to do so and the
+  // navigation came from a BeginNavigation IPC.
+  int need_to_inform_renderer =
+      inform_renderer && navigation_request_->from_begin_navigation();
+
   NavigationRequest::AssociatedSiteInstanceType site_instance_type =
       navigation_request_->associated_site_instance_type();
   navigation_request_.reset();
@@ -503,9 +508,9 @@
   // process asked for the navigation to be aborted, e.g. following a
   // document.open, do not send an IPC to the renderer process as it already
   // expects the navigation to stop.
-  if (was_renderer_initiated && inform_renderer) {
+  if (need_to_inform_renderer) {
     current_frame_host()->Send(
-        new FrameMsg_Stop(current_frame_host()->GetRoutingID()));
+        new FrameMsg_DroppedNavigation(current_frame_host()->GetRoutingID()));
   }
 
 }
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index d108ff7..ee570c4 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -264,7 +264,7 @@
                             blink::WebMixedContentContextType::kBlockable,
                             is_form_submission, initiator),
       request_params, browser_initiated,
-      true,  // may_transfer
+      false,  // from_begin_navigation
       &frame_entry, &entry));
   return navigation_request;
 }
@@ -311,7 +311,7 @@
   std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
       frame_tree_node, common_params, begin_params, request_params,
       false,  // browser_initiated
-      false,  // may_transfer
+      true,   // from_begin_navigation
       nullptr, entry));
   return navigation_request;
 }
@@ -322,7 +322,7 @@
     const BeginNavigationParams& begin_params,
     const RequestNavigationParams& request_params,
     bool browser_initiated,
-    bool may_transfer,
+    bool from_begin_navigation,
     const FrameNavigationEntry* frame_entry,
     const NavigationEntryImpl* entry)
     : frame_tree_node_(frame_tree_node),
@@ -336,7 +336,7 @@
       bindings_(NavigationEntryImpl::kInvalidBindings),
       response_should_be_rendered_(true),
       associated_site_instance_type_(AssociatedSiteInstanceType::NONE),
-      may_transfer_(may_transfer),
+      from_begin_navigation_(from_begin_navigation),
       weak_factory_(this) {
   DCHECK(!browser_initiated || (entry != nullptr && frame_entry != nullptr));
   TRACE_EVENT_ASYNC_BEGIN2("navigation", "NavigationRequest", this,
@@ -348,21 +348,20 @@
   common_params_.referrer =
       Referrer::SanitizeForRequest(common_params_.url, common_params_.referrer);
 
-  if (may_transfer) {
+  if (from_begin_navigation_) {
+    // This is needed to have data URLs commit in the same SiteInstance as the
+    // initiating renderer.
+    source_site_instance_ =
+        frame_tree_node->current_frame_host()->GetSiteInstance();
+  } else {
     FrameNavigationEntry* frame_entry = entry->GetFrameEntry(frame_tree_node);
     if (frame_entry) {
       source_site_instance_ = frame_entry->source_site_instance();
       dest_site_instance_ = frame_entry->site_instance();
     }
-
     restore_type_ = entry->restore_type();
     is_view_source_ = entry->IsViewSourceMode();
     bindings_ = entry->bindings();
-  } else {
-    // This is needed to have about:blank and data URLs commit in the same
-    // SiteInstance as the initiating renderer.
-    source_site_instance_ =
-        frame_tree_node->current_frame_host()->GetSiteInstance();
   }
 
   // Update the load flags with cache information.
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 82cbaf5..c78665b 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -141,7 +141,7 @@
 
   bool browser_initiated() const { return browser_initiated_ ; }
 
-  bool may_transfer() const { return may_transfer_; }
+  bool from_begin_navigation() const { return from_begin_navigation_; }
 
   AssociatedSiteInstanceType associated_site_instance_type() const {
     return associated_site_instance_type_;
@@ -191,7 +191,7 @@
                     const BeginNavigationParams& begin_params,
                     const RequestNavigationParams& request_params,
                     bool browser_initiated,
-                    bool may_transfer,
+                    bool from_begin_navigation,
                     const FrameNavigationEntry* frame_navigation_entry,
                     const NavigationEntryImpl* navitation_entry);
 
@@ -302,14 +302,11 @@
   // SiteInstance was a brand new SiteInstance, it is not stored.
   scoped_refptr<SiteInstance> speculative_site_instance_;
 
-  // Whether the request may be transferred to a different process upon commit.
-  // True for browser-initiated navigations and renderer-inititated navigations
-  // started via the OpenURL path.
-  // Note: the RenderFrameHostManager may still decide to have the navigation
-  // commit in a different renderer process if it detects that a renderer
-  // transfer is needed. This is the case in particular when --site-per-process
-  // is enabled.
-  bool may_transfer_;
+  // Whether the NavigationRequest was created after receiving a BeginNavigation
+  // IPC. When true, main frame navigations should not commit in a different
+  // process (unless asked by the content/ embedder). When true, the renderer
+  // process expects to be notified if the navigation is aborted.
+  bool from_begin_navigation_;
 
   std::unique_ptr<NavigationHandleImpl> navigation_handle_;
 
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index f7d31c96..3ba6abb 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -999,7 +999,7 @@
     RenderFrameHost* current_frame_host =
         frame_tree_node->render_manager()->current_frame_host();
     current_frame_host->Send(
-        new FrameMsg_Stop(current_frame_host->GetRoutingID()));
+        new FrameMsg_DroppedNavigation(current_frame_host->GetRoutingID()));
     return;
   }
 
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
index 2b67ceb..9f55c9a 100644
--- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -636,4 +636,40 @@
       blink::kBeforeUnloadHandler));
 }
 
+// Aborted renderer-initiated navigations that don't destroy the current
+// document (e.g. no error page is displayed) must not cancel pending
+// XMLHttpRequests.
+// See https://crbug.com/762945.
+IN_PROC_BROWSER_TEST_F(
+    RenderFrameHostImplBrowserTest,
+    AbortedRendererInitiatedNavigationDoNotCancelPendingXHR) {
+  GURL main_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  // 1) Send an XHR that is slow to complete.
+  const char* send_slow_XHR =
+      "var request = new XMLHttpRequest();"
+      "request.addEventListener('abort', () => document.title = 'XHR aborted');"
+      "request.addEventListener('load', () => document.title = 'XHR loaded');"
+      "request.open('GET', '%s');"
+      "request.send();";
+  const GURL slow_url = embedded_test_server()->GetURL("/slow?1");
+  EXPECT_TRUE(content::ExecuteScript(
+      shell(), base::StringPrintf(send_slow_XHR, slow_url.spec().c_str())));
+
+  // 2) In the meantime, create a renderer-initiated navigation. It will be
+  // aborted.
+  EXPECT_TRUE(content::ExecuteScript(
+      shell(), "window.location = 'customprotocol:aborted'"));
+
+  // 3) Wait for the XHR request to complete.
+  const base::string16 XHR_aborted = base::ASCIIToUTF16("XHR aborted");
+  const base::string16 XHR_loaded = base::ASCIIToUTF16("XHR loaded");
+  TitleWatcher watcher(shell()->web_contents(), XHR_loaded);
+  watcher.AlsoWaitForTitle(XHR_aborted);
+
+  EXPECT_EQ(XHR_loaded, watcher.WaitAndGetTitle());
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 8c8bf8ab..186a161 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -1944,7 +1944,7 @@
                                               request.common_params().url);
 
     no_renderer_swap_allowed |=
-        !request.may_transfer() && !can_renderer_initiate_transfer;
+        request.from_begin_navigation() && !can_renderer_initiate_transfer;
   } else {
     // Subframe navigations will use the current renderer, unless specifically
     // allowed to swap processes.
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 646b0a57..2b7095f 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1773,7 +1773,11 @@
     if (loader.first.child_id != child_id)
       continue;
 
+    // Added for http://crbug.com/754704; remove when that bug is resolved.
+    loader.second->AssertURLRequestPresent();
+
     ResourceRequestInfoImpl* info = loader.second->GetRequestInfo();
+    CHECK(info);
 
     GlobalRequestID id(child_id, loader.first.request_id);
     DCHECK(id == loader.first);
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index a7acc5b2..9294343 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -8,6 +8,7 @@
 
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
+#include "base/debug/dump_without_crashing.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
@@ -225,9 +226,13 @@
       times_cancelled_before_request_start_(0),
       started_request_(false),
       times_cancelled_after_request_start_(0),
+      request_context_(request_->context()),
       weak_ptr_factory_(this) {
   request_->set_delegate(this);
   handler_->SetDelegate(this);
+  // Added for http://crbug.com/754704; remove when that bug is resolved.
+  if (!GetRequestInfo())
+    base::debug::DumpWithoutCrashing();
 }
 
 ResourceLoader::~ResourceLoader() {
@@ -312,6 +317,12 @@
   CancelRequestInternal(error_code, !tell_renderer);
 }
 
+void ResourceLoader::AssertURLRequestPresent() const {
+  DCHECK(request_context_);
+  CHECK(request_);
+  request_context_->AssertURLRequestPresent(request_.get());
+}
+
 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused,
                                         const net::RedirectInfo& redirect_info,
                                         bool* defer) {
diff --git a/content/browser/loader/resource_loader.h b/content/browser/loader/resource_loader.h
index 259d498..e9d32c5 100644
--- a/content/browser/loader/resource_loader.h
+++ b/content/browser/loader/resource_loader.h
@@ -60,6 +60,10 @@
   // ResourceHandler::Delegate implementation:
   void OutOfBandCancel(int error_code, bool tell_renderer) override;
 
+  // CHECKs that the associated URLRequest is still present on its context.
+  // Added for http://crbug.com/754704; remove when that bug is resolved.
+  void AssertURLRequestPresent() const;
+
  private:
   // ResourceController implementation for the ResourceLoader.
   class Controller;
@@ -185,6 +189,10 @@
   net::HttpRawRequestHeaders raw_request_headers_;
   scoped_refptr<const net::HttpResponseHeaders> raw_response_headers_;
 
+  // URLRequestContext of the associated URLRequest.
+  // Added for http://crbug.com/754704; remove when that bug is resolved.
+  const net::URLRequestContext* request_context_;
+
   base::ThreadChecker thread_checker_;
 
   base::WeakPtrFactory<ResourceLoader> weak_ptr_factory_;
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index 0780f18..57b97720 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -324,6 +324,8 @@
 }
 
 void ResourceRequestInfoImpl::AssociateWithRequest(net::URLRequest* request) {
+  // Added for http://crbug.com/754704; remove when that bug is resolved.
+  CHECK(this);
   request->SetUserData(kResourceRequestInfoImplKey, base::WrapUnique(this));
   int render_process_id;
   int render_frame_id;
diff --git a/content/browser/media/capture/aura_window_capture_machine.cc b/content/browser/media/capture/aura_window_capture_machine.cc
index 22a4fba..c2d47c5 100644
--- a/content/browser/media/capture/aura_window_capture_machine.cc
+++ b/content/browser/media/capture/aura_window_capture_machine.cc
@@ -80,9 +80,6 @@
   // Update capture size.
   UpdateCaptureSize();
 
-  // Start observing for GL context losses.
-  ImageTransportFactory::GetInstance()->GetContextFactory()->AddObserver(this);
-
   // Start observing compositor updates.
   aura::WindowTreeHost* const host = desktop_window_->GetHost();
   ui::Compositor* const compositor = host ? host->compositor() : nullptr;
@@ -90,6 +87,9 @@
     return false;
   compositor->AddAnimationObserver(this);
 
+  // Start observing for GL context losses.
+  compositor->context_factory()->AddObserver(this);
+
   DCHECK(!wake_lock_);
   // Request Wake Lock. In some testing contexts, the service manager
   // connection isn't initialized.
@@ -159,17 +159,16 @@
   // Stop observing compositor and window events.
   if (desktop_window_) {
     if (aura::WindowTreeHost* host = desktop_window_->GetHost()) {
-      if (ui::Compositor* compositor = host->compositor())
+      if (ui::Compositor* compositor = host->compositor()) {
         compositor->RemoveAnimationObserver(this);
+        compositor->context_factory()->RemoveObserver(this);
+      }
     }
     desktop_window_->RemoveObserver(this);
     desktop_window_ = NULL;
     cursor_renderer_.reset();
   }
 
-  // Stop observing for GL context losses.
-  ImageTransportFactory::GetInstance()->GetContextFactory()->RemoveObserver(
-      this);
   OnLostResources();
 
   callback.Run();
@@ -436,8 +435,10 @@
   DCHECK(window == desktop_window_);
 
   if (aura::WindowTreeHost* host = window->GetHost()) {
-    if (ui::Compositor* compositor = host->compositor())
+    if (ui::Compositor* compositor = host->compositor()) {
       compositor->RemoveAnimationObserver(this);
+      compositor->context_factory()->RemoveObserver(this);
+    }
   }
 }
 
@@ -466,6 +467,7 @@
     ui::Compositor* compositor) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   compositor->RemoveAnimationObserver(this);
+  compositor->context_factory()->RemoveObserver(this);
 }
 
 void AuraWindowCaptureMachine::OnLostResources() {
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 0180d75..fa13aa7 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -90,6 +90,7 @@
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/display/display_switches.h"
+#include "ui/display/screen.h"
 #include "ui/events/blink/web_input_event_traits.h"
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
@@ -755,9 +756,18 @@
     // ScaleToCeiledSize(new_size, device_scale_factor) ??
     resize_params->physical_backing_size = view_->GetPhysicalBackingSize();
     resize_params->top_controls_height = view_->GetTopControlsHeight();
+    resize_params->bottom_controls_height = view_->GetBottomControlsHeight();
+    if (IsUseZoomForDSFEnabled() && display::Screen::GetScreen()) {
+      const display::Display& display =
+          display::Screen::GetScreen()->GetPrimaryDisplay();
+      if (display.id() != display::kInvalidDisplayId) {
+        float device_scale = display.device_scale_factor();
+        resize_params->top_controls_height *= device_scale;
+        resize_params->bottom_controls_height *= device_scale;
+      }
+    }
     resize_params->browser_controls_shrink_blink_size =
         view_->DoBrowserControlsShrinkBlinkSize();
-    resize_params->bottom_controls_height = view_->GetBottomControlsHeight();
     resize_params->visible_viewport_size = view_->GetVisibleViewportSize();
     viz::LocalSurfaceId local_surface_id = view_->GetLocalSurfaceId();
     if (local_surface_id.is_valid())
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index fa6a10a..c3cd93e 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -308,6 +308,14 @@
     bounds_ = bounds;
   }
 
+  void set_top_controls_height(float top_controls_height) {
+    top_controls_height_ = top_controls_height;
+  }
+
+  void set_bottom_controls_height(float bottom_controls_height) {
+    bottom_controls_height_ = bottom_controls_height;
+  }
+
   const WebTouchEvent& acked_event() const { return acked_event_; }
   int acked_event_count() const { return acked_event_count_; }
   void ClearAckedEvent() {
@@ -334,6 +342,10 @@
 
   // RenderWidgetHostView override.
   gfx::Rect GetViewBounds() const override { return bounds_; }
+  float GetTopControlsHeight() const override { return top_controls_height_; }
+  float GetBottomControlsHeight() const override {
+    return bottom_controls_height_;
+  }
   void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
                               InputEventAckState ack_result) override {
     acked_event_ = touch.event;
@@ -367,6 +379,8 @@
   bool use_fake_physical_backing_size_;
   gfx::Size mock_physical_backing_size_;
   InputEventAckState ack_result_;
+  float top_controls_height_;
+  float bottom_controls_height_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestView);
@@ -2576,6 +2590,30 @@
   EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size);
 }
 
+TEST_F(RenderWidgetHostTest, ResizeParamsDeviceScale) {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  command_line->AppendSwitchASCII(switches::kEnableUseZoomForDSF, "true");
+
+  DCHECK(display::Screen::GetScreen());
+  const display::Display& display =
+      display::Screen::GetScreen()->GetPrimaryDisplay();
+  DCHECK(display.id() != display::kInvalidDisplayId);
+
+  float device_scale = display.device_scale_factor();
+
+  float top_controls_height = 10.0f;
+  float bottom_controls_height = 20.0f;
+  view_->set_top_controls_height(top_controls_height);
+  view_->set_bottom_controls_height(bottom_controls_height);
+
+  ResizeParams resize_params;
+  host_->GetResizeParams(&resize_params);
+  EXPECT_EQ(top_controls_height * device_scale,
+            resize_params.top_controls_height);
+  EXPECT_EQ(bottom_controls_height * device_scale,
+            resize_params.bottom_controls_height);
+}
+
 // Make sure no dragging occurs after renderer exited. See crbug.com/704832.
 TEST_F(RenderWidgetHostTest, RendererExitedNoDrag) {
   host_->SetView(new TestView(host_.get()));
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 0997df8..7f43dc9 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -64,6 +64,7 @@
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
 #include "content/browser/renderer_host/ui_events_helper.h"
+#include "content/common/content_switches_internal.h"
 #include "content/common/gpu_stream_constants.h"
 #include "content/common/input_messages.h"
 #include "content/common/site_isolation_policy.h"
@@ -460,7 +461,7 @@
       text_suggestion_host_(nullptr),
       background_color_(SK_ColorWHITE),
       cached_background_color_(SK_ColorWHITE),
-      view_(this),
+      view_(this, ui::ViewAndroid::LayoutType::MATCH_PARENT),
       gesture_provider_(ui::GetGestureProviderConfig(
                             ui::GestureProviderConfigType::CURRENT_PLATFORM),
                         this),
@@ -1488,7 +1489,7 @@
   bool is_mobile_optimized = IsMobileOptimizedFrame(frame_metadata);
   gesture_provider_.SetDoubleTapSupportForPageEnabled(!is_mobile_optimized);
 
-  float dip_scale = view_.GetDipScale();
+  float dip_scale = IsUseZoomForDSFEnabled() ? 1.f : view_.GetDipScale();
   float top_controls_pix = frame_metadata.top_controls_height * dip_scale;
   float top_content_offset = frame_metadata.top_controls_height *
                              frame_metadata.top_controls_shown_ratio;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index ea7afb2..728d412 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -403,7 +403,8 @@
       is_guest_view_hack_(is_guest_view_hack),
       device_scale_factor_(0.0f),
       event_handler_(new RenderWidgetHostViewEventHandler(host_, this, this)),
-      frame_sink_id_(host_->AllocateFrameSinkId(is_guest_view_hack_)),
+      frame_sink_id_(IsMus() ? viz::FrameSinkId()
+                             : host_->AllocateFrameSinkId(is_guest_view_hack_)),
       weak_ptr_factory_(this) {
   if (!is_guest_view_hack_)
     host_->SetView(this);
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
index cf77affc..75841f7d 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -153,7 +153,7 @@
     RenderWidgetHostViewBase* parent_view =
         frame_connector_->GetParentRenderWidgetHostView();
     if (parent_view) {
-      DCHECK(parent_view->GetFrameSinkId().is_valid());
+      DCHECK(parent_view->GetFrameSinkId().is_valid() || IsUsingMus());
       SetParentFrameSinkId(parent_view->GetFrameSinkId());
     }
 
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc
index 6e34c386..5e0a0ae 100644
--- a/content/browser/web_contents/web_contents_view_android.cc
+++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -89,7 +89,7 @@
     : web_contents_(web_contents),
       content_view_core_(NULL),
       delegate_(delegate),
-      view_(this),
+      view_(this, ui::ViewAndroid::LayoutType::NORMAL),
       synchronous_compositor_client_(nullptr) {}
 
 WebContentsViewAndroid::~WebContentsViewAndroid() {
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 0e66797..10f9be2 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -762,6 +762,11 @@
 // Instructs the frame to stop the load in progress, if any.
 IPC_MESSAGE_ROUTED0(FrameMsg_Stop)
 
+// PlzNavigate
+// Informs the renderer that the browser stopped processing a renderer-initiated
+// navigation. It does not stop ongoing loads in the current page.
+IPC_MESSAGE_ROUTED0(FrameMsg_DroppedNavigation)
+
 // A message sent to RenderFrameProxy to indicate that its corresponding
 // RenderFrame has started loading a document.
 IPC_MESSAGE_ROUTED0(FrameMsg_DidStartLoading)
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 43676ef..2ac43ec 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -465,7 +465,7 @@
     "javatests/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegateTest.java",
     "javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplPixelTest.java",
     "javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java",
-    "javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestBase.java",
+    "javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestRule.java",
     "javatests/src/org/chromium/content/browser/crypto/CipherFactoryTest.java",
     "javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java",
     "javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java",
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplPixelTest.java b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplPixelTest.java
index 8992018..d41f6f6 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplPixelTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplPixelTest.java
@@ -10,27 +10,39 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Build;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.view.Surface;
 
 import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.androidoverlay.DialogOverlayImplTestRule.Client;
 
 import java.util.concurrent.Callable;
 
 /**
  * Pixel tests for DialogOverlayImpl.  These use UiAutomation, so they only run in JB or above.
- * TODO(liberato): Convert to junit4.
  */
+@RunWith(BaseJUnit4ClassRunner.class)
 @MinAndroidSdkLevel(Build.VERSION_CODES.JELLY_BEAN_MR2)
 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-public class DialogOverlayImplPixelTest extends DialogOverlayImplTestBase {
+public class DialogOverlayImplPixelTest {
     // Color that we'll fill the overlay with.
+
+    @Rule
+    public DialogOverlayImplTestRule mActivityTestRule =
+            new DialogOverlayImplTestRule(TEST_PAGE_DATA_URL);
+
     private static final int OVERLAY_FILL_COLOR = Color.BLUE;
 
     // CSS coordinates of a div that we'll try to cover with an overlay.
@@ -85,20 +97,14 @@
     // Screenshot of the test page, before we do anything.
     Bitmap mInitialScreenshot;
 
-    @Override
-    protected String getInitialUrl() {
-        return TEST_PAGE_DATA_URL;
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         takeScreenshotOfBackground();
     }
 
     // Take a screenshot via UiAutomation, which captures all overlays.
     Bitmap takeScreenshot() {
-        return getInstrumentation().getUiAutomation().takeScreenshot();
+        return InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot();
     }
 
     // Fill |surface| with OVERLAY_FILL_COLOR and return a screenshot.  Note that we have no idea
@@ -113,7 +119,7 @@
     }
 
     int convertCSSToScreenPixels(int css) {
-        ContentViewCore cvc = getContentViewCore();
+        ContentViewCore cvc = mActivityTestRule.getContentViewCore();
         return (int) (css * cvc.getPageScaleFactor() * cvc.getDeviceScaleFactor());
     }
 
@@ -221,7 +227,7 @@
     // Wait for |overlay| to become ready, get its surface, and return it.
     Surface waitForSurface(DialogOverlayImpl overlay) throws Exception {
         Assert.assertNotNull(overlay);
-        final Client.Event event = getClient().nextEvent();
+        final Client.Event event = mActivityTestRule.getClient().nextEvent();
         Assert.assertTrue(event.surfaceKey > 0);
         return ThreadUtils.runOnUiThreadBlocking(new Callable<Surface>() {
             @Override
@@ -231,22 +237,24 @@
         });
     }
 
+    @Test
     @MediumTest
     @Feature({"AndroidOverlay"})
     public void testInitialPosition() throws Exception {
         // Test that the initial position supplied for the overlay covers the <div> we created.
         final DialogOverlayImpl overlay =
-                createOverlay(mDivXPx, mDivYPx, mDivWidthPx, mDivHeightPx);
+                mActivityTestRule.createOverlay(mDivXPx, mDivYPx, mDivWidthPx, mDivHeightPx);
         Surface surface = waitForSurface(overlay);
 
         assertDivIsExactlyCovered(surface);
     }
 
+    @Test
     @MediumTest
     @Feature({"AndroidOverlay"})
     public void testScheduleLayout() throws Exception {
         // Test that scheduleLayout() moves the overlay to cover the <div>.
-        final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        final DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
         Surface surface = waitForSurface(overlay);
 
         final org.chromium.gfx.mojom.Rect rect = new org.chromium.gfx.mojom.Rect();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java
index 3699576..48bf897 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java
@@ -7,37 +7,42 @@
 import android.support.test.filters.SmallTest;
 
 import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.androidoverlay.DialogOverlayImplTestRule.Client;
 
 /**
  * Tests for DialogOverlayImpl.
- * TODO(liberato): Convert to junit4.
  */
-public class DialogOverlayImplTest extends DialogOverlayImplTestBase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class DialogOverlayImplTest {
     private static final String BLANK_URL = "about://blank";
 
-    @Override
-    protected String getInitialUrl() {
-        return BLANK_URL;
-    }
+    @Rule
+    public DialogOverlayImplTestRule mActivityTestRule =
+            new DialogOverlayImplTestRule(BLANK_URL);
 
+    @Test
     @SmallTest
     @Feature({"AndroidOverlay"})
     public void testCreateDestroyOverlay() {
-        Assert.assertFalse(getClient().hasReceivedOverlayModeChange());
-        Assert.assertFalse(getClient().isUsingOverlayMode());
+        Assert.assertFalse(mActivityTestRule.getClient().hasReceivedOverlayModeChange());
+        Assert.assertFalse(mActivityTestRule.getClient().isUsingOverlayMode());
 
-        final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        final DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
 
         // We should get a new overlay with a valid surface key.
-        Client.Event event = getClient().nextEvent();
+        Client.Event event = mActivityTestRule.getClient().nextEvent();
         Assert.assertEquals(Client.SURFACE_READY, event.which);
         Assert.assertTrue(event.surfaceKey > 0);
 
-        Assert.assertTrue(getClient().hasReceivedOverlayModeChange());
-        Assert.assertTrue(getClient().isUsingOverlayMode());
+        Assert.assertTrue(mActivityTestRule.getClient().hasReceivedOverlayModeChange());
+        Assert.assertTrue(mActivityTestRule.getClient().isUsingOverlayMode());
 
         // Close the overlay, and make sure that the provider is notified.
         // Note that we should not get a 'destroyed' message when we close it.
@@ -47,67 +52,71 @@
                 overlay.close();
             }
         });
-        Assert.assertEquals(Client.RELEASED, getClient().nextEvent().which);
-        Assert.assertFalse(getClient().isUsingOverlayMode());
+        Assert.assertEquals(Client.RELEASED, mActivityTestRule.getClient().nextEvent().which);
+        Assert.assertFalse(mActivityTestRule.getClient().isUsingOverlayMode());
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidOverlay"})
     public void testCreateOverlayFailsIfUnknownRoutingToken() {
         // Try to create an overlay with a bad routing token.
-        mRoutingToken.high++;
-        DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        mActivityTestRule.incrementUnguessableTokenHigh();
+        DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
         Assert.assertNotNull(overlay);
 
         // We should be notified that the overlay is destroyed.
-        Client.Event event = getClient().nextEvent();
+        Client.Event event = mActivityTestRule.getClient().nextEvent();
         Assert.assertEquals(Client.DESTROYED, event.which);
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidOverlay"})
     public void testCreateOverlayFailsIfWebContentsHidden() {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getWebContents().onHide();
+                mActivityTestRule.getWebContents().onHide();
             }
         });
 
-        DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
         Assert.assertNotNull(overlay);
 
         // We should be notified that the overlay is destroyed.
-        Client.Event event = getClient().nextEvent();
+        Client.Event event = mActivityTestRule.getClient().nextEvent();
         Assert.assertEquals(Client.DESTROYED, event.which);
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidOverlay"})
     public void testHiddingWebContentsDestroysOverlay() {
-        DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
         Assert.assertNotNull(overlay);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getWebContents().onHide();
+                mActivityTestRule.getWebContents().onHide();
             }
         });
 
         // We should be notified that the overlay is destroyed.
-        Client.Event event = getClient().nextEvent();
+        Client.Event event = mActivityTestRule.getClient().nextEvent();
         Assert.assertEquals(Client.DESTROYED, event.which);
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidOverlay"})
     public void testScheduleLayoutDoesntCrash() {
         // Make sure that we don't get any messages due to scheduleLayout, and we don't crash.
-        final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        final DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
 
         // Wait for the surface.
-        Assert.assertEquals(Client.SURFACE_READY, getClient().nextEvent().which);
+        Assert.assertEquals(Client.SURFACE_READY, mActivityTestRule.getClient().nextEvent().which);
         final org.chromium.gfx.mojom.Rect rect = new org.chromium.gfx.mojom.Rect();
         rect.x = 100;
         rect.y = 200;
@@ -121,29 +130,31 @@
         });
 
         // No additional messages should have arrived.
-        Assert.assertTrue(getClient().isEmpty());
+        Assert.assertTrue(mActivityTestRule.getClient().isEmpty());
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidOverlay"})
     public void testCreateSecureSurface() {
         // Test that creating a secure overlay creates an overlay.  We can't really tell if it's
         // secure or not, until we can do a screen shot test.
-        mSecure = true;
-        final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        mActivityTestRule.setSecure(true);
+        final DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
         Assert.assertNotNull(overlay);
 
         // We should get a new overlay with a valid surface key.
-        Client.Event event = getClient().nextEvent();
+        Client.Event event = mActivityTestRule.getClient().nextEvent();
         Assert.assertEquals(Client.SURFACE_READY, event.which);
         Assert.assertTrue(event.surfaceKey > 0);
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidOverlay"})
     public void testCloseOnlyClosesOnce() {
         // Test that trying to close an overlay more than once doesn't actually do anything.
-        final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        final DialogOverlayImpl overlay = mActivityTestRule.createOverlay(0, 0, 10, 10);
         // The first should generate RELEASED
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -151,15 +162,15 @@
                 overlay.close();
             }
         });
-        Assert.assertEquals(Client.RELEASED, getClient().nextEvent().which);
+        Assert.assertEquals(Client.RELEASED, mActivityTestRule.getClient().nextEvent().which);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
                 overlay.close();
-                getClient().injectMarkerEvent();
+                mActivityTestRule.getClient().injectMarkerEvent();
             }
         });
-        Assert.assertEquals(Client.TEST_MARKER, getClient().nextEvent().which);
+        Assert.assertEquals(Client.TEST_MARKER, mActivityTestRule.getClient().nextEvent().which);
     }
 }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestBase.java b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestRule.java
similarity index 66%
rename from content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestBase.java
rename to content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestRule.java
index 73e728f..b8b1ea1 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestBase.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTestRule.java
@@ -8,11 +8,13 @@
 import android.os.HandlerThread;
 
 import org.junit.Assert;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
 
 import org.chromium.base.Callback;
 import org.chromium.base.ThreadUtils;
 import org.chromium.content.browser.framehost.RenderFrameHostImpl;
-import org.chromium.content_shell_apk.ContentShellTestBase;
+import org.chromium.content_shell_apk.ContentShellActivityTestRule;
 import org.chromium.media.mojom.AndroidOverlayClient;
 import org.chromium.media.mojom.AndroidOverlayConfig;
 import org.chromium.mojo.common.mojom.UnguessableToken;
@@ -23,9 +25,9 @@
 import java.util.concurrent.TimeUnit;
 
 /**
- * Base class for tests for DialogOverlayImpl.
+ * TestRule for tests for DialogOverlayImpl.
  */
-public abstract class DialogOverlayImplTestBase extends ContentShellTestBase {
+public class DialogOverlayImplTestRule extends ContentShellActivityTestRule {
     // overlay-ui thread.
     private HandlerThread mOverlayUiThread;
     private Handler mOverlayUiHandler;
@@ -35,10 +37,12 @@
 
     // The routing token that we'll use to create overlays.  This may be modified by the tests prior
     // to calling createOverlay().
-    protected UnguessableToken mRoutingToken;
+    private UnguessableToken mRoutingToken;
 
     // True if we should create a secure overlay.
-    protected boolean mSecure;
+    private boolean mSecure;
+
+    private String mInitialUrl;
 
     /**
      * AndroidOverlay client that supports waiting operations for callbacks.  One may call
@@ -152,57 +156,75 @@
     private Client mClient = new Client();
 
     // Return the URL to start with.
-    protected abstract String getInitialUrl();
+    public DialogOverlayImplTestRule(String url) {
+        mInitialUrl = url;
+    }
 
-    protected Client getClient() {
+    public String getInitialUrl() {
+        return mInitialUrl;
+    }
+
+    public Client getClient() {
         return mClient;
     }
 
+    public void setSecure(boolean secure) {
+        mSecure = secure;
+    }
+
+    public void incrementUnguessableTokenHigh() {
+        mRoutingToken.high++;
+    }
+
+
     @Override
-    public void setUp() throws Exception {
-        super.setUp();
+    public Statement apply(final Statement base, Description desc) {
+        return super.apply(new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                launchContentShellWithUrl(getInitialUrl());
+                waitForActiveShellToBeDoneLoading(); // Do we need this?
 
-        launchContentShellWithUrl(getInitialUrl());
-        waitForActiveShellToBeDoneLoading(); // Do we need this?
+                // Fetch the routing token.
+                mRoutingToken = ThreadUtils.runOnUiThreadBlockingNoException(
+                        new Callable<UnguessableToken>() {
+                            @Override
+                            public UnguessableToken call() {
+                                RenderFrameHostImpl host =
+                                        (RenderFrameHostImpl) getWebContents().getMainFrame();
+                                org.chromium.base.UnguessableToken routingToken =
+                                        host.getAndroidOverlayRoutingToken();
+                                UnguessableToken mojoToken = new UnguessableToken();
+                                mojoToken.high = routingToken.getHighForSerialization();
+                                mojoToken.low = routingToken.getLowForSerialization();
+                                return mojoToken;
+                            }
+                        });
 
-        // Fetch the routing token.
-        mRoutingToken =
-                ThreadUtils.runOnUiThreadBlockingNoException(new Callable<UnguessableToken>() {
+                // Set up the overlay UI thread
+                mOverlayUiThread = new HandlerThread("TestOverlayUI");
+                mOverlayUiThread.start();
+                mOverlayUiHandler = new Handler(mOverlayUiThread.getLooper());
+
+                // Just delegate to |mClient| when an overlay is released.
+                mReleasedRunnable = new Runnable() {
                     @Override
-                    public UnguessableToken call() {
-                        RenderFrameHostImpl host =
-                                (RenderFrameHostImpl) getWebContents().getMainFrame();
-                        org.chromium.base.UnguessableToken routingToken =
-                                host.getAndroidOverlayRoutingToken();
-                        UnguessableToken mojoToken = new UnguessableToken();
-                        mojoToken.high = routingToken.getHighForSerialization();
-                        mojoToken.low = routingToken.getLowForSerialization();
-                        return mojoToken;
+                    public void run() {
+                        mClient.notifyReleased();
                     }
-                });
+                };
 
-        // Set up the overlay UI thread
-        mOverlayUiThread = new HandlerThread("TestOverlayUI");
-        mOverlayUiThread.start();
-        mOverlayUiHandler = new Handler(mOverlayUiThread.getLooper());
+                Callback<Boolean> overlayModeChanged = new Callback<Boolean>() {
+                    @Override
+                    public void onResult(Boolean useOverlayMode) {
+                        mClient.onOverlayModeChanged(useOverlayMode);
+                    }
+                };
 
-        // Just delegate to |mClient| when an overlay is released.
-        mReleasedRunnable = new Runnable() {
-            @Override
-            public void run() {
-                mClient.notifyReleased();
+                getActivityForTestCommon().getActiveShell().setOverayModeChangedCallbackForTesting(
+                        overlayModeChanged);
             }
-        };
-
-        Callback<Boolean> overlayModeChanged = new Callback<Boolean>() {
-            @Override
-            public void onResult(Boolean useOverlayMode) {
-                mClient.onOverlayModeChanged(useOverlayMode);
-            }
-        };
-
-        getActivityForTestCommon().getActiveShell().setOverayModeChangedCallbackForTesting(
-                overlayModeChanged);
+        }, desc);
     }
 
     // Create an overlay with the given parameters and return it.
diff --git a/content/renderer/media_recorder/video_track_recorder_unittest.cc b/content/renderer/media_recorder/video_track_recorder_unittest.cc
index 572c216..b46b6c2 100644
--- a/content/renderer/media_recorder/video_track_recorder_unittest.cc
+++ b/content/renderer/media_recorder/video_track_recorder_unittest.cc
@@ -338,12 +338,19 @@
       VideoFrame::CreateBlackFrame(frame_size);
 
   base::RunLoop run_loop;
-  video_frame->AddDestructionObserver(run_loop.QuitClosure());
-  EXPECT_CALL(*this, DoOnEncodedVideo(_, _, _, _, true)).Times(1);
+  base::Closure quit_closure = run_loop.QuitWhenIdleClosure();
+  bool frame_is_destroyed = false;
+  auto set_to_true = [](bool* b) { *b = true; };
+  video_frame->AddDestructionObserver(
+      base::BindOnce(set_to_true, &frame_is_destroyed));
+  EXPECT_CALL(*this, DoOnEncodedVideo(_, _, _, _, true))
+      .Times(1)
+      .WillOnce(RunClosure(quit_closure));
   Encode(video_frame, base::TimeTicks::Now());
   video_frame = nullptr;
   run_loop.Run();
   EXPECT_EQ(0u, NumFramesInEncode());
+  EXPECT_TRUE(frame_is_destroyed);
 
   Mock::VerifyAndClearExpectations(this);
 }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 0aa8441..9e37d7d 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1609,6 +1609,7 @@
     IPC_MESSAGE_HANDLER(FrameMsg_SwapIn, OnSwapIn)
     IPC_MESSAGE_HANDLER(FrameMsg_Delete, OnDeleteFrame)
     IPC_MESSAGE_HANDLER(FrameMsg_Stop, OnStop)
+    IPC_MESSAGE_HANDLER(FrameMsg_DroppedNavigation, OnDroppedNavigation)
     IPC_MESSAGE_HANDLER(FrameMsg_Collapse, OnCollapse)
     IPC_MESSAGE_HANDLER(FrameMsg_ContextMenuClosed, OnContextMenuClosed)
     IPC_MESSAGE_HANDLER(FrameMsg_CustomContextMenuAction,
@@ -4850,6 +4851,12 @@
     observer.OnStop();
 }
 
+void RenderFrameImpl::OnDroppedNavigation() {
+  browser_side_navigation_pending_ = false;
+  browser_side_navigation_pending_url_ = GURL();
+  frame_->ClientDroppedNavigation();
+}
+
 void RenderFrameImpl::OnCollapse(bool collapsed) {
   frame_->Collapse(collapsed);
 }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index c699fb5..6c293f4 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -908,6 +908,7 @@
                  const FrameReplicationState& replicated_frame_state);
   void OnDeleteFrame();
   void OnStop();
+  void OnDroppedNavigation();
   void OnCollapse(bool collapse);
   void OnShowContextMenu(const gfx::Point& location);
   void OnContextMenuClosed(const CustomContextMenuContext& custom_context);
diff --git a/extensions/browser/api/media_perception_private/conversion_utils.cc b/extensions/browser/api/media_perception_private/conversion_utils.cc
index 136e023..8ea457e 100644
--- a/extensions/browser/api/media_perception_private/conversion_utils.cc
+++ b/extensions/browser/api/media_perception_private/conversion_utils.cc
@@ -215,6 +215,7 @@
       return mri::State::SUSPENDED;
     case STATUS_RESTARTING:
       return mri::State::RESTARTING;
+    case STATUS_SERVICE_ERROR:
     case STATUS_NONE:
       return mri::State::STATUS_UNSPECIFIED;
   }
diff --git a/extensions/browser/api/media_perception_private/media_perception_api_manager.cc b/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
index d8604e3..0729f07 100644
--- a/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
+++ b/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
@@ -16,6 +16,25 @@
 
 namespace extensions {
 
+namespace {
+
+media_perception::State GetStateForServiceError(
+    const media_perception::ServiceError service_error) {
+  media_perception::State state;
+  state.status = media_perception::STATUS_SERVICE_ERROR;
+  state.service_error = service_error;
+  return state;
+}
+
+media_perception::Diagnostics GetDiagnosticsForServiceError(
+    const media_perception::ServiceError& service_error) {
+  media_perception::Diagnostics diagnostics;
+  diagnostics.service_error = service_error;
+  return diagnostics;
+}
+
+}  // namespace
+
 // static
 MediaPerceptionAPIManager* MediaPerceptionAPIManager::Get(
     content::BrowserContext* context) {
@@ -64,15 +83,15 @@
   }
 
   if (analytics_process_state_ == AnalyticsProcessState::LAUNCHING) {
-    callback.Run(CallbackStatus::PROCESS_LAUNCHING_ERROR,
-                 media_perception::State());
+    callback.Run(GetStateForServiceError(
+        media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING));
     return;
   }
 
   // Calling getState with process not running returns State UNINITIALIZED.
   media_perception::State state_uninitialized;
   state_uninitialized.status = media_perception::STATUS_UNINITIALIZED;
-  callback.Run(CallbackStatus::SUCCESS, std::move(state_uninitialized));
+  callback.Run(std::move(state_uninitialized));
 }
 
 void MediaPerceptionAPIManager::SetState(const media_perception::State& state,
@@ -85,8 +104,8 @@
          "or RESTARTING.";
 
   if (analytics_process_state_ == AnalyticsProcessState::LAUNCHING) {
-    callback.Run(CallbackStatus::PROCESS_LAUNCHING_ERROR,
-                 media_perception::State());
+    callback.Run(GetStateForServiceError(
+        media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING));
     return;
   }
 
@@ -118,7 +137,8 @@
     return;
   }
 
-  callback.Run(CallbackStatus::PROCESS_IDLE_ERROR, media_perception::State());
+  callback.Run(GetStateForServiceError(
+      media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING));
 }
 
 void MediaPerceptionAPIManager::SetStateInternal(
@@ -146,7 +166,8 @@
     bool succeeded) {
   if (!succeeded) {
     analytics_process_state_ = AnalyticsProcessState::IDLE;
-    callback.Run(CallbackStatus::PROCESS_IDLE_ERROR, media_perception::State());
+    callback.Run(GetStateForServiceError(
+        media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING));
     return;
   }
   analytics_process_state_ = AnalyticsProcessState::RUNNING;
@@ -158,7 +179,8 @@
     bool succeeded) {
   if (!succeeded) {
     analytics_process_state_ = AnalyticsProcessState::IDLE;
-    callback.Run(CallbackStatus::PROCESS_IDLE_ERROR, media_perception::State());
+    callback.Run(GetStateForServiceError(
+        media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING));
     return;
   }
   analytics_process_state_ = AnalyticsProcessState::RUNNING;
@@ -170,11 +192,11 @@
                                               const mri::State& state_proto) {
   media_perception::State state;
   if (!succeeded) {
-    callback.Run(CallbackStatus::DBUS_ERROR, media_perception::State());
+    callback.Run(GetStateForServiceError(
+        media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE));
     return;
   }
-  callback.Run(CallbackStatus::SUCCESS,
-               media_perception::StateProtoToIdl(state_proto));
+  callback.Run(media_perception::StateProtoToIdl(state_proto));
 }
 
 void MediaPerceptionAPIManager::GetDiagnosticsCallback(
@@ -182,11 +204,11 @@
     bool succeeded,
     const mri::Diagnostics& diagnostics_proto) {
   if (!succeeded) {
-    callback.Run(CallbackStatus::DBUS_ERROR, media_perception::Diagnostics());
+    callback.Run(GetDiagnosticsForServiceError(
+        media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE));
     return;
   }
-  callback.Run(CallbackStatus::SUCCESS,
-               media_perception::DiagnosticsProtoToIdl(diagnostics_proto));
+  callback.Run(media_perception::DiagnosticsProtoToIdl(diagnostics_proto));
 }
 
 void MediaPerceptionAPIManager::MediaPerceptionSignalHandler(
diff --git a/extensions/browser/api/media_perception_private/media_perception_api_manager.h b/extensions/browser/api/media_perception_private/media_perception_api_manager.h
index 28f7dfd..52d3d43 100644
--- a/extensions/browser/api/media_perception_private/media_perception_api_manager.h
+++ b/extensions/browser/api/media_perception_private/media_perception_api_manager.h
@@ -14,24 +14,10 @@
 
 class MediaPerceptionAPIManager : public BrowserContextKeyedAPI {
  public:
-  enum class CallbackStatus {
-    // Request to media analytics process was successful.
-    SUCCESS,
-    // Request to media analytics process failed at D-Bus layer.
-    DBUS_ERROR,
-    // The media analytics process is not running.
-    PROCESS_IDLE_ERROR,
-    // The media analytics process is still being launched via Upstart
-    // service.
-    PROCESS_LAUNCHING_ERROR
-  };
-
   using APIStateCallback = base::Callback<void(
-      CallbackStatus status,
       extensions::api::media_perception_private::State state)>;
 
   using APIGetDiagnosticsCallback = base::Callback<void(
-      CallbackStatus status,
       extensions::api::media_perception_private::Diagnostics diagnostics)>;
 
   explicit MediaPerceptionAPIManager(content::BrowserContext* context);
diff --git a/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc b/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc
index a94b7b7e..dc62a6c 100644
--- a/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc
+++ b/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc
@@ -80,36 +80,54 @@
 
 namespace extensions {
 
-using CallbackStatus = MediaPerceptionAPIManager::CallbackStatus;
-
 namespace {
 
-void RecordStatusAndRunClosure(base::Closure quit_run_loop,
-                               CallbackStatus* status,
-                               CallbackStatus result_status,
-                               media_perception::State result_state) {
-  *status = result_status;
+void RecordServiceErrorFromStateAndRunClosure(
+    base::Closure quit_run_loop,
+    media_perception::ServiceError* service_error,
+    media_perception::State result_state) {
+  *service_error = result_state.service_error;
   quit_run_loop.Run();
 }
 
-CallbackStatus SetStateAndWaitForResponse(
+void RecordServiceErrorFromDiagnosticsAndRunClosure(
+    base::Closure quit_run_loop,
+    media_perception::ServiceError* service_error,
+    media_perception::Diagnostics result_diagnostics) {
+  *service_error = result_diagnostics.service_error;
+  quit_run_loop.Run();
+}
+
+media_perception::ServiceError SetStateAndWaitForResponse(
     MediaPerceptionAPIManager* manager,
     const media_perception::State& state) {
   base::RunLoop run_loop;
-  CallbackStatus status;
-  manager->SetState(state, base::Bind(&RecordStatusAndRunClosure,
-                                      run_loop.QuitClosure(), &status));
+  media_perception::ServiceError service_error;
+  manager->SetState(state, base::Bind(&RecordServiceErrorFromStateAndRunClosure,
+                                      run_loop.QuitClosure(), &service_error));
   run_loop.Run();
-  return status;
+  return service_error;
 }
 
-CallbackStatus GetStateAndWaitForResponse(MediaPerceptionAPIManager* manager) {
+media_perception::ServiceError GetStateAndWaitForResponse(
+    MediaPerceptionAPIManager* manager) {
   base::RunLoop run_loop;
-  CallbackStatus status;
-  manager->GetState(
-      base::Bind(&RecordStatusAndRunClosure, run_loop.QuitClosure(), &status));
+  media_perception::ServiceError service_error;
+  manager->GetState(base::Bind(&RecordServiceErrorFromStateAndRunClosure,
+                               run_loop.QuitClosure(), &service_error));
   run_loop.Run();
-  return status;
+  return service_error;
+}
+
+media_perception::ServiceError GetDiagnosticsAndWaitForResponse(
+    MediaPerceptionAPIManager* manager) {
+  base::RunLoop run_loop;
+  media_perception::ServiceError service_error;
+  manager->GetDiagnostics(
+      base::Bind(&RecordServiceErrorFromDiagnosticsAndRunClosure,
+                 run_loop.QuitClosure(), &service_error));
+  run_loop.Run();
+  return service_error;
 }
 
 }  // namespace
@@ -160,16 +178,17 @@
   state.status = media_perception::STATUS_RUNNING;
 
   base::RunLoop run_loop;
-  CallbackStatus status;
-  manager_->SetState(state, base::Bind(&RecordStatusAndRunClosure,
-                                       run_loop.QuitClosure(), &status));
+  media_perception::ServiceError service_error;
+  manager_->SetState(state,
+                     base::Bind(&RecordServiceErrorFromStateAndRunClosure,
+                                run_loop.QuitClosure(), &service_error));
   EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(false));
   run_loop.Run();
-  EXPECT_EQ(CallbackStatus::PROCESS_IDLE_ERROR, status);
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING, service_error);
 
   // Check that after a failed request, setState RUNNING will go through.
   upstart_client_->set_enqueue_requests(false);
-  EXPECT_EQ(CallbackStatus::SUCCESS,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE,
             SetStateAndWaitForResponse(manager_.get(), state));
 }
 
@@ -179,17 +198,18 @@
   state.status = media_perception::STATUS_RESTARTING;
 
   base::RunLoop run_loop;
-  CallbackStatus status;
-  manager_->SetState(state, base::Bind(&RecordStatusAndRunClosure,
-                                       run_loop.QuitClosure(), &status));
+  media_perception::ServiceError service_error;
+  manager_->SetState(state,
+                     base::Bind(&RecordServiceErrorFromStateAndRunClosure,
+                                run_loop.QuitClosure(), &service_error));
   EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(false));
   run_loop.Run();
-  EXPECT_EQ(CallbackStatus::PROCESS_IDLE_ERROR, status);
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING, service_error);
 
   // Check that after a failed request, setState restarted will still go
   // through.
   upstart_client_->set_enqueue_requests(false);
-  EXPECT_EQ(CallbackStatus::SUCCESS,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE,
             SetStateAndWaitForResponse(manager_.get(), state));
 }
 
@@ -199,24 +219,25 @@
   state.status = media_perception::STATUS_RUNNING;
 
   base::RunLoop run_loop;
-  CallbackStatus status;
-  manager_->SetState(state, base::Bind(&RecordStatusAndRunClosure,
-                                       run_loop.QuitClosure(), &status));
+  media_perception::ServiceError service_error;
+  manager_->SetState(state,
+                     base::Bind(&RecordServiceErrorFromStateAndRunClosure,
+                                run_loop.QuitClosure(), &service_error));
 
-  EXPECT_EQ(CallbackStatus::PROCESS_LAUNCHING_ERROR,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING,
             GetStateAndWaitForResponse(manager_.get()));
-  EXPECT_EQ(CallbackStatus::PROCESS_LAUNCHING_ERROR,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING,
             SetStateAndWaitForResponse(manager_.get(), state));
   EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(true));
   run_loop.Run();
-  EXPECT_EQ(CallbackStatus::SUCCESS, status);
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, service_error);
 
   // Verify that after the slow start, things works as normal.
   upstart_client_->set_enqueue_requests(false);
-  EXPECT_EQ(CallbackStatus::SUCCESS,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE,
             GetStateAndWaitForResponse(manager_.get()));
   state.status = media_perception::STATUS_SUSPENDED;
-  EXPECT_EQ(CallbackStatus::SUCCESS,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE,
             SetStateAndWaitForResponse(manager_.get(), state));
 }
 
@@ -226,38 +247,42 @@
   state.status = media_perception::STATUS_RESTARTING;
 
   base::RunLoop run_loop;
-  CallbackStatus status;
-  manager_->SetState(state, base::Bind(&RecordStatusAndRunClosure,
-                                       run_loop.QuitClosure(), &status));
+  media_perception::ServiceError service_error;
+  manager_->SetState(state,
+                     base::Bind(&RecordServiceErrorFromStateAndRunClosure,
+                                run_loop.QuitClosure(), &service_error));
 
-  EXPECT_EQ(CallbackStatus::PROCESS_LAUNCHING_ERROR,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING,
             GetStateAndWaitForResponse(manager_.get()));
-  EXPECT_EQ(CallbackStatus::PROCESS_LAUNCHING_ERROR,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING,
             SetStateAndWaitForResponse(manager_.get(), state));
   EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(true));
   run_loop.Run();
-  EXPECT_EQ(CallbackStatus::SUCCESS, status);
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, service_error);
 
   // Verify that after the slow start, things works as normal.
   upstart_client_->set_enqueue_requests(false);
-  EXPECT_EQ(CallbackStatus::SUCCESS,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE,
             GetStateAndWaitForResponse(manager_.get()));
   state.status = media_perception::STATUS_RUNNING;
-  EXPECT_EQ(CallbackStatus::SUCCESS,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE,
             SetStateAndWaitForResponse(manager_.get(), state));
 }
 
 TEST_F(MediaPerceptionAPIManagerTest, MediaAnalyticsDbusError) {
   media_perception::State state;
   state.status = media_perception::STATUS_RUNNING;
-  EXPECT_EQ(CallbackStatus::SUCCESS,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_NONE,
             SetStateAndWaitForResponse(manager_.get(), state));
   // Disable the functionality of the fake process.
   media_analytics_client_->set_process_running(false);
-  EXPECT_EQ(CallbackStatus::DBUS_ERROR,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE,
             GetStateAndWaitForResponse(manager_.get()));
-  EXPECT_EQ(CallbackStatus::DBUS_ERROR,
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE,
             SetStateAndWaitForResponse(manager_.get(), state));
+  // Check that getting diagnostics also errors in the same way.
+  EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE,
+            GetDiagnosticsAndWaitForResponse(manager_.get()));
 }
 
 }  // namespace extensions
diff --git a/extensions/browser/api/media_perception_private/media_perception_private_api.cc b/extensions/browser/api/media_perception_private/media_perception_private_api.cc
index 54af2bd..4e5e07e6 100644
--- a/extensions/browser/api/media_perception_private/media_perception_private_api.cc
+++ b/extensions/browser/api/media_perception_private/media_perception_private_api.cc
@@ -8,31 +8,6 @@
 
 namespace extensions {
 
-using CallbackStatus = MediaPerceptionAPIManager::CallbackStatus;
-
-namespace {
-
-const char kErrorStringStatusDbusError[] = "Service is unreachable.";
-const char kErrorStringStatusIdle[] = "Service is not running.";
-const char kErrorStringStatusLaunching[] = "Service busy launching.";
-
-std::string CallbackStatusToErrorMessage(const CallbackStatus& status) {
-  switch (status) {
-    case CallbackStatus::DBUS_ERROR:
-      return kErrorStringStatusDbusError;
-    case CallbackStatus::PROCESS_IDLE_ERROR:
-      return kErrorStringStatusIdle;
-    case CallbackStatus::PROCESS_LAUNCHING_ERROR:
-      return kErrorStringStatusLaunching;
-    case CallbackStatus::SUCCESS:
-      return "CallbackStatus success.";
-  }
-  NOTREACHED() << "Reached CallbackStatus not in switch.";
-  return "CallbackStatus string not found.";
-}
-
-}  // namespace
-
 MediaPerceptionPrivateGetStateFunction ::
     MediaPerceptionPrivateGetStateFunction() {}
 
@@ -49,12 +24,7 @@
 }
 
 void MediaPerceptionPrivateGetStateFunction::GetStateCallback(
-    CallbackStatus status,
     media_perception::State state) {
-  if (status != CallbackStatus::SUCCESS) {
-    Respond(Error(CallbackStatusToErrorMessage(status)));
-    return;
-  }
   Respond(OneArgument(state.ToValue()));
 }
 
@@ -92,12 +62,7 @@
 }
 
 void MediaPerceptionPrivateSetStateFunction::SetStateCallback(
-    CallbackStatus status,
     media_perception::State state) {
-  if (status != CallbackStatus::SUCCESS) {
-    Respond(Error(CallbackStatusToErrorMessage(status)));
-    return;
-  }
   Respond(OneArgument(state.ToValue()));
 }
 
@@ -118,12 +83,7 @@
 }
 
 void MediaPerceptionPrivateGetDiagnosticsFunction::GetDiagnosticsCallback(
-    CallbackStatus status,
     media_perception::Diagnostics diagnostics) {
-  if (status != CallbackStatus::SUCCESS) {
-    Respond(Error(CallbackStatusToErrorMessage(status)));
-    return;
-  }
   Respond(OneArgument(diagnostics.ToValue()));
 }
 
diff --git a/extensions/browser/api/media_perception_private/media_perception_private_api.h b/extensions/browser/api/media_perception_private/media_perception_private_api.h
index 3528a50..a9657bd 100644
--- a/extensions/browser/api/media_perception_private/media_perception_private_api.h
+++ b/extensions/browser/api/media_perception_private/media_perception_private_api.h
@@ -24,8 +24,7 @@
   // ExtensionFunction:
   ResponseAction Run() override;
 
-  void GetStateCallback(MediaPerceptionAPIManager::CallbackStatus status,
-                        extensions::api::media_perception_private::State state);
+  void GetStateCallback(extensions::api::media_perception_private::State state);
 
   DISALLOW_COPY_AND_ASSIGN(MediaPerceptionPrivateGetStateFunction);
 };
@@ -43,8 +42,7 @@
   // ExtensionFunction:
   ResponseAction Run() override;
 
-  void SetStateCallback(MediaPerceptionAPIManager::CallbackStatus status,
-                        extensions::api::media_perception_private::State state);
+  void SetStateCallback(extensions::api::media_perception_private::State state);
 
   DISALLOW_COPY_AND_ASSIGN(MediaPerceptionPrivateSetStateFunction);
 };
@@ -63,7 +61,6 @@
   ResponseAction Run() override;
 
   void GetDiagnosticsCallback(
-      MediaPerceptionAPIManager::CallbackStatus status,
       extensions::api::media_perception_private::Diagnostics diagnostics);
 
   DISALLOW_COPY_AND_ASSIGN(MediaPerceptionPrivateGetDiagnosticsFunction);
diff --git a/extensions/common/api/media_perception_private.idl b/extensions/common/api/media_perception_private.idl
index 3ce4b9b..64325bc 100644
--- a/extensions/common/api/media_perception_private.idl
+++ b/extensions/common/api/media_perception_private.idl
@@ -30,11 +30,28 @@
     SUSPENDED,
 
     // Enum for restarting the media analytics process using upstart.
-    // Calling SetState <code>RESTARTING</code> will restart the media process
+    // Calling setState <code>RESTARTING</code> will restart the media process
     // to the <code>SUSPENDED</code> state. The app has to set the state to
     // <code>RUNNING</code> in order to start receiving media perception
     // information again.
-    RESTARTING
+    RESTARTING,
+
+    // Indicates that a ServiceError has occurred.
+    SERVICE_ERROR
+  };
+
+  enum ServiceError {
+    // The media analytics process could not be reached. This is likely due to
+    // a faulty comms configuration or that the process crashed.
+    SERVICE_UNREACHABLE,
+
+    // The media analytics process is not running. The MPP API knows that the
+    // process has not been started yet.
+    SERVICE_NOT_RUNNING,
+
+    // The media analytics process is busy launching. Wait for setState
+    // <code>RUNNING</code> or setState <code>RESTARTING</code> callback.
+    SERVICE_BUSY_LAUNCHING
   };
 
   // The system and configuration state of the analytics process.
@@ -45,6 +62,10 @@
     // analytics process should open while the media processing pipeline is
     // starting. To set this parameter, status has to be <code>RUNNING</code>.
     DOMString? deviceContext;
+
+    // Return parameter for $(ref:setState) or $(ref:getState) that
+    // specifies the error type for failure cases.
+    ServiceError? serviceError;
   };
 
   dictionary Point {
@@ -158,6 +179,10 @@
   };
 
   dictionary Diagnostics {
+    // Return parameter for $(ref:getDiagnostics) that specifies the error
+    // type for failure cases.
+    ServiceError? serviceError;
+
     // A buffer of image frames and the associated video analytics information
     // that can be used to diagnose a malfunction.
     PerceptionSample[]? perceptionSamples;
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index e3bf92c..f468c49 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -1,6 +1,6 @@
 {
   "name": "gpu driver bug list",
-  "version": "10.28",
+  "version": "10.29",
   "entries": [
     {
       "id": 1,
@@ -2609,7 +2609,7 @@
     },
     {
       "id": 240,
-      "cr_bugs": [750306],
+      "cr_bugs": [750306, 764526],
       "description": "glGetQueryObject(GL_QUERY_RESULT_AVAILABLE) blocks unexpectedly on Adreno",
       "os": {
         "type": "android",
@@ -2618,7 +2618,7 @@
           "value": "9.0"
         }
       },
-      "gl_renderer": "Adreno \\(TM\\) 530",
+      "gl_renderer": "Adreno \\(TM\\) 5[34]0",
       "disabled_extensions": [
         "GL_EXT_disjoint_timer_query",
         "GL_EXT_disjoint_timer_query_webgl2"
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index a8103ac..03b4a8f 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -1432,8 +1432,12 @@
   _lastRegisteredRequestURL = requestURL;
 
   if (!redirect) {
-    // Record state of outgoing page.
-    [self recordStateInHistory];
+    if (!self.nativeController) {
+      // Record the state of outgoing web view. Do nothing if native controller
+      // exists, because in that case recordStateInHistory will record the state
+      // of incoming page as native controller is already inserted.
+      [self recordStateInHistory];
+    }
   }
 
   [_delegate webWillAddPendingURL:requestURL transition:transition];
diff --git a/media/base/video_color_space.cc b/media/base/video_color_space.cc
index 03af659..30b62c5c 100644
--- a/media/base/video_color_space.cc
+++ b/media/base/video_color_space.cc
@@ -53,6 +53,19 @@
          matrix != other.matrix || range != other.range;
 }
 
+bool VideoColorSpace::IsSpecified() const {
+  if (primaries != PrimaryID::INVALID && primaries != PrimaryID::UNSPECIFIED)
+    return true;
+  if (transfer != TransferID::INVALID && transfer != TransferID::UNSPECIFIED)
+    return true;
+  if (matrix != MatrixID::INVALID && matrix != MatrixID::UNSPECIFIED)
+    return true;
+  // Note that it's not enough to have a range for a video color space to
+  // be considered valid, because often the range is just specified with
+  // a bool, so there is no way to know if it was set specifically or not.
+  return false;
+}
+
 gfx::ColorSpace VideoColorSpace::ToGfxColorSpace() const {
   gfx::ColorSpace::PrimaryID primary_id = gfx::ColorSpace::PrimaryID::INVALID;
   gfx::ColorSpace::TransferID transfer_id =
diff --git a/media/base/video_color_space.h b/media/base/video_color_space.h
index 59ec578e..ee639452 100644
--- a/media/base/video_color_space.h
+++ b/media/base/video_color_space.h
@@ -82,6 +82,9 @@
 
   bool operator==(const VideoColorSpace& other) const;
   bool operator!=(const VideoColorSpace& other) const;
+  // Returns true if any of the fields have a value other
+  // than INVALID or UNSPECIFIED.
+  bool IsSpecified() const;
 
   // These will return INVALID if the number you give it
   // is not a valid enum value.
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
index 6c056b0..2b99249 100644
--- a/media/filters/chunk_demuxer_unittest.cc
+++ b/media/filters/chunk_demuxer_unittest.cc
@@ -19,6 +19,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_feature_list.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/decoder_buffer.h"
 #include "media/base/decrypt_config.h"
@@ -45,9 +46,18 @@
 using ::testing::SaveArg;
 using ::testing::SetArgPointee;
 using ::testing::StrictMock;
+using ::testing::Values;
 using ::testing::WithParamInterface;
 using ::testing::_;
 
+namespace {
+
+// See https://crbug.com/718641 and kMseBufferByPts. This controls which kind of
+// buffering implementation is constructed and tested.
+enum class BufferingApi { kLegacyByDts, kNewByPts };
+
+}  // namespace
+
 namespace media {
 
 const uint8_t kTracksHeader[] = {
@@ -153,7 +163,9 @@
   *called = true;
 }
 
-class ChunkDemuxerTest : public ::testing::Test {
+// Test parameter determines if media::kMseBufferByPts feature should be forced
+// on or off for the test.
+class ChunkDemuxerTest : public ::testing::TestWithParam<BufferingApi> {
  public:
   // Public method because test cases use it directly.
   MOCK_METHOD1(DemuxerInitialized, void(PipelineStatus));
@@ -182,6 +194,15 @@
   ChunkDemuxerTest()
       : did_progress_(false),
         append_window_end_for_next_append_(kInfiniteDuration) {
+    buffering_api_ = GetParam();
+    switch (buffering_api_) {
+      case BufferingApi::kLegacyByDts:
+        scoped_feature_list_.InitAndDisableFeature(media::kMseBufferByPts);
+        break;
+      case BufferingApi::kNewByPts:
+        scoped_feature_list_.InitAndEnableFeature(media::kMseBufferByPts);
+        break;
+    }
     init_segment_received_cb_ = base::Bind(
         &ChunkDemuxerTest::InitSegmentReceived, base::Unretained(this));
     CreateNewDemuxer();
@@ -1325,6 +1346,9 @@
   base::TimeDelta append_window_start_for_next_append_;
   base::TimeDelta append_window_end_for_next_append_;
 
+  BufferingApi buffering_api_;
+  base::test::ScopedFeatureList scoped_feature_list_;
+
   // Map of source id to timestamp offset to use for the next AppendData()
   // operation for that source id.
   std::map<std::string, base::TimeDelta> timestamp_offset_map_;
@@ -1348,7 +1372,7 @@
   DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest);
 };
 
-TEST_F(ChunkDemuxerTest, Init) {
+TEST_P(ChunkDemuxerTest, Init) {
   InSequence s;
 
   // Test no streams, audio-only, video-only, and audio & video scenarios.
@@ -1419,7 +1443,7 @@
 
 // TODO(acolwell): Fold this test into Init tests since the tests are
 // almost identical.
-TEST_F(ChunkDemuxerTest, InitText) {
+TEST_P(ChunkDemuxerTest, InitText) {
   // Test with 1 video stream and 1 text streams, and 0 or 1 audio streams.
   // No encryption cases handled here.
   bool has_video = true;
@@ -1486,7 +1510,7 @@
   }
 }
 
-TEST_F(ChunkDemuxerTest, SingleTextTrackIdChange) {
+TEST_P(ChunkDemuxerTest, SingleTextTrackIdChange) {
   // Test with 1 video stream, 1 audio, and 1 text stream. Send a second init
   // segment in which the text track ID changes. Verify appended buffers before
   // and after the second init segment map to the same underlying track buffers.
@@ -1534,7 +1558,7 @@
   ShutdownDemuxer();
 }
 
-TEST_F(ChunkDemuxerTest, AudioVideoTrackIdsChange) {
+TEST_P(ChunkDemuxerTest, AudioVideoTrackIdsChange) {
   // Test with 1 audio and 1 video stream. Send a second init segment in which
   // the audio and video track IDs change. Verify that appended buffers before
   // and after the second init segment map to the same underlying track buffers.
@@ -1563,7 +1587,7 @@
   ShutdownDemuxer();
 }
 
-TEST_F(ChunkDemuxerTest, InitSegmentSetsNeedRandomAccessPointFlag) {
+TEST_P(ChunkDemuxerTest, InitSegmentSetsNeedRandomAccessPointFlag) {
   // Tests that non-key-frames following an init segment are allowed
   // and dropped, as expected if the initialization segment received
   // algorithm correctly sets the needs random access point flag to true for all
@@ -1599,7 +1623,7 @@
   CheckExpectedBuffers(text_stream, "25K 40K 80K 90K");
 }
 
-TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) {
+TEST_P(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(&host_, base::Bind(&ChunkDemuxerTest::DemuxerInitialized,
                                           base::Unretained(this)),
@@ -1615,7 +1639,7 @@
   ShutdownDemuxer();
 }
 
-TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) {
+TEST_P(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(&host_, base::Bind(&ChunkDemuxerTest::DemuxerInitialized,
                                           base::Unretained(this)),
@@ -1637,7 +1661,7 @@
 
 // Verifies that all streams waiting for data receive an end of stream
 // buffer when Shutdown() is called.
-TEST_F(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) {
+TEST_P(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) {
   DemuxerStream* text_stream = NULL;
   EXPECT_CALL(host_, AddTextStream(_, _))
       .WillOnce(SaveArg<0>(&text_stream));
@@ -1667,7 +1691,7 @@
 
 // Test that Seek() completes successfully when the first cluster
 // arrives.
-TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) {
+TEST_P(ChunkDemuxerTest, AppendDataAfterSeek) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
 
@@ -1689,7 +1713,7 @@
 }
 
 // Test that parsing errors are handled for clusters appended after init.
-TEST_F(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) {
+TEST_P(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) {
   InSequence s;
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
@@ -1701,7 +1725,7 @@
 // Test the case where a Seek() is requested while the parser
 // is in the middle of cluster. This is to verify that the parser
 // does not reset itself on a seek.
-TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) {
+TEST_P(ChunkDemuxerTest, SeekWhileParsingCluster) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   InSequence s;
@@ -1732,7 +1756,7 @@
 }
 
 // Test the case where AppendData() is called before Init().
-TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) {
+TEST_P(ChunkDemuxerTest, AppendDataBeforeInit) {
   std::unique_ptr<uint8_t[]> info_tracks;
   int info_tracks_size = 0;
   CreateInitSegment(HAS_AUDIO | HAS_VIDEO,
@@ -1744,7 +1768,7 @@
 }
 
 // Make sure Read() callbacks are dispatched with the proper data.
-TEST_F(ChunkDemuxerTest, Read) {
+TEST_P(ChunkDemuxerTest, Read) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
@@ -1762,7 +1786,7 @@
   EXPECT_TRUE(video_read_done);
 }
 
-TEST_F(ChunkDemuxerTest, OutOfOrderClusters) {
+TEST_P(ChunkDemuxerTest, OutOfOrderClusters) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
@@ -1798,7 +1822,7 @@
   CheckExpectedBuffers(video_stream, "45K");
 }
 
-TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) {
+TEST_P(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
 
@@ -1825,7 +1849,7 @@
       &timestamp_offset_map_[kSourceId]));
 }
 
-TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) {
+TEST_P(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
 
@@ -1852,8 +1876,7 @@
       &timestamp_offset_map_[kSourceId]));
 }
 
-
-TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) {
+TEST_P(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
 
@@ -1875,7 +1898,7 @@
 
 // Test the case where a cluster is passed to AppendCluster() before
 // INFO & TRACKS data.
-TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) {
+TEST_P(ChunkDemuxerTest, ClusterBeforeInitSegment) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, NewExpectedStatusCB(CHUNK_DEMUXER_ERROR_APPEND_FAILED), true);
@@ -1888,14 +1911,14 @@
 }
 
 // Test cases where we get an MarkEndOfStream() call during initialization.
-TEST_F(ChunkDemuxerTest, EOSDuringInit) {
+TEST_P(ChunkDemuxerTest, EOSDuringInit) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
   MarkEndOfStream(PIPELINE_OK);
 }
 
-TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) {
+TEST_P(ChunkDemuxerTest, EndOfStreamWithNoAppend) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
@@ -1910,7 +1933,7 @@
   demuxer_.reset();
 }
 
-TEST_F(ChunkDemuxerTest, EndOfStreamWithNoMediaAppend) {
+TEST_P(ChunkDemuxerTest, EndOfStreamWithNoMediaAppend) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   CheckExpectedRanges("{ }");
@@ -1918,7 +1941,7 @@
   CheckExpectedRanges("{ }");
 }
 
-TEST_F(ChunkDemuxerTest, DecodeErrorEndOfStream) {
+TEST_P(ChunkDemuxerTest, DecodeErrorEndOfStream) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
@@ -1930,7 +1953,7 @@
   CheckExpectedRanges(kDefaultFirstClusterRange);
 }
 
-TEST_F(ChunkDemuxerTest, NetworkErrorEndOfStream) {
+TEST_P(ChunkDemuxerTest, NetworkErrorEndOfStream) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
@@ -1989,7 +2012,7 @@
 
 // Make sure that all pending reads that we don't have media data for get an
 // "end of stream" buffer when MarkEndOfStream() is called.
-TEST_F(ChunkDemuxerTest, EndOfStreamWithPendingReads) {
+TEST_P(ChunkDemuxerTest, EndOfStreamWithPendingReads) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 2)));
@@ -2026,7 +2049,7 @@
 
 // Make sure that all Read() calls after we get an MarkEndOfStream()
 // call return an "end of stream" buffer.
-TEST_F(ChunkDemuxerTest, ReadsAfterEndOfStream) {
+TEST_P(ChunkDemuxerTest, ReadsAfterEndOfStream) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 2)));
@@ -2067,7 +2090,7 @@
   end_of_stream_helper_3.CheckIfReadDonesWereCalled(true);
 }
 
-TEST_F(ChunkDemuxerTest, EndOfStreamDuringCanceledSeek) {
+TEST_P(ChunkDemuxerTest, EndOfStreamDuringCanceledSeek) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(0, 10));
@@ -2098,7 +2121,7 @@
 }
 
 // Verify buffered range change behavior for audio/video/text tracks.
-TEST_F(ChunkDemuxerTest, EndOfStreamRangeChanges) {
+TEST_P(ChunkDemuxerTest, EndOfStreamRangeChanges) {
   DemuxerStream* text_stream = NULL;
 
   EXPECT_CALL(host_, AddTextStream(_, _))
@@ -2139,7 +2162,7 @@
 }
 
 // Make sure AppendData() will accept elements that span multiple calls.
-TEST_F(ChunkDemuxerTest, AppendingInPieces) {
+TEST_P(ChunkDemuxerTest, AppendingInPieces) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
@@ -2175,7 +2198,7 @@
   GenerateExpectedReads(0, 9);
 }
 
-TEST_F(ChunkDemuxerTest, WebMFile_AudioAndVideo) {
+TEST_P(ChunkDemuxerTest, WebMFile_AudioAndVideo) {
   struct BufferTimestamps buffer_timestamps[] = {
     {0, 0},
     {33, 3},
@@ -2197,7 +2220,7 @@
   EXPECT_EQ(212949, demuxer_->GetMemoryUsage());
 }
 
-TEST_F(ChunkDemuxerTest, WebMFile_LiveAudioAndVideo) {
+TEST_P(ChunkDemuxerTest, WebMFile_LiveAudioAndVideo) {
   struct BufferTimestamps buffer_timestamps[] = {
     {0, 0},
     {33, 3},
@@ -2219,7 +2242,7 @@
   EXPECT_EQ(212949, demuxer_->GetMemoryUsage());
 }
 
-TEST_F(ChunkDemuxerTest, WebMFile_AudioOnly) {
+TEST_P(ChunkDemuxerTest, WebMFile_AudioOnly) {
   struct BufferTimestamps buffer_timestamps[] = {
     {kSkip, 0},
     {kSkip, 3},
@@ -2242,7 +2265,7 @@
   EXPECT_EQ(18624, demuxer_->GetMemoryUsage());
 }
 
-TEST_F(ChunkDemuxerTest, WebMFile_VideoOnly) {
+TEST_P(ChunkDemuxerTest, WebMFile_VideoOnly) {
   struct BufferTimestamps buffer_timestamps[] = {
     {0, kSkip},
     {33, kSkip},
@@ -2264,7 +2287,7 @@
   EXPECT_EQ(194325, demuxer_->GetMemoryUsage());
 }
 
-TEST_F(ChunkDemuxerTest, WebMFile_AltRefFrames) {
+TEST_P(ChunkDemuxerTest, WebMFile_AltRefFrames) {
   struct BufferTimestamps buffer_timestamps[] = {
     {0, 0},
     {33, 3},
@@ -2281,7 +2304,7 @@
 }
 
 // Verify that we output buffers before the entire cluster has been parsed.
-TEST_F(ChunkDemuxerTest, IncrementalClusterParsing) {
+TEST_P(ChunkDemuxerTest, IncrementalClusterParsing) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   std::unique_ptr<Cluster> cluster(GenerateCluster(0, 6));
@@ -2333,7 +2356,7 @@
   EXPECT_TRUE(video_read_done);
 }
 
-TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) {
+TEST_P(ChunkDemuxerTest, ParseErrorDuringInit) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
@@ -2348,7 +2371,7 @@
       append_window_end_for_next_append_, &timestamp_offset_map_[kSourceId]));
 }
 
-TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) {
+TEST_P(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
@@ -2362,7 +2385,7 @@
   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
 }
 
-TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) {
+TEST_P(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
@@ -2378,7 +2401,7 @@
   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
 }
 
-TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) {
+TEST_P(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
@@ -2394,7 +2417,7 @@
   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO));
 }
 
-TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) {
+TEST_P(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
@@ -2410,7 +2433,7 @@
   ASSERT_FALSE(AppendInitSegment(HAS_VIDEO));
 }
 
-TEST_F(ChunkDemuxerTest, MultipleHeaders) {
+TEST_P(ChunkDemuxerTest, MultipleHeaders) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
@@ -2424,7 +2447,7 @@
   GenerateExpectedReads(0, 9);
 }
 
-TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) {
+TEST_P(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
@@ -2440,7 +2463,7 @@
   GenerateVideoStreamExpectedReads(0, 4);
 }
 
-TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) {
+TEST_P(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) {
   // TODO(matthewjheaney): Here and elsewhere, we need more tests
   // for inband text tracks (http://crbug/321455).
 
@@ -2462,7 +2485,7 @@
   GenerateVideoStreamExpectedReads(0, 4);
 }
 
-TEST_F(ChunkDemuxerTest, AddIdFailures) {
+TEST_P(ChunkDemuxerTest, AddIdFailures) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
@@ -2481,7 +2504,7 @@
 }
 
 // Test that Read() calls after a RemoveId() return "end of stream" buffers.
-TEST_F(ChunkDemuxerTest, RemoveId) {
+TEST_P(ChunkDemuxerTest, RemoveId) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
@@ -2516,7 +2539,7 @@
 
 // Test that removing an ID immediately after adding it does not interfere with
 // quota for new IDs in the future.
-TEST_F(ChunkDemuxerTest, RemoveAndAddId) {
+TEST_P(ChunkDemuxerTest, RemoveAndAddId) {
   std::string audio_id_1 = "audio1";
   ASSERT_TRUE(AddId(audio_id_1, HAS_AUDIO) == ChunkDemuxer::kOk);
   demuxer_->RemoveId(audio_id_1);
@@ -2525,7 +2548,7 @@
   ASSERT_TRUE(AddId(audio_id_2, HAS_AUDIO) == ChunkDemuxer::kOk);
 }
 
-TEST_F(ChunkDemuxerTest, SeekCanceled) {
+TEST_P(ChunkDemuxerTest, SeekCanceled) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   // Append cluster at the beginning of the stream.
@@ -2555,7 +2578,7 @@
   GenerateExpectedReads(0, 4);
 }
 
-TEST_F(ChunkDemuxerTest, SeekCanceledWhileWaitingForSeek) {
+TEST_P(ChunkDemuxerTest, SeekCanceledWhileWaitingForSeek) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   // Append cluster at the beginning of the stream.
@@ -2584,7 +2607,7 @@
 }
 
 // Test that Seek() successfully seeks to all source IDs.
-TEST_F(ChunkDemuxerTest, SeekAudioAndVideoSources) {
+TEST_P(ChunkDemuxerTest, SeekAudioAndVideoSources) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
@@ -2641,7 +2664,7 @@
 // is called before data is available for that seek point.
 // This scenario might be useful if seeking past the end of stream
 // of either audio or video (or both).
-TEST_F(ChunkDemuxerTest, EndOfStreamAfterPastEosSeek) {
+TEST_P(ChunkDemuxerTest, EndOfStreamAfterPastEosSeek) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   AppendMuxedCluster(
@@ -2674,7 +2697,7 @@
 
 // Test that EndOfStream is ignored if coming during a pending seek
 // whose seek time is before some existing ranges.
-TEST_F(ChunkDemuxerTest, EndOfStreamDuringPendingSeek) {
+TEST_P(ChunkDemuxerTest, EndOfStreamDuringPendingSeek) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   AppendMuxedCluster(
@@ -2716,7 +2739,7 @@
 }
 
 // Test ranges in an audio-only stream.
-TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) {
+TEST_P(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
 
   // Test a simple cluster.
@@ -2733,7 +2756,7 @@
 }
 
 // Test ranges in a video-only stream.
-TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) {
+TEST_P(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) {
   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
 
   // Test a simple cluster.
@@ -2749,7 +2772,7 @@
   CheckExpectedRanges("{ [0,132) [200,299) }");
 }
 
-TEST_F(ChunkDemuxerTest, GetBufferedRanges_SeparateStreams) {
+TEST_P(ChunkDemuxerTest, GetBufferedRanges_SeparateStreams) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
@@ -2839,7 +2862,7 @@
       "{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
 }
 
-TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
+TEST_P(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   // Audio block: 0 -> 23
@@ -2925,7 +2948,7 @@
   CheckExpectedRanges("{ [0,23) [300,400) [500,570) [700,750) [900,950) }");
 }
 
-TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideoText) {
+TEST_P(ChunkDemuxerTest, GetBufferedRanges_AudioVideoText) {
   EXPECT_CALL(host_, AddTextStream(_, _));
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
 
@@ -2954,7 +2977,7 @@
 // Once MarkEndOfStream() is called, GetBufferedRanges should not cut off any
 // over-hanging tails at the end of the ranges as this is likely due to block
 // duration differences.
-TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) {
+TEST_P(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23),
@@ -3010,7 +3033,7 @@
   CheckExpectedRanges("{ [0,46) [200,266) [332,398) }");
 }
 
-TEST_F(ChunkDemuxerTest, DifferentStreamTimecodes) {
+TEST_P(ChunkDemuxerTest, DifferentStreamTimecodes) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   // Create a cluster where the video timecode begins 25ms after the audio.
@@ -3028,7 +3051,7 @@
   GenerateExpectedReads(5025, 5000, 8);
 }
 
-TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesSeparateSources) {
+TEST_P(ChunkDemuxerTest, DifferentStreamTimecodesSeparateSources) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
@@ -3050,7 +3073,7 @@
   GenerateVideoStreamExpectedReads(30, 4);
 }
 
-TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesOutOfRange) {
+TEST_P(ChunkDemuxerTest, DifferentStreamTimecodesOutOfRange) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
@@ -3075,7 +3098,7 @@
   ExpectEndOfStream(DemuxerStream::VIDEO);
 }
 
-TEST_F(ChunkDemuxerTest, CodecPrefixMatching) {
+TEST_P(ChunkDemuxerTest, CodecPrefixMatching) {
   ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
 
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
@@ -3092,7 +3115,7 @@
 
 // Test codec ID's that are not compliant with RFC6381, but have been
 // seen in the wild.
-TEST_F(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) {
+TEST_P(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) {
   ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
 
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
@@ -3115,7 +3138,7 @@
   }
 }
 
-TEST_F(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) {
+TEST_P(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   EXPECT_CALL(host_, SetDuration(_))
@@ -3152,7 +3175,7 @@
   EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
 }
 
-TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) {
+TEST_P(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(&host_, base::Bind(&ChunkDemuxerTest::DemuxerInitialized,
                                           base::Unretained(this)),
@@ -3166,7 +3189,7 @@
 
 // Test that Seek() completes successfully when the first cluster
 // arrives.
-TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) {
+TEST_P(ChunkDemuxerTest, EndOfStreamDuringSeek) {
   InSequence s;
 
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
@@ -3193,7 +3216,7 @@
   end_of_stream_helper.CheckIfReadDonesWereCalled(true);
 }
 
-TEST_F(ChunkDemuxerTest, ConfigChange_Video) {
+TEST_P(ChunkDemuxerTest, ConfigChange_Video) {
   InSequence s;
 
   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
@@ -3240,7 +3263,7 @@
   ASSERT_EQ(status, DemuxerStream::kOk);
 }
 
-TEST_F(ChunkDemuxerTest, ConfigChange_Audio) {
+TEST_P(ChunkDemuxerTest, ConfigChange_Audio) {
   InSequence s;
 
   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
@@ -3282,7 +3305,7 @@
   EXPECT_EQ(last_timestamp.InMilliseconds(), 2744);
 }
 
-TEST_F(ChunkDemuxerTest, ConfigChange_Seek) {
+TEST_P(ChunkDemuxerTest, ConfigChange_Seek) {
   InSequence s;
 
   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
@@ -3329,7 +3352,7 @@
   ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
 }
 
-TEST_F(ChunkDemuxerTest, TimestampPositiveOffset) {
+TEST_P(ChunkDemuxerTest, TimestampPositiveOffset) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(SetTimestampOffset(kSourceId, base::TimeDelta::FromSeconds(30)));
@@ -3340,7 +3363,7 @@
   GenerateExpectedReads(30000, 2);
 }
 
-TEST_F(ChunkDemuxerTest, TimestampNegativeOffset) {
+TEST_P(ChunkDemuxerTest, TimestampNegativeOffset) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(SetTimestampOffset(kSourceId, base::TimeDelta::FromSeconds(-1)));
@@ -3349,7 +3372,7 @@
   GenerateExpectedReads(0, 2);
 }
 
-TEST_F(ChunkDemuxerTest, TimestampOffsetSeparateStreams) {
+TEST_P(ChunkDemuxerTest, TimestampOffsetSeparateStreams) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
@@ -3387,7 +3410,7 @@
   GenerateAudioStreamExpectedReads(27300, 4);
 }
 
-TEST_F(ChunkDemuxerTest, IsParsingMediaSegmentMidMediaSegment) {
+TEST_P(ChunkDemuxerTest, IsParsingMediaSegmentMidMediaSegment) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   std::unique_ptr<Cluster> cluster = GenerateCluster(0, 2);
@@ -3414,7 +3437,7 @@
 const char* kMp2tCodecs = "mp4a.40.2,avc1.640028";
 }
 
-TEST_F(ChunkDemuxerTest, EmitBuffersDuringAbort) {
+TEST_P(ChunkDemuxerTest, EmitBuffersDuringAbort) {
   EXPECT_CALL(*this, DemuxerOpened());
   EXPECT_MEDIA_LOG(FoundStream("audio"));
   EXPECT_MEDIA_LOG(CodecName("audio", "aac"));
@@ -3462,7 +3485,7 @@
   EXPECT_GT(range_after_abort.end(0), range_before_abort.end(0));
 }
 
-TEST_F(ChunkDemuxerTest, SeekCompleteDuringAbort) {
+TEST_P(ChunkDemuxerTest, SeekCompleteDuringAbort) {
   EXPECT_CALL(*this, DemuxerOpened());
   EXPECT_MEDIA_LOG(FoundStream("audio"));
   EXPECT_MEDIA_LOG(CodecName("audio", "aac"));
@@ -3508,7 +3531,7 @@
 #endif
 #endif
 
-TEST_F(ChunkDemuxerTest, WebMIsParsingMediaSegmentDetection) {
+TEST_P(ChunkDemuxerTest, WebMIsParsingMediaSegmentDetection) {
   const uint8_t kBuffer[] = {
       // CLUSTER (size = 10)
       0x1F, 0x43, 0xB6, 0x75, 0x8A,
@@ -3588,7 +3611,7 @@
   }
 }
 
-TEST_F(ChunkDemuxerTest, DurationChange) {
+TEST_P(ChunkDemuxerTest, DurationChange) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   const int kStreamDuration = kDefaultDuration().InMilliseconds();
 
@@ -3624,7 +3647,7 @@
   CheckExpectedRanges("{ [201191,201290) }");
 }
 
-TEST_F(ChunkDemuxerTest, DurationChangeTimestampOffset) {
+TEST_P(ChunkDemuxerTest, DurationChangeTimestampOffset) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   ASSERT_TRUE(SetTimestampOffset(kSourceId, kDefaultDuration()));
   EXPECT_CALL(host_, SetDuration(
@@ -3633,7 +3656,7 @@
   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 4)));
 }
 
-TEST_F(ChunkDemuxerTest, EndOfStreamTruncateDuration) {
+TEST_P(ChunkDemuxerTest, EndOfStreamTruncateDuration) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
@@ -3643,13 +3666,12 @@
   MarkEndOfStream(PIPELINE_OK);
 }
 
-
-TEST_F(ChunkDemuxerTest, ZeroLengthAppend) {
+TEST_P(ChunkDemuxerTest, ZeroLengthAppend) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   ASSERT_TRUE(AppendData(NULL, 0));
 }
 
-TEST_F(ChunkDemuxerTest, AppendAfterEndOfStream) {
+TEST_P(ChunkDemuxerTest, AppendAfterEndOfStream) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   EXPECT_CALL(host_, SetDuration(_))
@@ -3667,7 +3689,7 @@
 // Test receiving a Shutdown() call before we get an Initialize()
 // call. This can happen if video element gets destroyed before
 // the pipeline has a chance to initialize the demuxer.
-TEST_F(ChunkDemuxerTest, Shutdown_BeforeInitialize) {
+TEST_P(ChunkDemuxerTest, Shutdown_BeforeInitialize) {
   demuxer_->Shutdown();
   demuxer_->Initialize(
       &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
@@ -3676,7 +3698,7 @@
 
 // Verifies that signaling end of stream while stalled at a gap
 // boundary does not trigger end of stream buffers to be returned.
-TEST_F(ChunkDemuxerTest, EndOfStreamWhileWaitingForGapToBeFilled) {
+TEST_P(ChunkDemuxerTest, EndOfStreamWhileWaitingForGapToBeFilled) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(0, 10));
@@ -3739,7 +3761,7 @@
   EXPECT_TRUE(video_read_done);
 }
 
-TEST_F(ChunkDemuxerTest, CanceledSeekDuringInitialPreroll) {
+TEST_P(ChunkDemuxerTest, CanceledSeekDuringInitialPreroll) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   // Cancel preroll.
@@ -3753,7 +3775,7 @@
   ASSERT_TRUE(AppendCluster(seek_time.InMilliseconds(), 10));
 }
 
-TEST_F(ChunkDemuxerTest, SetMemoryLimitType) {
+TEST_P(ChunkDemuxerTest, SetMemoryLimitType) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   // Set different memory limits for audio and video.
@@ -3793,7 +3815,7 @@
   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [1000,1165) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekForward) {
+TEST_P(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekForward) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
   // Append some data at position 1000ms
@@ -3811,7 +3833,7 @@
   CheckExpectedRanges("{ [1115,1230) [2000,2115) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekBack) {
+TEST_P(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekBack) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
   // Append some data at position 1000ms
@@ -3830,7 +3852,7 @@
   CheckExpectedRanges("{ [0,115) [1115,1230) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekForward) {
+TEST_P(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekForward) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
   // Append some data at position 1000ms then at 2000ms
@@ -3849,7 +3871,7 @@
   CheckExpectedRanges("{ [2069,2115) [3000,3115) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween1) {
+TEST_P(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween1) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
   // Append some data at position 1000ms then at 2000ms
@@ -3874,7 +3896,7 @@
   CheckExpectedRanges("{ [1500,1615) [2069,2115) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween2) {
+TEST_P(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween2) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
 
@@ -3895,7 +3917,7 @@
   CheckExpectedRanges("{ [1000,1115) [1500,1615) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekBack) {
+TEST_P(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekBack) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
   // Append some data at position 1000ms then at 2000ms
@@ -3914,7 +3936,7 @@
   CheckExpectedRanges("{ [0,115) [2069,2115) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCDuringSeek) {
+TEST_P(ChunkDemuxerTest, GCDuringSeek) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
 
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 5 * kBlockSize);
@@ -3959,7 +3981,7 @@
   CheckExpectedRanges("{ [500,615) [700,815) }");
 }
 
-TEST_F(ChunkDemuxerTest, GCKeepPlayhead) {
+TEST_P(ChunkDemuxerTest, GCKeepPlayhead) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
 
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 5 * kBlockSize);
@@ -3998,7 +4020,7 @@
   CheckExpectedRanges("{ [115,230) }");
 }
 
-TEST_F(ChunkDemuxerTest, AppendWindow_Video) {
+TEST_P(ChunkDemuxerTest, AppendWindow_Video) {
   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
 
@@ -4028,7 +4050,7 @@
   CheckExpectedRanges("{ [120,270) [420,630) }");
 }
 
-TEST_F(ChunkDemuxerTest, AppendWindow_Audio) {
+TEST_P(ChunkDemuxerTest, AppendWindow_Audio) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   DemuxerStream* stream = GetStream(DemuxerStream::AUDIO);
 
@@ -4065,7 +4087,7 @@
   CheckExpectedRanges("{ [50,280) [360,650) }");
 }
 
-TEST_F(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) {
+TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
 
   // Set the append window to [10,20).
@@ -4081,7 +4103,7 @@
   CheckExpectedRanges("{ [10,20) }");
 }
 
-TEST_F(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) {
+TEST_P(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_,
@@ -4107,7 +4129,7 @@
   CheckExpectedBuffers(stream, "50KP 50K 62K 86K 109K 122K 125K 128K");
 }
 
-TEST_F(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) {
+TEST_P(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) {
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(
       &host_,
@@ -4150,7 +4172,7 @@
   CheckExpectedBuffers(stream, "2746K 2767K 2789K 2810K");
 }
 
-TEST_F(ChunkDemuxerTest, AppendWindow_Text) {
+TEST_P(ChunkDemuxerTest, AppendWindow_Text) {
   DemuxerStream* text_stream = NULL;
   EXPECT_CALL(host_, AddTextStream(_, _))
       .WillOnce(SaveArg<0>(&text_stream));
@@ -4191,7 +4213,7 @@
   CheckExpectedBuffers(text_stream, "400K 500K");
 }
 
-TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) {
+TEST_P(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   EXPECT_MEDIA_LOG(StreamParsingFailed());
   EXPECT_CALL(host_, OnDemuxerError(CHUNK_DEMUXER_ERROR_APPEND_FAILED));
@@ -4200,7 +4222,7 @@
   demuxer_->StartWaitingForSeek(seek_time);
 }
 
-TEST_F(ChunkDemuxerTest, Remove_AudioVideoText) {
+TEST_P(ChunkDemuxerTest, Remove_AudioVideoText) {
   DemuxerStream* text_stream = NULL;
   EXPECT_CALL(host_, AddTextStream(_, _))
       .WillOnce(SaveArg<0>(&text_stream));
@@ -4238,7 +4260,7 @@
   CheckExpectedBuffers(text_stream, "1K 101K 201K");
 }
 
-TEST_F(ChunkDemuxerTest, Remove_StartAtDuration) {
+TEST_P(ChunkDemuxerTest, Remove_StartAtDuration) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
 
@@ -4268,7 +4290,7 @@
 // Verifies that a Seek() will complete without text cues for
 // the seek point and will return cues after the seek position
 // when they are eventually appended.
-TEST_F(ChunkDemuxerTest, SeekCompletesWithoutTextCues) {
+TEST_P(ChunkDemuxerTest, SeekCompletesWithoutTextCues) {
   DemuxerStream* text_stream = NULL;
   EXPECT_CALL(host_, AddTextStream(_, _))
       .WillOnce(SaveArg<0>(&text_stream));
@@ -4325,7 +4347,7 @@
   CheckExpectedBuffers(video_stream, "180 210");
 }
 
-TEST_F(ChunkDemuxerTest, ClusterWithUnknownSize) {
+TEST_P(ChunkDemuxerTest, ClusterWithUnknownSize) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 0, 4, true)));
@@ -4336,7 +4358,7 @@
   CheckExpectedRanges("{ [0,115) }");
 }
 
-TEST_F(ChunkDemuxerTest, CuesBetweenClustersWithUnknownSize) {
+TEST_P(ChunkDemuxerTest, CuesBetweenClustersWithUnknownSize) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   // Add two clusters separated by Cues in a single Append() call.
@@ -4350,7 +4372,7 @@
   CheckExpectedRanges("{ [0,115) }");
 }
 
-TEST_F(ChunkDemuxerTest, CuesBetweenClusters) {
+TEST_P(ChunkDemuxerTest, CuesBetweenClusters) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 0, 4)));
@@ -4359,7 +4381,7 @@
   CheckExpectedRanges("{ [0,115) }");
 }
 
-TEST_F(ChunkDemuxerTest, EvictCodedFramesTest) {
+TEST_P(ChunkDemuxerTest, EvictCodedFramesTest) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
   demuxer_->SetMemoryLimitsForTest(DemuxerStream::VIDEO, 15 * kBlockSize);
@@ -4409,38 +4431,38 @@
   CheckExpectedBuffers(video_stream, "60K 70 80K 90 100K 110 120K 130 140K");
 }
 
-TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioOnly) {
+TEST_P(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioOnly) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
   EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
   ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
 }
 
-TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_VideoOnly) {
+TEST_P(ChunkDemuxerTest, SegmentMissingVideoFrame_VideoOnly) {
   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
   EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
   ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
 }
 
-TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioVideo) {
+TEST_P(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioVideo) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 0, 10);
 }
 
-TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_AudioVideo) {
+TEST_P(ChunkDemuxerTest, SegmentMissingVideoFrame_AudioVideo) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
 }
 
-TEST_F(ChunkDemuxerTest, SegmentMissingAudioVideoFrames) {
+TEST_P(ChunkDemuxerTest, SegmentMissingAudioVideoFrames) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
   EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
   ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
 }
 
-TEST_F(ChunkDemuxerTest, RelaxedKeyframe_FirstSegmentMissingKeyframe) {
+TEST_P(ChunkDemuxerTest, RelaxedKeyframe_FirstSegmentMissingKeyframe) {
   // Append V:[n n n][n n K]
   // Expect V:           [K]
   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
@@ -4453,7 +4475,7 @@
   CheckExpectedBuffers(video_stream, "50K");
 }
 
-TEST_F(ChunkDemuxerTest, RelaxedKeyframe_SecondSegmentMissingKeyframe) {
+TEST_P(ChunkDemuxerTest, RelaxedKeyframe_SecondSegmentMissingKeyframe) {
   // Append V:[K n n][n n n]
   // Expect V:[K n n][n n n]
   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
@@ -4466,7 +4488,7 @@
   CheckExpectedBuffers(video_stream, "0K 10 20 30 40 50");
 }
 
-TEST_F(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_1) {
+TEST_P(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_1) {
   // Append V:[K n n]
   // Remove    *****
   // Append V:       [n n n][n K n]
@@ -4484,7 +4506,7 @@
   CheckExpectedBuffers(video_stream, "70K 80");
 }
 
-TEST_F(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_2) {
+TEST_P(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_2) {
   // Append V:[K n n][n n n][n K n]
   // Remove    *
   // Expect:                  [K n]
@@ -4501,7 +4523,7 @@
   CheckExpectedBuffers(video_stream, "70K 80");
 }
 
-TEST_F(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_3) {
+TEST_P(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_3) {
   // Append V:[K n n][n n n][n K n]
   // Remove               *
   // Expect:  [K n n..n n]    [K n]
@@ -4520,7 +4542,7 @@
   CheckExpectedBuffers(video_stream, "70K 80");
 }
 
-TEST_F(ChunkDemuxerTest,
+TEST_P(ChunkDemuxerTest,
        RelaxedKeyframe_RemoveInterruptsMuxedCodedFrameGroup_1) {
   // Append muxed:
   //        A:[K K K]
@@ -4551,7 +4573,7 @@
   CheckExpectedBuffers(video_stream, "70K 80");
 }
 
-TEST_F(ChunkDemuxerTest,
+TEST_P(ChunkDemuxerTest,
        RelaxedKeyframe_RemoveInterruptsMuxedCodedFrameGroup_2) {
   // Append muxed:
   //        A:[K K K]
@@ -4586,7 +4608,7 @@
   CheckExpectedBuffers(video_stream, "70K 80");
 }
 
-TEST_F(ChunkDemuxerTest,
+TEST_P(ChunkDemuxerTest,
        RelaxedKeyframe_RemoveInterruptsMuxedCodedFrameGroup_3) {
   // Append muxed:
   //        A:[K K K
@@ -4674,7 +4696,7 @@
   ASSERT_TRUE(event.IsSignaled());
 }
 
-TEST_F(ChunkDemuxerTest, StreamStatusNotifications) {
+TEST_P(ChunkDemuxerTest, StreamStatusNotifications) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
   ChunkDemuxerStream* audio_stream =
       static_cast<ChunkDemuxerStream*>(GetStream(DemuxerStream::AUDIO));
@@ -4698,7 +4720,7 @@
   EXPECT_TRUE(read_done);
 }
 
-TEST_F(ChunkDemuxerTest, MultipleIds) {
+TEST_P(ChunkDemuxerTest, MultipleIds) {
   CreateNewDemuxer();
   EXPECT_CALL(*this, DemuxerOpened());
   EXPECT_CALL(host_, SetDuration(_)).Times(2);
@@ -4725,7 +4747,7 @@
   CheckExpectedRanges(kId2, "{ [0,10007) }");
 }
 
-TEST_F(ChunkDemuxerTest, CompleteInitAfterIdRemoved) {
+TEST_P(ChunkDemuxerTest, CompleteInitAfterIdRemoved) {
   CreateNewDemuxer();
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(&host_,
@@ -4748,7 +4770,7 @@
   AppendSingleStreamCluster(kId1, kVideoTrackNum, "0K 30 60 90");
 }
 
-TEST_F(ChunkDemuxerTest, RemovingIdMustRemoveStreams) {
+TEST_P(ChunkDemuxerTest, RemovingIdMustRemoveStreams) {
   CreateNewDemuxer();
   EXPECT_CALL(*this, DemuxerOpened());
   demuxer_->Initialize(&host_,
@@ -4774,7 +4796,7 @@
   EXPECT_EQ(nullptr, GetStream(DemuxerStream::VIDEO));
 }
 
-TEST_F(ChunkDemuxerTest, SequenceModeMuxedAppendShouldWarn) {
+TEST_P(ChunkDemuxerTest, SequenceModeMuxedAppendShouldWarn) {
   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
 
   demuxer_->SetSequenceMode(kSourceId, true);
@@ -4786,7 +4808,7 @@
                      MuxedStreamInfo(kVideoTrackNum, "0D10K"));
 }
 
-TEST_F(ChunkDemuxerTest, SequenceModeSingleTrackNoWarning) {
+TEST_P(ChunkDemuxerTest, SequenceModeSingleTrackNoWarning) {
   std::string audio_id = "audio1";
   std::string video_id = "video1";
 
@@ -4807,7 +4829,7 @@
       video_id, GenerateSingleStreamCluster(0, 33, kVideoTrackNum, 33)));
 }
 
-TEST_F(ChunkDemuxerTest, Mp4Vp9CodecSupport) {
+TEST_P(ChunkDemuxerTest, Mp4Vp9CodecSupport) {
   ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
   expected = ChunkDemuxer::kOk;
@@ -4820,4 +4842,13 @@
 // same codec type in a single SourceBufferState, when WebM parser supports
 // multiple tracks. crbug.com/646900
 
+// Though most of these ChunkDemuxerTests use WebM (where PTS==DTS), we still
+// need to ensure that both versions of the buffering API work.
+INSTANTIATE_TEST_CASE_P(LegacyByDts,
+                        ChunkDemuxerTest,
+                        Values(BufferingApi::kLegacyByDts));
+INSTANTIATE_TEST_CASE_P(NewByPts,
+                        ChunkDemuxerTest,
+                        Values(BufferingApi::kNewByPts));
+
 }  // namespace media
diff --git a/media/filters/frame_processor_unittest.cc b/media/filters/frame_processor_unittest.cc
index 1b107d3c..392f182 100644
--- a/media/filters/frame_processor_unittest.cc
+++ b/media/filters/frame_processor_unittest.cc
@@ -11,13 +11,16 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
 #include "media/base/media_log.h"
+#include "media/base/media_switches.h"
 #include "media/base/media_util.h"
 #include "media/base/mock_filters.h"
 #include "media/base/mock_media_log.h"
@@ -31,6 +34,26 @@
 using ::testing::StrictMock;
 using ::testing::Values;
 
+namespace {
+
+enum class BufferingApi { kLegacyByDts, kNewByPts };
+
+struct FrameProcessorTestParams {
+ public:
+  FrameProcessorTestParams(const bool use_sequence_mode,
+                           const BufferingApi buffering_api)
+      : use_sequence_mode(use_sequence_mode), buffering_api(buffering_api) {}
+
+  // Test will use 'sequence' append mode if true, or 'segments' if false.
+  const bool use_sequence_mode;
+
+  // Determines if media::kMseBufferByPts feature should be forced on or off for
+  // the test.
+  const BufferingApi buffering_api;
+};
+
+}  // namespace
+
 namespace media {
 
 typedef StreamParser::BufferQueue BufferQueue;
@@ -58,20 +81,32 @@
   DISALLOW_COPY_AND_ASSIGN(FrameProcessorTestCallbackHelper);
 };
 
-// Test parameter determines indicates if the TEST_P instance is targeted for
-// sequence mode (if true), or segments mode (if false).
-class FrameProcessorTest : public testing::TestWithParam<bool> {
+class FrameProcessorTest
+    : public ::testing::TestWithParam<FrameProcessorTestParams> {
  protected:
   FrameProcessorTest()
-      : frame_processor_(new FrameProcessor(
-            base::Bind(
-                &FrameProcessorTestCallbackHelper::OnPossibleDurationIncrease,
-                base::Unretained(&callbacks_)),
-            &media_log_)),
-        append_window_end_(kInfiniteDuration),
+      : append_window_end_(kInfiniteDuration),
         frame_duration_(base::TimeDelta::FromMilliseconds(10)),
         audio_id_(1),
         video_id_(2) {
+    const FrameProcessorTestParams& params = GetParam();
+    use_sequence_mode_ = params.use_sequence_mode;
+    buffering_api_ = params.buffering_api;
+
+    switch (buffering_api_) {
+      case BufferingApi::kLegacyByDts:
+        scoped_feature_list_.InitAndDisableFeature(media::kMseBufferByPts);
+        break;
+      case BufferingApi::kNewByPts:
+        scoped_feature_list_.InitAndEnableFeature(media::kMseBufferByPts);
+        break;
+    }
+
+    frame_processor_ = base::MakeUnique<FrameProcessor>(
+        base::Bind(
+            &FrameProcessorTestCallbackHelper::OnPossibleDurationIncrease,
+            base::Unretained(&callbacks_)),
+        &media_log_);
     frame_processor_->SetParseWarningCallback(
         base::Bind(&FrameProcessorTestCallbackHelper::OnParseWarning,
                    base::Unretained(&callbacks_)));
@@ -272,6 +307,10 @@
   StrictMock<MockMediaLog> media_log_;
   StrictMock<FrameProcessorTestCallbackHelper> callbacks_;
 
+  bool use_sequence_mode_;
+  BufferingApi buffering_api_;
+  base::test::ScopedFeatureList scoped_feature_list_;
+
   std::unique_ptr<FrameProcessor> frame_processor_;
   base::TimeDelta append_window_start_;
   base::TimeDelta append_window_end_;
@@ -334,7 +373,7 @@
   DISALLOW_COPY_AND_ASSIGN(FrameProcessorTest);
 };
 
-TEST_F(FrameProcessorTest, WrongTypeInAppendedBuffer) {
+TEST_P(FrameProcessorTest, WrongTypeInAppendedBuffer) {
   AddTestTracks(HAS_AUDIO);
   EXPECT_FALSE(in_coded_frame_group());
 
@@ -352,7 +391,7 @@
   CheckReadStalls(audio_.get());
 }
 
-TEST_F(FrameProcessorTest, NonMonotonicallyIncreasingTimestampInOneCall) {
+TEST_P(FrameProcessorTest, NonMonotonicallyIncreasingTimestampInOneCall) {
   AddTestTracks(HAS_AUDIO);
 
   StreamParser::BufferQueueMap buffer_queue_map;
@@ -373,7 +412,7 @@
   // Tests A: P(A) -> (a)
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
 
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_));
@@ -388,7 +427,7 @@
   // Tests V: P(V) -> (v)
   InSequence s;
   AddTestTracks(HAS_VIDEO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
 
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_));
@@ -403,7 +442,7 @@
   // Tests A: P(A0, A10) -> (a0, a10)
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
 
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 2));
@@ -418,7 +457,7 @@
   // Tests A: STSO(50)+P(A0) -> TSO==50,(a0@50)
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
 
   const base::TimeDelta fifty_ms = base::TimeDelta::FromMilliseconds(50);
@@ -440,15 +479,14 @@
   //   if segments mode: TSO==50,(a20@70)
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  bool using_sequence_mode = GetParam();
-  if (using_sequence_mode)
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
 
   const base::TimeDelta fifty_ms = base::TimeDelta::FromMilliseconds(50);
   const base::TimeDelta twenty_ms = base::TimeDelta::FromMilliseconds(20);
   SetTimestampOffset(fifty_ms);
 
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(
         fifty_ms + frame_duration_));
   } else {
@@ -461,7 +499,7 @@
 
   // We do not stall on reading without seeking to 50ms / 70ms due to
   // SourceBufferStream::kSeekToStartFudgeRoom().
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     EXPECT_EQ(fifty_ms - twenty_ms, timestamp_offset_);
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [50,60) }");
     CheckReadsThenReadStalls(audio_.get(), "50:20");
@@ -476,7 +514,7 @@
   // Tests A: P(A0,A10)+P(A20,A30) -> (a0,a10,a20,a30)
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
 
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 2));
@@ -501,8 +539,7 @@
   //   if segments mode: TSO==0,(a0,a10,a20,a30)
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  bool using_sequence_mode = GetParam();
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     frame_processor_->SetSequenceMode(true);
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 2));
   } else {
@@ -512,7 +549,7 @@
   ProcessFrames("20K 30K", "");
   EXPECT_TRUE(in_coded_frame_group());
 
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
     EXPECT_EQ(frame_duration_ * -2, timestamp_offset_);
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 4));
@@ -525,7 +562,7 @@
   ProcessFrames("0K 10K", "");
   EXPECT_TRUE(in_coded_frame_group());
 
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,40) }");
     EXPECT_EQ(frame_duration_ * 2, timestamp_offset_);
     CheckReadsThenReadStalls(audio_.get(), "0:20 10:30 20:0 30:10");
@@ -544,7 +581,7 @@
   //   (a0,a10,a20,a30,a40);(v0,v10,v20,v30)
   InSequence s;
   AddTestTracks(HAS_AUDIO | HAS_VIDEO);
-  if (GetParam()) {
+  if (use_sequence_mode_) {
     frame_processor_->SetSequenceMode(true);
     EXPECT_CALL(callbacks_,
                 OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
@@ -577,8 +614,7 @@
   // MergeBufferQueues() behavior.
   InSequence s;
   AddTestTracks(HAS_AUDIO | HAS_VIDEO);
-  bool using_sequence_mode = GetParam();
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     frame_processor_->SetSequenceMode(true);
     EXPECT_CALL(callbacks_,
                 OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
@@ -591,7 +627,7 @@
   ProcessFrames("0K 10K 30K 40K 50K", "0K 10 40 50K");
   EXPECT_TRUE(in_coded_frame_group());
 
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     EXPECT_EQ(frame_duration_, timestamp_offset_);
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,70) }");
     CheckExpectedRangesByTimestamp(video_.get(), "{ [0,70) }");
@@ -616,9 +652,8 @@
   // to handle overlap-appends, too.
   InSequence s;
   AddTestTracks(HAS_AUDIO | HAS_VIDEO);
-  bool using_sequence_mode = GetParam();
-  frame_processor_->SetSequenceMode(using_sequence_mode);
-  if (using_sequence_mode) {
+  frame_processor_->SetSequenceMode(use_sequence_mode_);
+  if (use_sequence_mode_) {
     EXPECT_CALL(callbacks_,
                 OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
     EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
@@ -642,7 +677,7 @@
   ProcessFrames("0K 10K 20K", "10K 20K 30K");
   EXPECT_EQ(frame_duration_ * 20, timestamp_offset_);
   EXPECT_TRUE(in_coded_frame_group());
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,230) }");
     CheckExpectedRangesByTimestamp(video_.get(), "{ [100,240) }");
   } else {
@@ -663,7 +698,7 @@
   // The new audio range is not within SourceBufferStream's coalescing threshold
   // relative to the next range, but the new video range is within the
   // threshold.
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     // TODO(wolenetz/chcunningham): The large explicit-timestampOffset-induced
     // jump forward (from timestamp 130 to 200) while in a sequence mode coded
     // frame group makes our adjacency threshold in SourceBuffer, based on
@@ -697,7 +732,7 @@
   // our initial seek to start.
   SeekStream(audio_.get(), fifty_five_ms);
   SeekStream(video_.get(), fifty_five_ms);
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     CheckReadsThenReadStalls(
         audio_.get(),
         "55:0 65:10 75:20 100:0 110:10 120:20 200:0 210:10 220:20");
@@ -730,11 +765,10 @@
   // these append sequences can occur.
   InSequence s;
   AddTestTracks(HAS_AUDIO | HAS_VIDEO);
-  bool using_sequence_mode = GetParam();
-  frame_processor_->SetSequenceMode(using_sequence_mode);
+  frame_processor_->SetSequenceMode(use_sequence_mode_);
 
   // Begin with a simple set of appends for all tracks.
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     // Allow room in the timeline for the last audio append (50K, below) in this
     // test to remain within default append window [0, +Infinity]. Moving the
     // sequence mode appends to begin at time 100ms, the same time as the first
@@ -754,7 +788,7 @@
   CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) }");
 
   // Trigger (normal) discontinuity with one track (video).
-  if (using_sequence_mode)
+  if (use_sequence_mode_)
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 15));
   else
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 17));
@@ -762,7 +796,7 @@
   ProcessFrames("", "160K");
   EXPECT_TRUE(in_coded_frame_group());
 
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     // The new video buffer is relocated into [140,150).
     EXPECT_EQ(frame_duration_ * -2, timestamp_offset_);
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,130) }");
@@ -778,7 +812,7 @@
   // just appended. Append with a timestamp such that segments mode demonstrates
   // we don't retroactively extend the new video buffer appended above's range
   // start back to this audio start time.
-  if (using_sequence_mode)
+  if (use_sequence_mode_)
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 15));
   else
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 17));
@@ -789,7 +823,7 @@
   // Because this is the first audio buffer appended following the discontinuity
   // detected while appending the video frame, above, a new coded frame group
   // for video is not triggered.
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     // The new audio buffer is relocated into [30,40). Note the muxed 'sequence'
     // mode append mode results in a buffered range gap in this case.
     EXPECT_EQ(frame_duration_ * -2, timestamp_offset_);
@@ -803,7 +837,7 @@
 
   // Finally, append a non-keyframe to the first track (video), to continue the
   // GOP that started the normal discontinuity on the previous video append.
-  if (using_sequence_mode)
+  if (use_sequence_mode_)
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 16));
   else
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 18));
@@ -815,7 +849,7 @@
   // earlier than what already satisfied our initial seek to start. We satisfy
   // the seek with the first buffer in [0,1000).
   SeekStream(audio_.get(), base::TimeDelta());
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     // The new video buffer is relocated into [150,160).
     EXPECT_EQ(frame_duration_ * -2, timestamp_offset_);
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [30,40) [100,130) }");
@@ -843,7 +877,7 @@
        AppendWindowFilterOfNegativeBufferTimestampsWithPrerollDiscard) {
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
 
   SetTimestampOffset(frame_duration_ * -2);
@@ -858,7 +892,7 @@
 TEST_P(FrameProcessorTest, AppendWindowFilterWithInexactPreroll) {
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
   SetTimestampOffset(-frame_duration_);
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 2));
@@ -870,7 +904,7 @@
 TEST_P(FrameProcessorTest, AppendWindowFilterWithInexactPreroll_2) {
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
   SetTimestampOffset(-frame_duration_);
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 2));
@@ -882,8 +916,7 @@
 TEST_P(FrameProcessorTest, AllowNegativeFramePTSAndDTSBeforeOffsetAdjustment) {
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  bool using_sequence_mode = GetParam();
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     frame_processor_->SetSequenceMode(true);
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 3));
   } else {
@@ -893,7 +926,7 @@
 
   ProcessFrames("-5K 5K 15K", "");
 
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     EXPECT_EQ(frame_duration_ / 2, timestamp_offset_);
     CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,30) }");
     CheckReadsThenReadStalls(audio_.get(), "0:-5 10:5 20:15");
@@ -909,7 +942,7 @@
   // trimmed frame.
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  if (GetParam())
+  if (use_sequence_mode_)
     frame_processor_->SetSequenceMode(true);
   EXPECT_CALL(callbacks_,
               PossibleDurationIncrease(base::TimeDelta::FromMilliseconds(29)));
@@ -928,10 +961,9 @@
   // frame that originally had DTS > PTS.
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  bool using_sequence_mode = GetParam();
 
   EXPECT_MEDIA_LOG(ParsedDTSGreaterThanPTS()).Times(2);
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     frame_processor_->SetSequenceMode(true);
     EXPECT_CALL(callbacks_, PossibleDurationIncrease(
                                 base::TimeDelta::FromMilliseconds(20)));
@@ -942,7 +974,7 @@
 
   ProcessFrames("-7|10K 3|20K", "");
 
-  if (using_sequence_mode) {
+  if (use_sequence_mode_) {
     EXPECT_EQ(base::TimeDelta::FromMilliseconds(7), timestamp_offset_);
 
     // TODO(wolenetz): Adjust the following expectation to use PTS instead of
@@ -966,11 +998,10 @@
   // partial front trim, to prevent incorrect introduction of a discontinuity
   // and potentially a non-keyframe video frame to be processed next after the
   // discontinuity.
-  bool using_sequence_mode = GetParam();
   InSequence s;
   AddTestTracks(HAS_AUDIO | HAS_VIDEO);
-  frame_processor_->SetSequenceMode(using_sequence_mode);
-  if (using_sequence_mode) {
+  frame_processor_->SetSequenceMode(use_sequence_mode_);
+  if (use_sequence_mode_) {
     EXPECT_CALL(callbacks_,
                 OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
     EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
@@ -990,7 +1021,12 @@
   CheckReadsThenReadStalls(video_.get(), "0 10");
 }
 
-TEST_F(FrameProcessorTest, AudioOnly_SequenceModeContinuityAcrossReset) {
+TEST_P(FrameProcessorTest, AudioOnly_SequenceModeContinuityAcrossReset) {
+  if (!use_sequence_mode_) {
+    DVLOG(1) << "Skipping segments mode variant; inapplicable to this case.";
+    return;
+  }
+
   InSequence s;
   AddTestTracks(HAS_AUDIO);
   frame_processor_->SetSequenceMode(true);
@@ -1009,8 +1045,7 @@
 TEST_P(FrameProcessorTest, PartialAppendWindowZeroDurationPreroll) {
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  bool is_sequence_mode = GetParam();
-  frame_processor_->SetSequenceMode(is_sequence_mode);
+  frame_processor_->SetSequenceMode(use_sequence_mode_);
 
   append_window_start_ = base::TimeDelta::FromMilliseconds(5);
 
@@ -1032,7 +1067,7 @@
 
   // Append a frame with 10ms duration, with 9ms falling after the window start.
   base::TimeDelta expected_duration =
-      base::TimeDelta::FromMilliseconds(is_sequence_mode ? 10 : 14);
+      base::TimeDelta::FromMilliseconds(use_sequence_mode_ ? 10 : 14);
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(expected_duration));
   frame_duration_ = base::TimeDelta::FromMilliseconds(10);
   ProcessFrames("4K", "");
@@ -1040,7 +1075,7 @@
 
   // Verify range updated to reflect last append was processed and trimmed, and
   // also that zero duration buffer was saved and attached as preroll.
-  if (is_sequence_mode) {
+  if (use_sequence_mode_) {
     // For sequence mode, append window trimming is applied after the append
     // is adjusted for timestampOffset. Basically, everything gets rebased to 0
     // and trimming then removes 5 seconds from the front.
@@ -1060,12 +1095,11 @@
 
 TEST_P(FrameProcessorTest,
        OOOKeyframePrecededByDependantNonKeyframeShouldWarn) {
-  bool is_sequence_mode = GetParam();
   InSequence s;
   AddTestTracks(HAS_VIDEO);
-  frame_processor_->SetSequenceMode(is_sequence_mode);
+  frame_processor_->SetSequenceMode(use_sequence_mode_);
 
-  if (is_sequence_mode) {
+  if (use_sequence_mode_) {
     // Allow room in the timeline for the last video append (40|70, below) in
     // this test to remain within default append window [0, +Infinity]. Moving
     // the sequence mode appends to begin at time 50ms, the same time as the
@@ -1107,16 +1141,15 @@
   // to a keyframe, so no longer depends on the original preceding keyframe).
   // The sequence mode test version uses SetTimestampOffset to make it behave
   // like segments mode to simplify the tests.
-  bool is_sequence_mode = GetParam();
   InSequence s;
   AddTestTracks(HAS_AUDIO);
-  frame_processor_->SetSequenceMode(is_sequence_mode);
+  frame_processor_->SetSequenceMode(use_sequence_mode_);
 
   EXPECT_MEDIA_LOG(AudioNonKeyframe(10000, 10000));
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_ * 3));
   ProcessFrames("0K 10 20K", "");
 
-  if (is_sequence_mode)
+  if (use_sequence_mode_)
     SetTimestampOffset(base::TimeDelta());
 
   EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_));
@@ -1127,7 +1160,21 @@
   CheckReadsThenReadStalls(audio_.get(), "0 10 20");
 }
 
-INSTANTIATE_TEST_CASE_P(SequenceMode, FrameProcessorTest, Values(true));
-INSTANTIATE_TEST_CASE_P(SegmentsMode, FrameProcessorTest, Values(false));
+INSTANTIATE_TEST_CASE_P(
+    SequenceModeLegacyByDts,
+    FrameProcessorTest,
+    Values(FrameProcessorTestParams(true, BufferingApi::kLegacyByDts)));
+INSTANTIATE_TEST_CASE_P(
+    SegmentsModeLegacyByDts,
+    FrameProcessorTest,
+    Values(FrameProcessorTestParams(false, BufferingApi::kLegacyByDts)));
+INSTANTIATE_TEST_CASE_P(
+    SequenceModeNewByPts,
+    FrameProcessorTest,
+    Values(FrameProcessorTestParams(true, BufferingApi::kNewByPts)));
+INSTANTIATE_TEST_CASE_P(
+    SegmentsModeNewByPts,
+    FrameProcessorTest,
+    Values(FrameProcessorTestParams(false, BufferingApi::kNewByPts)));
 
 }  // namespace media
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc
index 25853b4..53c283b 100644
--- a/media/gpu/dxva_video_decode_accelerator_win.cc
+++ b/media/gpu/dxva_video_decode_accelerator_win.cc
@@ -47,7 +47,9 @@
 #include "media/base/media_switches.h"
 #include "media/base/win/mf_helpers.h"
 #include "media/base/win/mf_initializer.h"
+#include "media/filters/vp9_parser.h"
 #include "media/gpu/dxva_picture_buffer_win.h"
+#include "media/video/h264_parser.h"
 #include "media/video/video_decode_accelerator.h"
 #include "third_party/angle/include/EGL/egl.h"
 #include "third_party/angle/include/EGL/eglext.h"
@@ -302,10 +304,43 @@
   return hr;
 }
 
+ConfigChangeDetector::~ConfigChangeDetector() {}
+
+// Provides functionality to detect H.264 stream configuration changes.
+// TODO(ananta)
+// Move this to a common place so that all VDA's can use this.
+class H264ConfigChangeDetector : public ConfigChangeDetector {
+ public:
+  H264ConfigChangeDetector();
+  ~H264ConfigChangeDetector() override;
+
+  // Detects stream configuration changes.
+  // Returns false on failure.
+  bool DetectConfig(const uint8_t* stream, unsigned int size) override;
+  VideoColorSpace current_color_space(
+      const VideoColorSpace& container_color_space) const override;
+
+ private:
+  // These fields are used to track the SPS/PPS in the H.264 bitstream and
+  // are eventually compared against the SPS/PPS in the bitstream to detect
+  // a change.
+  int last_sps_id_;
+  std::vector<uint8_t> last_sps_;
+  int last_pps_id_;
+  std::vector<uint8_t> last_pps_;
+  // We want to indicate configuration changes only after we see IDR slices.
+  // This flag tracks that we potentially have a configuration change which
+  // we want to honor after we see an IDR slice.
+  bool pending_config_changed_;
+
+  std::unique_ptr<H264Parser> parser_;
+
+  DISALLOW_COPY_AND_ASSIGN(H264ConfigChangeDetector);
+};
+
 H264ConfigChangeDetector::H264ConfigChangeDetector()
     : last_sps_id_(0),
       last_pps_id_(0),
-      config_changed_(false),
       pending_config_changed_(false) {}
 
 H264ConfigChangeDetector::~H264ConfigChangeDetector() {}
@@ -409,16 +444,85 @@
   return true;
 }
 
-VideoColorSpace H264ConfigChangeDetector::current_color_space() const {
+VideoColorSpace H264ConfigChangeDetector::current_color_space(
+    const VideoColorSpace& container_color_space) const {
   if (!parser_)
-    return VideoColorSpace();
+    return container_color_space;
   // TODO(hubbe): Is using last_sps_id_ correct here?
   const H264SPS* sps = parser_->GetSPS(last_sps_id_);
-  if (sps)
+  if (sps && sps->GetColorSpace().IsSpecified()) {
     return sps->GetColorSpace();
-  return VideoColorSpace();
+  }
+  return container_color_space;
 }
 
+// Doesn't actually detect config changes, only color spaces.
+class VP9ConfigChangeDetector : public ConfigChangeDetector {
+ public:
+  VP9ConfigChangeDetector() : ConfigChangeDetector(), parser_(false) {}
+  ~VP9ConfigChangeDetector() override {}
+
+  // Detects stream configuration changes.
+  // Returns false on failure.
+  bool DetectConfig(const uint8_t* stream, unsigned int size) override {
+    parser_.SetStream(stream, size);
+    Vp9FrameHeader fhdr;
+    while (parser_.ParseNextFrame(&fhdr) == Vp9Parser::kOk) {
+      // TODO(hubbe): move the conversion from Vp9FrameHeader to VideoColorSpace
+      // into a common, reusable location.
+      color_space_.range = fhdr.color_range ? gfx::ColorSpace::RangeID::FULL
+                                            : gfx::ColorSpace::RangeID::INVALID;
+      color_space_.primaries = VideoColorSpace::PrimaryID::INVALID;
+      color_space_.transfer = VideoColorSpace::TransferID::INVALID;
+      color_space_.matrix = VideoColorSpace::MatrixID::INVALID;
+      switch (fhdr.color_space) {
+        case Vp9ColorSpace::RESERVED:
+        case Vp9ColorSpace::UNKNOWN:
+          break;
+        case Vp9ColorSpace::BT_601:
+        case Vp9ColorSpace::SMPTE_170:
+          color_space_.primaries = VideoColorSpace::PrimaryID::SMPTE170M;
+          color_space_.transfer = VideoColorSpace::TransferID::SMPTE170M;
+          color_space_.matrix = VideoColorSpace::MatrixID::SMPTE170M;
+          break;
+        case Vp9ColorSpace::BT_709:
+          color_space_.primaries = VideoColorSpace::PrimaryID::BT709;
+          color_space_.transfer = VideoColorSpace::TransferID::BT709;
+          color_space_.matrix = VideoColorSpace::MatrixID::BT709;
+          break;
+        case Vp9ColorSpace::SMPTE_240:
+          color_space_.primaries = VideoColorSpace::PrimaryID::SMPTE240M;
+          color_space_.transfer = VideoColorSpace::TransferID::SMPTE240M;
+          color_space_.matrix = VideoColorSpace::MatrixID::SMPTE240M;
+          break;
+        case Vp9ColorSpace::BT_2020:
+          color_space_.primaries = VideoColorSpace::PrimaryID::BT2020;
+          color_space_.transfer = VideoColorSpace::TransferID::BT2020_10;
+          color_space_.matrix = VideoColorSpace::MatrixID::BT2020_NCL;
+          break;
+        case Vp9ColorSpace::SRGB:
+          color_space_.primaries = VideoColorSpace::PrimaryID::BT709;
+          color_space_.transfer = VideoColorSpace::TransferID::IEC61966_2_1;
+          color_space_.matrix = VideoColorSpace::MatrixID::BT709;
+          break;
+      }
+    }
+    return true;
+  }
+  VideoColorSpace current_color_space(
+      const VideoColorSpace& container_color_space) const override {
+    // For VP9, container color spaces override video stream color spaces.
+    if (container_color_space.IsSpecified()) {
+      return container_color_space;
+    }
+    return color_space_;
+  }
+
+ private:
+  VideoColorSpace color_space_;
+  Vp9Parser parser_;
+};
+
 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo(
     int32_t buffer_id,
     base::win::ScopedComPtr<IMFSample> sample,
@@ -603,7 +707,10 @@
       "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed",
       PLATFORM_FAILURE, false);
 
-  config_change_detector_.reset(new H264ConfigChangeDetector);
+  if (codec_ == kCodecH264)
+    config_change_detector_.reset(new H264ConfigChangeDetector);
+  if (codec_ == kCodecVP9)
+    config_change_detector_.reset(new VP9ConfigChangeDetector);
 
   SetState(kNormal);
 
@@ -2179,9 +2286,9 @@
   // Attempt to retrieve an output frame from the decoder. If we have one,
   // return and proceed when the output frame is processed. If we don't have a
   // frame then we are done.
-  VideoColorSpace color_space = config_change_detector_->current_color_space();
-  if (color_space == VideoColorSpace())
-    color_space = config_.container_color_space;
+  VideoColorSpace color_space = config_.container_color_space;
+  if (config_change_detector_)
+    color_space = config_change_detector_->current_color_space(color_space);
   DoDecode(color_space.ToGfxColorSpace());
   if (OutputSamplesPresent())
     return;
@@ -2231,9 +2338,9 @@
     return;
   }
 
-  VideoColorSpace color_space = config_change_detector_->current_color_space();
-  if (color_space == VideoColorSpace())
-    color_space = config_.container_color_space;
+  VideoColorSpace color_space = config_.container_color_space;
+  if (config_change_detector_)
+    color_space = config_change_detector_->current_color_space(color_space);
 
   if (!inputs_before_decode_) {
     TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding",
@@ -2960,8 +3067,10 @@
 
 HRESULT DXVAVideoDecodeAccelerator::CheckConfigChanged(IMFSample* sample,
                                                        bool* config_changed) {
-  if (codec_ != kCodecH264)
-    return S_FALSE;
+  if (!config_change_detector_) {
+    *config_changed = false;
+    return S_OK;
+  }
 
   base::win::ScopedComPtr<IMFMediaBuffer> buffer;
   HRESULT hr = sample->GetBufferByIndex(0, buffer.GetAddressOf());
diff --git a/media/gpu/dxva_video_decode_accelerator_win.h b/media/gpu/dxva_video_decode_accelerator_win.h
index a928a8d..ce95dbc 100644
--- a/media/gpu/dxva_video_decode_accelerator_win.h
+++ b/media/gpu/dxva_video_decode_accelerator_win.h
@@ -34,7 +34,6 @@
 #include "media/base/video_color_space.h"
 #include "media/gpu/gpu_video_decode_accelerator_helpers.h"
 #include "media/gpu/media_gpu_export.h"
-#include "media/video/h264_parser.h"
 #include "media/video/video_decode_accelerator.h"
 #include "ui/gfx/color_space.h"
 
@@ -60,39 +59,17 @@
 class EGLStreamPictureBuffer;
 class PbufferPictureBuffer;
 
-// Provides functionality to detect H.264 stream configuration changes.
-// TODO(ananta)
-// Move this to a common place so that all VDA's can use this.
-class H264ConfigChangeDetector {
+class ConfigChangeDetector {
  public:
-  H264ConfigChangeDetector();
-  ~H264ConfigChangeDetector();
-
-  // Detects stream configuration changes.
-  // Returns false on failure.
-  bool DetectConfig(const uint8_t* stream, unsigned int size);
+  virtual ~ConfigChangeDetector();
+  virtual bool DetectConfig(const uint8_t* stream, unsigned int size) = 0;
+  virtual VideoColorSpace current_color_space(
+      const VideoColorSpace& container_color_space) const = 0;
   bool config_changed() const { return config_changed_; }
 
-  VideoColorSpace current_color_space() const;
-
- private:
-  // These fields are used to track the SPS/PPS in the H.264 bitstream and
-  // are eventually compared against the SPS/PPS in the bitstream to detect
-  // a change.
-  int last_sps_id_;
-  std::vector<uint8_t> last_sps_;
-  int last_pps_id_;
-  std::vector<uint8_t> last_pps_;
+ protected:
   // Set to true if we detect a stream configuration change.
-  bool config_changed_;
-  // We want to indicate configuration changes only after we see IDR slices.
-  // This flag tracks that we potentially have a configuration change which
-  // we want to honor after we see an IDR slice.
-  bool pending_config_changed_;
-
-  std::unique_ptr<H264Parser> parser_;
-
-  DISALLOW_COPY_AND_ASSIGN(H264ConfigChangeDetector);
+  bool config_changed_ = false;
 };
 
 // Class to provide a DXVA 2.0 based accelerator using the Microsoft Media
@@ -584,7 +561,7 @@
   // when these changes occur then, the decoder works fine. The
   // H264ConfigChangeDetector class provides functionality to check if the
   // stream configuration changed.
-  std::unique_ptr<H264ConfigChangeDetector> config_change_detector_;
+  std::unique_ptr<ConfigChangeDetector> config_change_detector_;
 
   // Contains the initialization parameters for the video.
   Config config_;
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 9113cbf7..7cdd373 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -42,8 +42,8 @@
 # in addition to use_nss_certs, in that case byte certs are used internally but
 # NSS is used for certificate verification.
 # TODO(mattm): crbug.com/671420: Implement and enable this for all platforms.
-use_byte_certs =
-    is_mac || is_android || is_nacl || is_ios || is_win || is_fuchsia
+use_byte_certs = is_mac || is_android || is_nacl || is_ios || is_win ||
+                 is_fuchsia || is_linux
 
 # Android and Fuchsia can't run testserver.py directly, so they use remote
 # test server.
diff --git a/net/cert/x509_certificate_bytes.cc b/net/cert/x509_certificate_bytes.cc
index c23e94f..9f4f7b5 100644
--- a/net/cert/x509_certificate_bytes.cc
+++ b/net/cert/x509_certificate_bytes.cc
@@ -7,6 +7,7 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/pickle.h"
 #include "base/stl_util.h"
+#include "build/build_config.h"
 #include "crypto/openssl_util.h"
 #include "net/base/ip_address.h"
 #include "net/cert/asn1_util.h"
@@ -39,7 +40,31 @@
   exploded.hour = generalized.hours;
   exploded.minute = generalized.minutes;
   exploded.second = generalized.seconds;
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
+  if (base::Time::FromUTCExploded(exploded, result))
+    return true;
+
+  if (sizeof(time_t) == 4) {
+    // Fail on obviously bad dates before trying the 32-bit hacks.
+    if (!exploded.HasValidValues())
+      return false;
+
+    // Hack to handle dates that can't be converted on 32-bit systems.
+    // TODO(mattm): consider consolidating this with
+    // SaturatedTimeFromUTCExploded from cookie_util.cc
+    if (generalized.year >= 2038) {
+      *result = base::Time::Max();
+      return true;
+    }
+    if (generalized.year < 1970) {
+      *result = base::Time::Min();
+      return true;
+    }
+  }
+  return false;
+#else
   return base::Time::FromUTCExploded(exploded, result);
+#endif
 }
 
 // Sets |value| to the Value from a DER Sequence Tag-Length-Value and return
diff --git a/net/disk_cache/disk_cache_test_util.cc b/net/disk_cache/disk_cache_test_util.cc
index 283b254..426aeab 100644
--- a/net/disk_cache/disk_cache_test_util.cc
+++ b/net/disk_cache/disk_cache_test_util.cc
@@ -82,22 +82,23 @@
       last_(0),
       completed_(false),
       callback_reused_error_(false),
-      callbacks_called_(0) {
-}
+      callbacks_called_(0) {}
 
-MessageLoopHelper::~MessageLoopHelper() {
-}
+MessageLoopHelper::~MessageLoopHelper() {}
 
 bool MessageLoopHelper::WaitUntilCacheIoFinished(int num_callbacks) {
   if (num_callbacks == callbacks_called_)
     return true;
 
   ExpectCallbacks(num_callbacks);
-  // Create a recurrent timer of 50 mS.
-  if (!timer_.IsRunning())
-    timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(50), this,
-                 &MessageLoopHelper::TimerExpired);
-  base::RunLoop().Run();
+  // Create a recurrent timer of 50 ms.
+  base::RepeatingTimer timer;
+  timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(50), this,
+              &MessageLoopHelper::TimerExpired);
+  run_loop_ = std::make_unique<base::RunLoop>();
+  run_loop_->Run();
+  run_loop_.reset();
+
   return completed_;
 }
 
@@ -107,7 +108,7 @@
   CHECK_LE(callbacks_called_, num_callbacks_);
   if (callbacks_called_ == num_callbacks_) {
     completed_ = true;
-    base::RunLoop::QuitCurrentWhenIdleDeprecated();
+    run_loop_->Quit();
   } else {
     // Not finished yet. See if we have to abort.
     if (last_ == callbacks_called_)
@@ -115,7 +116,7 @@
     else
       last_ = callbacks_called_;
     if (40 == num_iterations_)
-      base::RunLoop::QuitCurrentWhenIdleDeprecated();
+      run_loop_->Quit();
   }
 }
 
diff --git a/net/disk_cache/disk_cache_test_util.h b/net/disk_cache/disk_cache_test_util.h
index 1dc348b..8be94ab 100644
--- a/net/disk_cache/disk_cache_test_util.h
+++ b/net/disk_cache/disk_cache_test_util.h
@@ -69,7 +69,7 @@
   // Called periodically to test if WaitUntilCacheIoFinished should return.
   void TimerExpired();
 
-  base::RepeatingTimer timer_;
+  std::unique_ptr<base::RunLoop> run_loop_;
   int num_callbacks_;
   int num_iterations_;
   int last_;
diff --git a/net/quic/core/crypto/quic_crypto_client_config.cc b/net/quic/core/crypto/quic_crypto_client_config.cc
index 8317145..21d4d2a 100644
--- a/net/quic/core/crypto/quic_crypto_client_config.cc
+++ b/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -192,7 +192,7 @@
   server_config_.clear();
   scfg_.reset();
   SetProofInvalid();
-  std::queue<QuicConnectionId> empty_queue;
+  QuicQueue<QuicConnectionId> empty_queue;
   using std::swap;
   swap(server_designated_connection_ids_, empty_queue);
 }
@@ -237,7 +237,7 @@
   proof_verify_details_.reset();
   scfg_.reset();
   ++generation_counter_;
-  std::queue<QuicConnectionId> empty_queue;
+  QuicQueue<QuicConnectionId> empty_queue;
   using std::swap;
   swap(server_designated_connection_ids_, empty_queue);
 }
diff --git a/net/quic/core/crypto/quic_crypto_client_config.h b/net/quic/core/crypto/quic_crypto_client_config.h
index 160d1870..ee72afa 100644
--- a/net/quic/core/crypto/quic_crypto_client_config.h
+++ b/net/quic/core/crypto/quic_crypto_client_config.h
@@ -8,7 +8,6 @@
 #include <cstdint>
 #include <map>
 #include <memory>
-#include <queue>
 #include <string>
 #include <vector>
 
@@ -192,8 +191,8 @@
     // TODO(jokulik): Consider using a hash-set as extra book-keeping to ensure
     // that no connection-id is added twice.  Also, consider keeping the server
     // nonces and connection_ids together in one queue.
-    std::queue<QuicConnectionId> server_designated_connection_ids_;
-    std::queue<std::string> server_nonces_;
+    QuicQueue<QuicConnectionId> server_designated_connection_ids_;
+    QuicQueue<std::string> server_nonces_;
 
     DISALLOW_COPY_AND_ASSIGN(CachedState);
   };
diff --git a/net/quic/core/frames/quic_ack_frame.cc b/net/quic/core/frames/quic_ack_frame.cc
index c9c4d2e..df759bc7 100644
--- a/net/quic/core/frames/quic_ack_frame.cc
+++ b/net/quic/core/frames/quic_ack_frame.cc
@@ -32,7 +32,7 @@
 PacketNumberQueue::const_reverse_iterator::~const_reverse_iterator() {}
 
 PacketNumberQueue::const_iterator::const_iterator(
-    typename std::deque<Interval<QuicPacketNumber>>::const_iterator it)
+    typename QuicDeque<Interval<QuicPacketNumber>>::const_iterator it)
     : deque_it_(it), use_deque_it_(true) {}
 
 PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
@@ -41,7 +41,7 @@
     : vector_it_(it), use_deque_it_(false) {}
 
 PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
-    const typename std::deque<
+    const typename QuicDeque<
         Interval<QuicPacketNumber>>::const_reverse_iterator& it)
     : deque_it_(it), use_deque_it_(true) {}
 
diff --git a/net/quic/core/frames/quic_ack_frame.h b/net/quic/core/frames/quic_ack_frame.h
index 54f95a3..6f3c8068 100644
--- a/net/quic/core/frames/quic_ack_frame.h
+++ b/net/quic/core/frames/quic_ack_frame.h
@@ -39,7 +39,7 @@
         typename QuicIntervalSet<QuicPacketNumber>::const_iterator it);
 
     explicit const_iterator(
-        typename std::deque<Interval<QuicPacketNumber>>::const_iterator it);
+        typename QuicDeque<Interval<QuicPacketNumber>>::const_iterator it);
 
     typedef std::input_iterator_tag iterator_category;
     typedef Interval<QuicPacketNumber> value_type;
@@ -101,7 +101,7 @@
 
    private:
     typename QuicIntervalSet<QuicPacketNumber>::const_iterator vector_it_;
-    typename std::deque<Interval<QuicPacketNumber>>::const_iterator deque_it_;
+    typename QuicDeque<Interval<QuicPacketNumber>>::const_iterator deque_it_;
     const bool use_deque_it_;
   };
 
@@ -116,7 +116,7 @@
             QuicPacketNumber>::const_reverse_iterator& it);
 
     explicit const_reverse_iterator(
-        const typename std::deque<
+        const typename QuicDeque<
             Interval<QuicPacketNumber>>::const_reverse_iterator& it);
 
     typedef std::input_iterator_tag iterator_category;
@@ -188,7 +188,7 @@
    private:
     typename QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator
         vector_it_;
-    typename std::deque<Interval<QuicPacketNumber>>::const_reverse_iterator
+    typename QuicDeque<Interval<QuicPacketNumber>>::const_reverse_iterator
         deque_it_;
     const bool use_deque_it_;
   };
@@ -246,7 +246,7 @@
   // TODO(lilika): Remove QuicIntervalSet<QuicPacketNumber>
   // once FLAGS_quic_reloadable_flag_quic_frames_deque2 is removed
   QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
-  std::deque<Interval<QuicPacketNumber>> packet_number_deque_;
+  QuicDeque<Interval<QuicPacketNumber>> packet_number_deque_;
   bool use_deque_;
 };
 
diff --git a/net/quic/core/packet_number_indexed_queue.h b/net/quic/core/packet_number_indexed_queue.h
index 84388c2..ed98134 100644
--- a/net/quic/core/packet_number_indexed_queue.h
+++ b/net/quic/core/packet_number_indexed_queue.h
@@ -5,10 +5,9 @@
 #ifndef NET_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
 #define NET_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
 
-#include <deque>
-
 #include "base/logging.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_containers.h"
 
 namespace net {
 
@@ -101,7 +100,7 @@
     return const_cast<EntryWrapper*>(const_this->GetEntryWrapper(offset));
   }
 
-  std::deque<EntryWrapper> entries_;
+  QuicDeque<EntryWrapper> entries_;
   size_t number_of_present_entries_;
   QuicPacketNumber first_packet_;
 };
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h
index 6b624c05..9de998a 100644
--- a/net/quic/core/quic_connection.h
+++ b/net/quic/core/quic_connection.h
@@ -18,11 +18,9 @@
 
 #include <cstddef>
 #include <cstdint>
-#include <deque>
 #include <list>
 #include <map>
 #include <memory>
-#include <queue>
 #include <string>
 #include <vector>
 
@@ -42,6 +40,7 @@
 #include "net/quic/core/quic_sent_packet_manager.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 #include "net/quic/platform/api/quic_string_piece.h"
@@ -911,7 +910,7 @@
   // established, but which could not be decrypted.  We buffer these on
   // the assumption that they could not be processed because they were
   // sent with the INITIAL encryption and the CHLO message was lost.
-  std::deque<std::unique_ptr<QuicEncryptedPacket>> undecryptable_packets_;
+  QuicDeque<std::unique_ptr<QuicEncryptedPacket>> undecryptable_packets_;
 
   // Maximum number of undecryptable packets the connection will store.
   size_t max_undecryptable_packets_;
diff --git a/net/quic/core/quic_header_list.h b/net/quic/core/quic_header_list.h
index 983cd8e..f25a6eb1 100644
--- a/net/quic/core/quic_header_list.h
+++ b/net/quic/core/quic_header_list.h
@@ -6,12 +6,12 @@
 #define NET_QUIC_CORE_QUIC_HEADER_LIST_H_
 
 #include <algorithm>
-#include <deque>
 #include <functional>
 #include <string>
 #include <utility>
 
 #include "net/quic/platform/api/quic_bug_tracker.h"
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_string_piece.h"
 #include "net/spdy/core/spdy_header_block.h"
@@ -22,7 +22,7 @@
 // A simple class that accumulates header pairs
 class QUIC_EXPORT_PRIVATE QuicHeaderList : public SpdyHeadersHandlerInterface {
  public:
-  typedef std::deque<std::pair<std::string, std::string>> ListType;
+  typedef QuicDeque<std::pair<std::string, std::string>> ListType;
   typedef ListType::const_iterator const_iterator;
 
   QuicHeaderList();
@@ -58,7 +58,7 @@
   std::string DebugString() const;
 
  private:
-  std::deque<std::pair<std::string, std::string>> header_list_;
+  QuicDeque<std::pair<std::string, std::string>> header_list_;
 
   // The limit on the size of the header list (defined by spec as name + value +
   // overhead for each header field). Headers over this limit will not be
diff --git a/net/quic/core/quic_headers_stream.h b/net/quic/core/quic_headers_stream.h
index 1e17b187..3493987 100644
--- a/net/quic/core/quic_headers_stream.h
+++ b/net/quic/core/quic_headers_stream.h
@@ -6,13 +6,13 @@
 #define NET_QUIC_CORE_QUIC_HEADERS_STREAM_H_
 
 #include <cstddef>
-#include <deque>
 #include <memory>
 
 #include "base/macros.h"
 #include "net/quic/core/quic_header_list.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream.h"
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/platform/api/quic_export.h"
 #include "net/spdy/core/spdy_framer.h"
 
@@ -92,7 +92,7 @@
   QuicSpdySession* spdy_session_;
 
   // Headers that have not been fully acked.
-  std::deque<CompressedHeaderInfo> unacked_headers_;
+  QuicDeque<CompressedHeaderInfo> unacked_headers_;
 
   DISALLOW_COPY_AND_ASSIGN(QuicHeadersStream);
 };
diff --git a/net/quic/core/quic_stream_send_buffer.cc b/net/quic/core/quic_stream_send_buffer.cc
index e195bb3..83abb935d 100644
--- a/net/quic/core/quic_stream_send_buffer.cc
+++ b/net/quic/core/quic_stream_send_buffer.cc
@@ -19,6 +19,10 @@
       offset(offset),
       outstanding_data_length(slice.length()) {}
 
+BufferedSlice::BufferedSlice(BufferedSlice&& other) = default;
+
+BufferedSlice& BufferedSlice::operator=(BufferedSlice&& other) = default;
+
 BufferedSlice::~BufferedSlice() {}
 
 QuicStreamSendBuffer::QuicStreamSendBuffer(QuicBufferAllocator* allocator)
diff --git a/net/quic/core/quic_stream_send_buffer.h b/net/quic/core/quic_stream_send_buffer.h
index 79b7c1f..9b33f91 100644
--- a/net/quic/core/quic_stream_send_buffer.h
+++ b/net/quic/core/quic_stream_send_buffer.h
@@ -5,10 +5,9 @@
 #ifndef NET_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
 #define NET_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
 
-#include <deque>
-
 #include "net/quic/core/frames/quic_stream_frame.h"
 #include "net/quic/core/quic_iovector.h"
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/platform/api/quic_mem_slice.h"
 
 namespace net {
@@ -22,14 +21,14 @@
 // BufferedSlice comprises information of a piece of stream data stored in
 // contiguous memory space. Please note, BufferedSlice is constructed when
 // stream data is saved in send buffer and is removed when stream data is fully
-// acked. There is no usage cases that BufferedSlice needs to be either copied
-// or moved.
+// acked. It is move-only.
 struct BufferedSlice {
   BufferedSlice(QuicMemSlice mem_slice, QuicStreamOffset offset);
+  BufferedSlice(BufferedSlice&& other);
+  BufferedSlice& operator=(BufferedSlice&& other);
+
   BufferedSlice(const BufferedSlice& other) = delete;
   BufferedSlice& operator=(const BufferedSlice& other) = delete;
-  BufferedSlice(BufferedSlice&& other) = delete;
-  BufferedSlice& operator=(BufferedSlice&& other) = delete;
   ~BufferedSlice();
 
   // Stream data of this data slice.
@@ -75,7 +74,8 @@
 
  private:
   friend class test::QuicStreamSendBufferPeer;
-  std::deque<BufferedSlice> buffered_slices_;
+
+  QuicDeque<BufferedSlice> buffered_slices_;
 
   // Offset of next inserted byte.
   QuicStreamOffset stream_offset_;
diff --git a/net/quic/core/quic_unacked_packet_map.h b/net/quic/core/quic_unacked_packet_map.h
index 70549b5..5a08eb7 100644
--- a/net/quic/core/quic_unacked_packet_map.h
+++ b/net/quic/core/quic_unacked_packet_map.h
@@ -99,6 +99,8 @@
   // been acked by the peer.  If there are no unacked packets, returns 0.
   QuicPacketNumber GetLeastUnacked() const;
 
+  // This can not be a QuicDeque since pointers into this are
+  // assumed to be stable.
   typedef std::deque<QuicTransmissionInfo> UnackedPacketMap;
 
   typedef UnackedPacketMap::const_iterator const_iterator;
diff --git a/net/quic/platform/api/quic_containers.h b/net/quic/platform/api/quic_containers.h
index d666f42..3aeb37d2 100644
--- a/net/quic/platform/api/quic_containers.h
+++ b/net/quic/platform/api/quic_containers.h
@@ -40,6 +40,20 @@
 template <typename T>
 using QuicIntervalSet = QuicIntervalSetImpl<T>;
 
+// Represents a simple queue which may be backed by a list or
+// a flat circular buffer.
+//
+// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY!
+template <typename T>
+using QuicQueue = QuicQueueImpl<T>;
+
+// Represents a double-ended queue which may be backed by a list or
+// a flat circular buffer.
+//
+// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY!
+template <typename T>
+using QuicDeque = QuicDequeImpl<T>;
+
 }  // namespace net
 
 #endif  // NET_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
diff --git a/net/quic/platform/impl/quic_containers_impl.h b/net/quic/platform/impl/quic_containers_impl.h
index dfa6c7b..dcaf70c6 100644
--- a/net/quic/platform/impl/quic_containers_impl.h
+++ b/net/quic/platform/impl/quic_containers_impl.h
@@ -8,6 +8,8 @@
 #include <unordered_map>
 #include <unordered_set>
 
+#include "base/containers/circular_deque.h"
+#include "base/containers/queue.h"
 #include "base/containers/small_map.h"
 #include "net/base/interval_set.h"
 #include "net/base/linked_hash_map.h"
@@ -47,6 +49,20 @@
 template <typename T>
 using QuicIntervalSetImpl = IntervalSet<T>;
 
+// Represents a simple queue which may be backed by a list or
+// a flat circular buffer.
+//
+// DOES NOT GUARANTEE POINTER STABILITY!
+template <typename T>
+using QuicQueueImpl = base::queue<T>;
+
+// Represents a double-ended queue which may be backed by a list or
+// a flat circular buffer.
+//
+// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY!
+template <typename T>
+using QuicDequeImpl = base::circular_deque<T>;
+
 }  // namespace net
 
 #endif  // NET_QUIC_PLATFORM_IMPL_QUIC_CONTAINERS_IMPL_H_
diff --git a/net/quic/test_tools/simulator/link.cc b/net/quic/test_tools/simulator/link.cc
index 2bc7499..38b157b 100644
--- a/net/quic/test_tools/simulator/link.cc
+++ b/net/quic/test_tools/simulator/link.cc
@@ -32,6 +32,8 @@
                                        QuicTime dequeue_time)
     : packet(std::move(packet)), dequeue_time(dequeue_time) {}
 
+OneWayLink::QueuedPacket::QueuedPacket(QueuedPacket&& other) = default;
+
 OneWayLink::QueuedPacket::~QueuedPacket() {}
 
 void OneWayLink::AcceptPacket(std::unique_ptr<Packet> packet) {
diff --git a/net/quic/test_tools/simulator/link.h b/net/quic/test_tools/simulator/link.h
index 8df241d..1850d8f 100644
--- a/net/quic/test_tools/simulator/link.h
+++ b/net/quic/test_tools/simulator/link.h
@@ -5,7 +5,6 @@
 #ifndef NET_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
 #define NET_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
 
-#include <queue>
 #include <utility>
 
 #include "net/quic/core/crypto/quic_random.h"
@@ -42,6 +41,7 @@
     QuicTime dequeue_time;
 
     QueuedPacket(std::unique_ptr<Packet> packet, QuicTime dequeue_time);
+    QueuedPacket(QueuedPacket&& other);
     ~QueuedPacket();
   };
 
@@ -54,7 +54,7 @@
   QuicTime::Delta GetRandomDelay(QuicTime::Delta transfer_time);
 
   UnconstrainedPortInterface* sink_;
-  std::queue<QueuedPacket> packets_in_transit_;
+  QuicQueue<QueuedPacket> packets_in_transit_;
 
   const QuicBandwidth bandwidth_;
   const QuicTime::Delta propagation_delay_;
diff --git a/net/quic/test_tools/simulator/queue.cc b/net/quic/test_tools/simulator/queue.cc
index a7e8cb9..da922ce 100644
--- a/net/quic/test_tools/simulator/queue.cc
+++ b/net/quic/test_tools/simulator/queue.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "net/quic/test_tools/simulator/queue.h"
+
 #include "net/quic/platform/api/quic_logging.h"
 #include "net/quic/test_tools/simulator/simulator.h"
 
@@ -96,6 +97,9 @@
 Queue::EnqueuedPacket::EnqueuedPacket(std::unique_ptr<Packet> packet,
                                       AggregationBundleNumber bundle)
     : packet(std::move(packet)), bundle(bundle) {}
+
+Queue::EnqueuedPacket::EnqueuedPacket(EnqueuedPacket&& other) = default;
+
 Queue::EnqueuedPacket::~EnqueuedPacket() = default;
 
 void Queue::NextBundle() {
diff --git a/net/quic/test_tools/simulator/queue.h b/net/quic/test_tools/simulator/queue.h
index 532bb22..2eb7a05 100644
--- a/net/quic/test_tools/simulator/queue.h
+++ b/net/quic/test_tools/simulator/queue.h
@@ -62,6 +62,7 @@
   struct EnqueuedPacket {
     EnqueuedPacket(std::unique_ptr<Packet> packet,
                    AggregationBundleNumber bundle);
+    EnqueuedPacket(EnqueuedPacket&& other);
     ~EnqueuedPacket();
 
     std::unique_ptr<Packet> packet;
@@ -106,7 +107,7 @@
   std::unique_ptr<QuicAlarm> aggregation_timeout_alarm_;
 
   ConstrainedPortInterface* tx_port_;
-  std::queue<EnqueuedPacket> queue_;
+  QuicQueue<EnqueuedPacket> queue_;
 
   ListenerInterface* listener_;
 
diff --git a/net/quic/test_tools/simulator/switch.h b/net/quic/test_tools/simulator/switch.h
index f138d87..f2fcb81 100644
--- a/net/quic/test_tools/simulator/switch.h
+++ b/net/quic/test_tools/simulator/switch.h
@@ -5,6 +5,8 @@
 #ifndef NET_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
 #define NET_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
 
+#include <deque>
+
 #include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/test_tools/simulator/queue.h"
 
@@ -77,6 +79,8 @@
   void DispatchPacket(SwitchPortNumber port_number,
                       std::unique_ptr<Packet> packet);
 
+  // This can not be a QuicDeque since pointers into this are
+  // assumed to be stable.
   std::deque<Port> ports_;
   QuicUnorderedMap<std::string, Port*> switching_table_;
 
diff --git a/net/tools/quic/quic_simple_server_session.h b/net/tools/quic/quic_simple_server_session.h
index f9ff7da..917fd8a 100644
--- a/net/tools/quic/quic_simple_server_session.h
+++ b/net/tools/quic/quic_simple_server_session.h
@@ -9,7 +9,6 @@
 
 #include <stdint.h>
 
-#include <deque>
 #include <list>
 #include <memory>
 #include <set>
@@ -22,6 +21,7 @@
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_server_session_base.h"
 #include "net/quic/core/quic_spdy_session.h"
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/tools/quic/quic_http_response_cache.h"
 #include "net/tools/quic/quic_simple_server_stream.h"
 
@@ -144,7 +144,7 @@
   // the queue also increases by 2 from previous one's. The front element's
   // stream_id is always next_outgoing_stream_id_, and the last one is always
   // highest_promised_stream_id_.
-  std::deque<PromisedStreamInfo> promised_streams_;
+  QuicDeque<PromisedStreamInfo> promised_streams_;
 
   QuicHttpResponseCache* response_cache_;  // Not owned.
 
diff --git a/net/tools/quic/quic_simple_server_session_test.cc b/net/tools/quic/quic_simple_server_session_test.cc
index c9e3cf80..be3dba41 100644
--- a/net/tools/quic/quic_simple_server_session_test.cc
+++ b/net/tools/quic/quic_simple_server_session_test.cc
@@ -14,6 +14,7 @@
 #include "net/quic/core/quic_connection.h"
 #include "net/quic/core/quic_crypto_server_stream.h"
 #include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/platform/api/quic_flags.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 #include "net/quic/platform/api/quic_string_piece.h"
@@ -65,7 +66,7 @@
     return s->CreateOutgoingDynamicStream(priority);
   }
 
-  static std::deque<PromisedStreamInfo>* promised_streams(
+  static QuicDeque<PromisedStreamInfo>* promised_streams(
       QuicSimpleServerSession* s) {
     return &(s->promised_streams_);
   }
diff --git a/net/tools/quic/quic_time_wait_list_manager.h b/net/tools/quic/quic_time_wait_list_manager.h
index 495d55c..ff88c6a 100644
--- a/net/tools/quic/quic_time_wait_list_manager.h
+++ b/net/tools/quic/quic_time_wait_list_manager.h
@@ -11,7 +11,6 @@
 
 #include <stddef.h>
 
-#include <deque>
 #include <memory>
 
 #include "base/macros.h"
@@ -185,7 +184,7 @@
 
   // Pending public reset packets that need to be sent out to the client
   // when we are given a chance to write by the dispatcher.
-  std::deque<std::unique_ptr<QueuedPacket>> pending_packets_queue_;
+  QuicDeque<std::unique_ptr<QueuedPacket>> pending_packets_queue_;
 
   // Time period for which connection_ids should remain in time wait state.
   const QuicTime::Delta time_wait_period_;
diff --git a/net/tools/quic/test_tools/server_thread.cc b/net/tools/quic/test_tools/server_thread.cc
index 9afbdac..22f52ce9 100644
--- a/net/tools/quic/test_tools/server_thread.cc
+++ b/net/tools/quic/test_tools/server_thread.cc
@@ -4,6 +4,7 @@
 
 #include "net/tools/quic/test_tools/server_thread.h"
 
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/test_tools/crypto_test_utils.h"
 #include "net/tools/quic/quic_dispatcher.h"
 #include "net/tools/quic/test_tools/quic_server_peer.h"
@@ -113,7 +114,7 @@
 }
 
 void ServerThread::ExecuteScheduledActions() {
-  std::deque<std::function<void()>> actions;
+  QuicDeque<std::function<void()>> actions;
   {
     QuicWriterMutexLock lock(&scheduled_actions_lock_);
     actions.swap(scheduled_actions_);
diff --git a/net/tools/quic/test_tools/server_thread.h b/net/tools/quic/test_tools/server_thread.h
index 287eb18..7ebb5f5 100644
--- a/net/tools/quic/test_tools/server_thread.h
+++ b/net/tools/quic/test_tools/server_thread.h
@@ -11,6 +11,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/simple_thread.h"
 #include "net/quic/core/quic_config.h"
+#include "net/quic/platform/api/quic_containers.h"
 #include "net/quic/platform/api/quic_mutex.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 #include "net/tools/quic/quic_server.h"
@@ -77,7 +78,7 @@
   bool initialized_;
 
   QuicMutex scheduled_actions_lock_;
-  std::deque<std::function<void()>> scheduled_actions_
+  QuicDeque<std::function<void()>> scheduled_actions_
       GUARDED_BY(scheduled_actions_lock_);
 
   DISALLOW_COPY_AND_ASSIGN(ServerThread);
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc
index b8a7286..042c257 100644
--- a/net/url_request/url_request_context.cc
+++ b/net/url_request/url_request_context.cc
@@ -166,6 +166,11 @@
   }
 }
 
+void URLRequestContext::AssertURLRequestPresent(
+    const URLRequest* request) const {
+  CHECK_GE(url_requests_.count(request), 0u);
+}
+
 bool URLRequestContext::OnMemoryDump(
     const base::trace_event::MemoryDumpArgs& args,
     base::trace_event::ProcessMemoryDump* pmd) {
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index 24941cf..b917393 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -237,6 +237,10 @@
   // prior to implicit destruction of subclass-owned state.
   void AssertNoURLRequests() const;
 
+  // CHECKs that the passed URLRequest is present on this context.
+  // Added for http://crbug.com/754704; remove when that bug is resolved.
+  void AssertURLRequestPresent(const URLRequest* request) const;
+
   // Get the underlying |HttpUserAgentSettings| implementation that provides
   // the HTTP Accept-Language and User-Agent header values.
   const HttpUserAgentSettings* http_user_agent_settings() const {
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd
index fabdce33..bc413890 100644
--- a/remoting/resources/remoting_strings.grd
+++ b/remoting/resources/remoting_strings.grd
@@ -676,24 +676,23 @@
           Chrome Remote Desktop
         </message>
         <message name="IDS_APP_STORE_KEYWORDS" desc="App Store keywords (to be used to search for the app) for the Chrome Remote Desktop app for iOS. Separate keywords with newline. [NAME=app_store_keywords]">
-Chrome Remote Desktop
-Remote Desktop
-Remote PC
-Remote Computer
-Remote Access
-Remote Support
+Chrome
+Remote
+Desktop
+Access
+Support
+Computer
+PC
         </message>
         <message name="IDS_APP_STORE_DESCRIPTION" desc="App Store description of the Chrome Remote Desktop app for iOS. [CHAR-LIMIT=4000] [NAME=app_store_description]">
-Securely access your computer from your iOS device. Its fast, simple and free.
+Securely access your computer from your iOS device. It's fast, simple and free.
 
-• On the computer you want to access remotely, find the Chrome Remote Desktop app on the Chrome Web Store  https://chrome.google.com/remotedesktop
+• Download the Chrome Remote Desktop app from the Chrome WebStore on the computer you want to access remotely.
 • Install Chrome Remote Desktop software and follow the instructions to complete setup.
 • On your iOS device, open the app and tap on any of your online computers to connect.
-
-For information about privacy, please see the Google Privacy Policy (http://goo.gl/SyrVzj).
         </message>
         <message name="IDS_APP_STORE_CHANGES" desc="List of what's changed in this release of Chrome Remote Desktop for iOS. [CHAR-LIMIT=500] [NAME=app_store_changes]">
-• Redesigned user interface.
+• New look and feel.
 • Improved performance, responsiveness and reliability.
 • Support for playing audio from Windows or Linux computers.
         </message>
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json
index 752c772..8b4daf4 100644
--- a/testing/buildbot/chromium.perf.fyi.json
+++ b/testing/buildbot/chromium.perf.fyi.json
@@ -1410,38 +1410,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:22b1",
-              "id": "build137-b1",
-              "os": "Windows-10-10586",
-              "pool": "Chrome-perf-fyi"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -4458,38 +4426,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:22b1",
-              "id": "build147-b1",
-              "os": "Windows-10-10586",
-              "pool": "Chrome-perf-fyi"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -5888,38 +5824,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:9874",
-              "id": "build186-b4",
-              "os": "Windows-10-10586",
-              "pool": "Chrome-perf-fyi"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -8894,38 +8798,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:9874",
-              "id": "build211-b4",
-              "os": "Windows-10-10586",
-              "pool": "Chrome-perf-fyi"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index ec1be21f..09a46e2 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -1322,38 +1322,6 @@
       },
       {
         "args": [
-          "loading.mobile",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.mobile.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build48-b1--device1",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 16200,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.android.tough_video_cases",
           "-v",
           "--upload-results",
@@ -5155,38 +5123,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build48-b1--device7",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_mobile",
           "-v",
           "--upload-results",
@@ -6606,38 +6542,6 @@
       },
       {
         "args": [
-          "loading.mobile",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.mobile.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build75-b1--device1",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 16200,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.android.tough_video_cases",
           "-v",
           "--upload-results",
@@ -10439,38 +10343,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build75-b1--device7",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_mobile",
           "-v",
           "--upload-results",
@@ -14426,38 +14298,6 @@
       },
       {
         "args": [
-          "loading.mobile",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.mobile.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build45-b1--device1",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 16200,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.android.tough_video_cases",
           "-v",
           "--upload-results",
@@ -18259,38 +18099,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build45-b1--device7",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_mobile",
           "-v",
           "--upload-results",
@@ -22246,38 +22054,6 @@
       },
       {
         "args": [
-          "loading.mobile",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.mobile.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build49-b1--device1",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 16200,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.android.tough_video_cases",
           "-v",
           "--upload-results",
@@ -26079,38 +25855,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build49-b1--device7",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_mobile",
           "-v",
           "--upload-results",
@@ -27530,38 +27274,6 @@
       },
       {
         "args": [
-          "loading.mobile",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.mobile.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build47-b1--device1",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 16200,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.android.tough_video_cases",
           "-v",
           "--upload-results",
@@ -31363,38 +31075,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "android_devices": "1",
-              "id": "build47-b1--device7",
-              "os": "Android",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_mobile",
           "-v",
           "--upload-results",
@@ -32819,38 +32499,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0534",
-              "id": "build149-m1",
-              "os": "Ubuntu-14.04",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -35950,38 +35598,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0534",
-              "id": "build151-m1",
-              "os": "Ubuntu-14.04",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -37504,38 +37120,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0166",
-              "id": "build103-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -40593,38 +40177,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0166",
-              "id": "build102-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -42147,38 +41699,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -45236,38 +44756,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -46790,38 +46278,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -49879,38 +49335,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -51433,38 +50857,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a26",
-              "id": "build25-b1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -54501,38 +53893,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a26",
-              "id": "build24-b1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -56055,38 +55415,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build129-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -59144,38 +58472,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build128-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -60698,38 +59994,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0d26",
-              "id": "build5-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -63787,38 +63051,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0d26",
-              "id": "build4-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -65217,38 +64449,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1616",
-              "id": "build118-b1",
-              "os": "Windows-10-10240",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -68223,38 +67423,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1616",
-              "id": "build117-b1",
-              "os": "Windows-10-10240",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -69653,38 +68821,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0534",
-              "id": "build133-m1",
-              "os": "Windows-10-10240",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -72680,38 +71816,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0534",
-              "id": "build132-m1",
-              "os": "Windows-10-10240",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -74152,38 +73256,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6613",
-              "id": "build102-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -77200,38 +76272,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6613",
-              "id": "build101-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -78672,38 +77712,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:041a",
-              "id": "build165-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -81699,38 +80707,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:041a",
-              "id": "build164-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -83171,38 +82147,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "id": "build93-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -86198,38 +85142,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "id": "build92-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -87649,38 +86561,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0532",
-              "id": "build186-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -90676,38 +89556,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0532",
-              "id": "build185-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -92127,38 +90975,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0532",
-              "id": "build139-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -95154,38 +93970,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0532",
-              "id": "build138-m1",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
@@ -96605,38 +95389,6 @@
       },
       {
         "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0532",
-              "id": "build144-m1",
-              "os": "Windows-2012ServerR2-SP0",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "media.media_cns_cases",
           "-v",
           "--upload-results",
@@ -99653,38 +98405,6 @@
       },
       {
         "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=chartjson",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "102b:0532",
-              "id": "build143-m1",
-              "os": "Windows-2012ServerR2-SP0",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 600,
-          "upload_test_results": false
-        }
-      },
-      {
-        "args": [
           "v8.runtimestats.browsing_desktop",
           "-v",
           "--upload-results",
diff --git a/testing/buildbot/filters/fuchsia.net_unittests.filter b/testing/buildbot/filters/fuchsia.net_unittests.filter
index 66c5c41c..d05667e 100644
--- a/testing/buildbot/filters/fuchsia.net_unittests.filter
+++ b/testing/buildbot/filters/fuchsia.net_unittests.filter
@@ -1,17 +1,14 @@
 # TODO(fuchsia): Fix these tests and remove the filter. https://crbug.com/731302 .
--CertVerifyProcInternalTest.*
 -CloseOnConnectHttpServerTest.ServerImmediatelyClosesConnection
 -NetworkInterfacesTest.GetNetworkList
 -ProxyScriptFetcherImplTest.Priority
 -PythonUtils*
--SQLite*
 -UDPSocketTest.PartialRecv
 -UnixDomain*Socket*
 -URLRequest*FTP*
 -URLRequestQuic*
 
 # Following tests pass locally, but flake on bots.
--DiskCacheEntryTest*AsyncIO*
 -DiskCacheTest.BlockFiles_Grow
 -DiskCacheBackendTest.SimpleCacheDeleteQuickly
 -URLRequestTestHTTP.GetTest_ManyCookies
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 86d826cf83..2b869f7c 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -274,6 +274,25 @@
             ]
         }
     ],
+    "AutofillUpstreamRequestCvcIfMissing": [
+        {
+            "platforms": [
+                "chromeos",
+                "linux",
+                "win"
+            ],
+            "experiments": [
+                {
+                    "name": "EnabledWithGoogleBranding",
+                    "enable_features": [
+                        "AutofillUpstreamRequestCvcIfMissing",
+                        "AutofillUpstreamShowGoogleLogo",
+                        "AutofillUpstreamShowNewUi"
+                    ]
+                }
+            ]
+        }
+    ],
     "AutomaticTabDiscarding": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index c12c830..ec94eab 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -9346,8 +9346,8 @@
 crbug.com/591099 fast/multicol/client-rect-after-spanner.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/client-rect-nested.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/client-rect-trailing-column.html [ Failure ]
-crbug.com/757767 fast/multicol/client-rects-crossing-boundaries-nested.html [ Timeout ]
-crbug.com/591099 fast/multicol/client-rects-crossing-boundaries.html [ Failure Timeout ]
+crbug.com/591099 fast/multicol/client-rects-crossing-boundaries-nested.html [ Failure ]
+crbug.com/591099 fast/multicol/client-rects-crossing-boundaries.html [ Failure ]
 crbug.com/591099 fast/multicol/client-rects-empty-element-boundary.html [ Failure ]
 crbug.com/591099 fast/multicol/client-rects-rtl.html [ Failure ]
 crbug.com/591099 fast/multicol/client-rects-sole-empty-block.html [ Failure ]
@@ -9358,7 +9358,7 @@
 crbug.com/591099 fast/multicol/column-width-zero.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/columns-shorthand-parsing-2.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/columns-shorthand-parsing.html [ Failure ]
-crbug.com/757767 fast/multicol/composited-inner-multicol.html [ Timeout ]
+crbug.com/591099 fast/multicol/composited-inner-multicol.html [ Failure ]
 crbug.com/591099 fast/multicol/composited-layer-multiple-fragments-translated.html [ Failure ]
 crbug.com/591099 fast/multicol/composited-layer-multiple-fragments.html [ Failure ]
 crbug.com/591099 fast/multicol/composited-layer-nested.html [ Failure ]
@@ -9378,7 +9378,7 @@
 crbug.com/591099 fast/multicol/cssom-view.html [ Failure ]
 crbug.com/591099 fast/multicol/doubly-nested-with-increasing-row-heights-crash.html [ Failure Pass ]
 crbug.com/757767 fast/multicol/doubly-nested-with-insane-child-height-crash.html [ Timeout ]
-crbug.com/757767 fast/multicol/doubly-nested-with-top-padding-crossing-row-boundaries.html [ Timeout ]
+crbug.com/591099 fast/multicol/doubly-nested-with-top-padding-crossing-row-boundaries.html [ Failure ]
 crbug.com/591099 fast/multicol/dynamic/abspos-becomes-spanner.html [ Failure ]
 crbug.com/591099 fast/multicol/dynamic/abspos-multicol-with-spanner-becomes-spanner.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/dynamic/add-will-change-transform.html [ Failure ]
@@ -9449,7 +9449,7 @@
 crbug.com/591099 fast/multicol/dynamic/valid-spanner-container-becomes-invalid.html [ Failure ]
 crbug.com/591099 fast/multicol/empty-list-item.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/event-offset-complex-tree.html [ Failure ]
-crbug.com/757767 fast/multicol/event-offset-in-nested.html [ Timeout ]
+crbug.com/591099 fast/multicol/event-offset-in-nested.html [ Failure ]
 crbug.com/591099 fast/multicol/event-offset.html [ Failure ]
 crbug.com/591099 fast/multicol/explicit-columns-auto.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/filter-in-second-column.html [ Failure ]
@@ -9500,11 +9500,9 @@
 crbug.com/591099 fast/multicol/hit-test-float.html [ Failure ]
 crbug.com/591099 fast/multicol/hit-test-gap-between-pages-flipped.html [ Failure ]
 crbug.com/591099 fast/multicol/hit-test-gap-between-pages.html [ Failure ]
-crbug.com/757767 fast/multicol/huge-column-count.html [ Crash Timeout ]
 crbug.com/591099 fast/multicol/image-inside-nested-blocks-with-border.html [ Failure ]
 crbug.com/591099 fast/multicol/image-loaded-before-layout-assert.html [ Failure Pass ]
 crbug.com/757767 fast/multicol/infinite-height-causing-fractional-row-height-crash.html [ Timeout ]
-crbug.com/757767 fast/multicol/infinitely-tall-content-in-outer-crash.html [ Timeout ]
 crbug.com/591099 fast/multicol/inline-block-baseline.html [ Failure ]
 crbug.com/591099 fast/multicol/inline-children-crash.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/inline-getclientrects.html [ Failure ]
@@ -9562,7 +9560,7 @@
 crbug.com/591099 fast/multicol/nested-with-padding.html [ Failure ]
 crbug.com/591099 fast/multicol/nested-with-single-empty-block.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/nested-with-single-tall-line.html [ Failure ]
-crbug.com/757767 fast/multicol/nested-with-tall-block.html [ Timeout ]
+crbug.com/591099 fast/multicol/nested-with-tall-block.html [ Failure ]
 crbug.com/591099 fast/multicol/newmulticol/avoid-column-break-inside.html [ Failure ]
 crbug.com/591099 fast/multicol/newmulticol/balance-images.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/newmulticol/balance-maxheight1.html [ Failure ]
@@ -9641,7 +9639,7 @@
 crbug.com/591099 fast/multicol/span/abspos-containing-block-outside-spanner.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/span/adjacent-spanners-with-margin.html [ Failure ]
 crbug.com/591099 fast/multicol/span/adjacent-spanners.html [ Failure Timeout ]
-crbug.com/757767 fast/multicol/span/after-row-with-uneven-height-nested-multicol.html [ Timeout ]
+crbug.com/591099 fast/multicol/span/after-row-with-uneven-height-nested-multicol.html [ Failure ]
 crbug.com/591099 fast/multicol/span/anonymous-before-child-parent-crash.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/span/anonymous-split-block-crash.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/span/as-inner-multicol-after-composited-layer-crash.html [ Failure Pass ]
@@ -9682,7 +9680,7 @@
 crbug.com/591099 fast/multicol/span/invalid-spanner-in-transform.html [ Failure ]
 crbug.com/591099 fast/multicol/span/margin-on-multicol.html [ Failure ]
 crbug.com/591099 fast/multicol/span/multicol-with-padding.html [ Failure ]
-crbug.com/757767 fast/multicol/span/nested-multicol.html [ Timeout ]
+crbug.com/591099 fast/multicol/span/nested-multicol.html [ Failure ]
 crbug.com/591099 fast/multicol/span/offset-properties-empty-content.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/span/offset-properties.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/span/outer-column-break-after-inner-spanner-2.html [ Failure ]
@@ -9753,7 +9751,7 @@
 crbug.com/757767 fast/multicol/vertical-lr/caret-range-outside-columns-rtl.html [ Failure Timeout ]
 crbug.com/757767 fast/multicol/vertical-lr/caret-range-outside-columns.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/vertical-lr/client-rect-after-spanner.html [ Failure Timeout ]
-crbug.com/757767 fast/multicol/vertical-lr/client-rects-crossing-boundaries-nested.html [ Timeout ]
+crbug.com/591099 fast/multicol/vertical-lr/client-rects-crossing-boundaries-nested.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-lr/column-break-with-balancing.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-lr/column-count-with-rules.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-lr/column-rules.html [ Failure ]
@@ -9768,7 +9766,7 @@
 crbug.com/591099 fast/multicol/vertical-lr/gap-non-negative.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/vertical-lr/image-inside-nested-blocks-with-border.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-lr/nested-columns.html [ Failure ]
-crbug.com/757767 fast/multicol/vertical-lr/offset-top-and-left-at-boundaries-nested.html [ Timeout ]
+crbug.com/591099 fast/multicol/vertical-lr/offset-top-and-left-at-boundaries-nested.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-lr/offset-top-and-left-at-boundaries.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/vertical-lr/offset-top-and-left-nested.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/vertical-lr/rules-with-border-before.html [ Failure ]
@@ -9784,7 +9782,7 @@
 crbug.com/591099 fast/multicol/vertical-rl/caret-range-outside-columns-rtl.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-rl/caret-range-outside-columns.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-rl/client-rect-after-spanner.html [ Failure Timeout ]
-crbug.com/757767 fast/multicol/vertical-rl/client-rects-crossing-boundaries-nested.html [ Timeout ]
+crbug.com/591099 fast/multicol/vertical-rl/client-rects-crossing-boundaries-nested.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-rl/column-break-with-balancing.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-rl/column-count-with-rules.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-rl/column-rules.html [ Failure ]
@@ -9799,7 +9797,7 @@
 crbug.com/591099 fast/multicol/vertical-rl/gap-non-negative.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/vertical-rl/image-inside-nested-blocks-with-border.html [ Failure ]
 crbug.com/757767 fast/multicol/vertical-rl/nested-columns.html [ Crash Failure ]
-crbug.com/757767 fast/multicol/vertical-rl/offset-top-and-left-at-boundaries-nested.html [ Timeout ]
+crbug.com/591099 fast/multicol/vertical-rl/offset-top-and-left-at-boundaries-nested.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-rl/offset-top-and-left-at-boundaries.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/vertical-rl/offset-top-and-left-nested.html [ Failure Timeout ]
 crbug.com/591099 fast/multicol/vertical-rl/rules-with-border-before.html [ Failure ]
@@ -10773,7 +10771,6 @@
 crbug.com/591099 fast/text/shaping/same-script-different-lang.html [ Failure ]
 crbug.com/591099 fast/text/shaping/shaping-width-initialized.html [ Failure Pass ]
 crbug.com/591099 fast/text/soft-hyphen-5.html [ Failure Pass ]
-crbug.com/591099 fast/text/soft-hyphen-overflow.html [ Failure Pass ]
 crbug.com/591099 fast/text/sub-pixel/text-scaling-pixel.html [ Failure Timeout ]
 crbug.com/591099 fast/text/tab-min-size.html [ Failure Pass ]
 crbug.com/591099 fast/text/text-between-two-brs-in-nowrap-overflow.html [ Failure Pass ]
@@ -12353,9 +12350,9 @@
 crbug.com/591099 http/tests/inspector-protocol/network/request-interception-patterns.js [ Timeout ]
 crbug.com/591099 http/tests/inspector-unit/viewport-datagrid-items-attached-to-dom.js [ Failure ]
 crbug.com/591099 http/tests/inspector-unit/viewport-datagrid-items-expandable-attached-to-dom.js [ Failure ]
-crbug.com/591099 http/tests/inspector/appcache/appcache-iframe-manifests.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/appcache/appcache-manifest-with-non-existing-file.html [ Failure Timeout ]
-crbug.com/591099 http/tests/inspector/appcache/appcache-swap.html [ Failure Timeout ]
+crbug.com/591099 http/tests/devtools/appcache/appcache-iframe-manifests.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/appcache/appcache-manifest-with-non-existing-file.html [ Failure Timeout ]
+crbug.com/591099 http/tests/devtools/appcache/appcache-swap.html [ Failure Timeout ]
 crbug.com/591099 http/tests/inspector/application-panel/resources-panel-on-navigation.html [ Failure Pass Timeout ]
 crbug.com/591099 http/tests/inspector/application-panel/resources-panel-resource-preview.html [ Failure Pass Timeout ]
 crbug.com/591099 http/tests/inspector/application-panel/resources-panel-selection-on-reload.html [ Failure Pass Timeout ]
@@ -12380,12 +12377,12 @@
 crbug.com/591099 http/tests/inspector/bindings/sourcemap-navigator-multiple-frames.html [ Crash Failure Pass Timeout ]
 crbug.com/591099 http/tests/inspector/bindings/suspendtarget-bindings.html [ Crash Failure Pass Timeout ]
 crbug.com/591099 http/tests/inspector/bindings/suspendtarget-navigator.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/cache-storage/cache-data.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/cache-storage/cache-deletion.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/cache-storage/cache-entry-deletion.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/cache-storage/cache-live-update-cache-content.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/cache-storage/cache-live-update-list.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/cache-storage/cache-names.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/cache-storage/cache-data.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/cache-storage/cache-deletion.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/cache-storage/cache-entry-deletion.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/cache-storage/cache-live-update-cache-content.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/cache-storage/cache-live-update-list.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/cache-storage/cache-names.html [ Failure Pass Timeout ]
 crbug.com/591099 http/tests/inspector/command-line-api-inspect.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/compiler-script-mapping.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/compiler-source-mapping-debug.html [ Crash Failure Pass ]
@@ -12398,21 +12395,21 @@
 crbug.com/591099 http/tests/inspector/console-xhr-logging-async.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/console-xhr-logging.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/console/console-links-on-messages-before-inspection.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/debugger/fetch-breakpoints.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/elements-linkify-attributes.html [ Crash Failure Timeout ]
-crbug.com/591099 http/tests/inspector/elements/event-listeners-framework-with-service-worker.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/elements/html-link-import.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/edit-css-with-source-url.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/import-added-through-js-crash.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/selector-line-deprecated.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/selector-line-sourcemap-header.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/selector-line.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/styles-redirected-css.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/stylesheet-tracking.html [ Crash Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/elements/styles/xsl-transformed.xml [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/debugger/fetch-breakpoints.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/elements-linkify-attributes.html [ Crash Failure Timeout ]
+crbug.com/591099 http/tests/devtools/elements/event-listeners-framework-with-service-worker.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/elements/html-link-import.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/edit-css-with-source-url.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/import-added-through-js-crash.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/selector-line-deprecated.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/selector-line-sourcemap-header-deprecated.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/selector-line-sourcemap-header.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/selector-line.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/styles-redirected-css.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/stylesheet-tracking.html [ Crash Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/elements/styles/xsl-transformed.xml [ Crash Failure Pass Timeout ]
 crbug.com/591099 http/tests/inspector/extensions-headers.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/extensions-iframe-eval.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/extensions-ignore-cache.html [ Crash Failure Pass ]
@@ -12475,76 +12472,76 @@
 crbug.com/591099 http/tests/inspector/resource-har-headers.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/resource-parameters-ipv6.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/resource-parameters.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/cached-resource-metadata.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/iframe-main-resource.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-metadata.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-request-content-after-loading-and-clearing-cache.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-request-content-while-loading.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-crafted-frame-add.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-document-url.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-events.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-frame-add.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-frame-navigate.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-htmlimports.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-invalid-mime-type-css-content.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-no-xhrs.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/resource-tree/resource-tree-non-unique-url.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/search-ignore-binary-files.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/search-in-non-existing-resource.html [ Failure ]
-crbug.com/591099 http/tests/inspector/search/search-in-resource.html [ Failure ]
-crbug.com/591099 http/tests/inspector/search/search-in-script.html [ Failure ]
-crbug.com/591099 http/tests/inspector/search/search-in-static.html [ Failure ]
-crbug.com/591099 http/tests/inspector/search/source-frame-replace-1.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/source-frame-replace-2.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/source-frame-replace-3.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/source-frame-replace-4.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/source-frame-search.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/sources-search-scope-in-files.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/search/sources-search-scope-many-projects.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/blank-origins-not-shown.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/security/blocked-mixed-content.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/failed-request.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/interstitial-sidebar.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/main-origin-assigned-despite-request-missing.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/security/mixed-content-active-and-passive-reload.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/mixed-content-reload.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/origin-group-names-unique.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/origin-view-then-interstitial.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/security-blocked-mixed-content.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/security-details-updated-with-security-state.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/security-explanation-ordering.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/security-state-comparator.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/security-summary.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/security/security-unknown-resource.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/service-workers/lazy-addeventlisteners.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-worker-agents.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-worker-manager.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-worker-network-fetch-blocked.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-worker-network-fetch.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-worker-pause.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-workers-navigation-preload.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-workers-redundant.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/service-workers-view.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/service-workers/user-agent-override.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/sources/css-sourcemaps-toggle-enabled.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/debugger/async-callstack-fetch.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/debugger/async-callstack-network-initiator-image.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/debugger/async-callstack-network-initiator.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/sources/debugger/pause-in-removed-frame.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/debugger/source-map-http-header.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/debugger/worker-debugging-script-mapping.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/debugger/worker-debugging.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/event-listener-breakpoints-script-fst-stmt-for-module.html [ Failure Pass Timeout ]
-crbug.com/591099 http/tests/inspector/sources/js-sourcemaps-toggle-enabled.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/navigator-view-content-scripts.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/ui-source-code-highlight.php [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/sources/ui-source-code-metadata.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/stacktraces/csp-inline-warning-contains-stacktrace.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace.html [ Failure Pass ]
-crbug.com/591099 http/tests/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/cached-resource-metadata.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/iframe-main-resource.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-metadata.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-request-content-after-loading-and-clearing-cache.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-request-content-while-loading.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-document-url.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-events.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-frame-add.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-frame-navigate.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-htmlimports.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-invalid-mime-type-css-content.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-no-xhrs.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/resource-tree/resource-tree-non-unique-url.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/search-ignore-binary-files.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/search-in-non-existing-resource.html [ Failure ]
+crbug.com/591099 http/tests/devtools/search/search-in-resource.html [ Failure ]
+crbug.com/591099 http/tests/devtools/search/search-in-script.html [ Failure ]
+crbug.com/591099 http/tests/devtools/search/search-in-static.html [ Failure ]
+crbug.com/591099 http/tests/devtools/search/source-frame-replace-1.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/source-frame-replace-2.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/source-frame-replace-3.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/source-frame-replace-4.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/source-frame-search.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/sources-search-scope-in-files.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/search/sources-search-scope-many-projects.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/blank-origins-not-shown.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/security/blocked-mixed-content.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/failed-request.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/interstitial-sidebar.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/main-origin-assigned-despite-request-missing.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/security/mixed-content-active-and-passive-reload.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/mixed-content-reload.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/origin-group-names-unique.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/origin-view-then-interstitial.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/security-blocked-mixed-content.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/security-details-updated-with-security-state.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/security-explanation-ordering.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/security-state-comparator.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/security-summary.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/security/security-unknown-resource.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/service-workers/lazy-addeventlisteners.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-worker-agents.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-worker-manager.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-worker-network-fetch-blocked.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-worker-network-fetch.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-worker-pause.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-workers-force-update-on-page-load.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-workers-navigation-preload.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-workers-redundant.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/service-workers-view.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/service-workers/user-agent-override.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/sources/css-sourcemaps-toggle-enabled.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger/async-callstack-fetch.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger/async-callstack-network-initiator-image.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger/async-callstack-network-initiator.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/sources/debugger/pause-in-removed-frame.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger/source-map-http-header.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger/worker-debugging-script-mapping.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger/worker-debugging.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.html [ Failure Pass Timeout ]
+crbug.com/591099 http/tests/devtools/sources/js-sourcemaps-toggle-enabled.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/navigator-view-content-scripts.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/ui-source-code-highlight.php [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/sources/ui-source-code-metadata.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/stacktraces/csp-inline-warning-contains-stacktrace.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace.html [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace.html [ Failure Pass ]
 crbug.com/591099 http/tests/inspector/stylesheet-source-mapping.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/template-content-inspect-crash.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/inspector/text-source-map.html [ Crash Failure Pass ]
@@ -15761,7 +15758,6 @@
 crbug.com/591099 svg/text/foreignObject-repaint.xml [ Failure ]
 crbug.com/591099 svg/text/foreignObject-text-clipping-bug.xml [ Failure Pass ]
 crbug.com/591099 svg/text/invalid-glyph-crash.html [ Failure Pass ]
-crbug.com/757767 svg/text/layout-inline-children-assert.html [ Crash ]
 crbug.com/591099 svg/text/lengthAdjust-text-metrics.html [ Failure Pass ]
 crbug.com/591099 svg/text/ligature-queries.html [ Failure Pass ]
 crbug.com/591099 svg/text/scaling-font-with-geometric-precision.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index 6e895a7..3e8dd77 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -307,12 +307,12 @@
 crbug.com/721408 http/tests/inspector-protocol/network/xhr-interception-auth-fail.js [ Failure ]
 crbug.com/721408 http/tests/inspector-protocol/network/xhr-interception.js [ Timeout ]
 crbug.com/721408 http/tests/inspector-protocol/page/frameScheduledNavigation.js [ Crash ]
-crbug.com/721408 http/tests/inspector/service-workers/service-worker-network-fetch.html [ Failure ]
-crbug.com/721408 http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html [ Crash ]
-crbug.com/721408 http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html [ Timeout ]
-crbug.com/721408 http/tests/inspector/service-workers/service-workers-navigation-preload.html [ Timeout ]
-crbug.com/721408 http/tests/inspector/service-workers/service-workers-redundant.html [ Timeout ]
-crbug.com/721408 http/tests/inspector/service-workers/service-workers-view.html [ Timeout ]
+crbug.com/721408 http/tests/devtools/service-workers/service-worker-network-fetch.html [ Failure ]
+crbug.com/721408 http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.html [ Crash ]
+crbug.com/721408 http/tests/devtools/service-workers/service-workers-force-update-on-page-load.html [ Timeout ]
+crbug.com/721408 http/tests/devtools/service-workers/service-workers-navigation-preload.html [ Timeout ]
+crbug.com/721408 http/tests/devtools/service-workers/service-workers-redundant.html [ Timeout ]
+crbug.com/721408 http/tests/devtools/service-workers/service-workers-view.html [ Timeout ]
 crbug.com/721408 http/tests/devtools/console/console-uncaught-promise.html [ Failure ]
 crbug.com/721408 http/tests/devtools/sources/debugger-async/async-callstack-xhrs.html [ Failure Timeout ]
 Bug(none) http/tests/loading/307-after-303-after-post.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
index 6717312..89a43a0 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -133,10 +133,10 @@
 crbug.com/645641 external/wpt/html/syntax/parsing/html5lib_tests19.html [ Crash Failure ]
 
 # http/ flaky tests w/ --site-per-process
-crbug.com/678481 http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout Pass ]
-crbug.com/678481 virtual/mojo-loading/http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout Pass ]
-crbug.com/678482 http/tests/inspector/debugger/fetch-breakpoints.html [ Timeout Pass ]
-crbug.com/678482 virtual/mojo-loading/http/tests/inspector/debugger/fetch-breakpoints.html [ Timeout Pass ]
+crbug.com/678481 http/tests/devtools/appcache/appcache-iframe-manifests.html [ Timeout Pass ]
+crbug.com/678481 virtual/mojo-loading/http/tests/devtools/appcache/appcache-iframe-manifests.html [ Timeout Pass ]
+crbug.com/678482 http/tests/devtools/debugger/fetch-breakpoints.html [ Timeout Pass ]
+crbug.com/678482 virtual/mojo-loading/http/tests/devtools/debugger/fetch-breakpoints.html [ Timeout Pass ]
 crbug.com/678484 http/tests/inspector-enabled/reattach-after-editing-styles.html [ Timeout Pass ]
 crbug.com/678484 virtual/mojo-loading/http/tests/inspector-enabled/reattach-after-editing-styles.html [ Timeout Pass ]
 crbug.com/678485 http/tests/inspector-enabled/shadow-dom-rules-restart.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 0685230..31f4962 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -131,10 +131,8 @@
 
 # Debugger and profiler tests are slow in Release as well.
 crbug.com/450493 http/tests/devtools/startup/sources/ [ Slow ]
-crbug.com/450493 http/tests/inspector/sources/ [ Slow ]
-crbug.com/450493 virtual/mojo-loading/http/tests/inspector/sources/ [ Slow ]
-crbug.com/450493 http/tests/inspector/stacktraces/ [ Slow ]
-crbug.com/450493 virtual/mojo-loading/http/tests/inspector/stacktraces/ [ Slow ]
+crbug.com/450493 http/tests/devtools/stacktraces/ [ Slow ]
+crbug.com/450493 virtual/mojo-loading/http/tests/devtools/stacktraces/ [ Slow ]
 crbug.com/450493 http/tests/devtools/profiler/ [ Slow ]
 crbug.com/450493 virtual/mojo-loading/http/tests/devtools/profiler/ [ Slow ]
 crbug.com/420008 http/tests/devtools/tracing/ [ Slow ]
@@ -160,12 +158,12 @@
 crbug.com/667560 [ Linux ] virtual/mojo-loading/http/tests/devtools/elements/insert-node.html [ Slow ]
 webkit.org/b/84735 [ Win ] http/tests/inspector/change-iframe-src.html [ Slow ]
 webkit.org/b/84735 [ Win ] virtual/mojo-loading/http/tests/inspector/change-iframe-src.html [ Slow ]
-crbug.com/504565 [ Mac ] http/tests/inspector/search/sources-search-scope.html [ Slow ]
-crbug.com/504565 [ Mac ] virtual/mojo-loading/http/tests/inspector/search/sources-search-scope.html [ Slow ]
-crbug.com/451577 http/tests/inspector/resource-tree/resource-tree-crafted-frame-add.html [ Slow ]
-crbug.com/451577 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-crafted-frame-add.html [ Slow ]
-crbug.com/451577 http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame.html [ Slow ]
-crbug.com/451577 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame.html [ Slow ]
+crbug.com/504565 [ Mac ] http/tests/devtools/search/sources-search-scope.html [ Slow ]
+crbug.com/504565 [ Mac ] virtual/mojo-loading/http/tests/devtools/search/sources-search-scope.html [ Slow ]
+crbug.com/451577 http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.html [ Slow ]
+crbug.com/451577 virtual/mojo-loading/http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.html [ Slow ]
+crbug.com/451577 http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.html [ Slow ]
+crbug.com/451577 virtual/mojo-loading/http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.html [ Slow ]
 crbug.com/763197 [ Mac ] virtual/gpu-rasterization/images/color-profile-border-radius.html [ Slow ]
 crbug.com/763197 [ Mac ] virtual/gpu-rasterization/images/color-profile-image-canvas-svg.html [ Slow ]
 crbug.com/763197 [ Mac ] virtual/gpu-rasterization/images/color-profile-image-svg-resource-url.html [ Slow ]
@@ -279,10 +277,10 @@
 crbug.com/504706 [ Linux ] http/tests/devtools/profiler/heap-snapshot-containment-sorting.html [ Slow ]
 crbug.com/667560 [ Linux ] virtual/mojo-loading/http/tests/devtools/profiler/heap-snapshot-containment-sorting.html [ Slow ]
 crbug.com/440452 virtual/display_list_2d_canvas/fast/canvas/canvas-partial-invalidation-zoomed.html [ Slow ]
-crbug.com/480769 http/tests/inspector/service-workers/service-workers-redundant.html [ Slow ]
-crbug.com/480769 virtual/mojo-loading/http/tests/inspector/service-workers/service-workers-redundant.html [ Slow ]
-crbug.com/480769 http/tests/inspector/service-workers/service-worker-agents.html [ Slow ]
-crbug.com/480769 virtual/mojo-loading/http/tests/inspector/service-workers/service-worker-agents.html [ Slow ]
+crbug.com/480769 http/tests/devtools/service-workers/service-workers-redundant.html [ Slow ]
+crbug.com/480769 virtual/mojo-loading/http/tests/devtools/service-workers/service-workers-redundant.html [ Slow ]
+crbug.com/480769 http/tests/devtools/service-workers/service-worker-agents.html [ Slow ]
+crbug.com/480769 virtual/mojo-loading/http/tests/devtools/service-workers/service-worker-agents.html [ Slow ]
 crbug.com/504703 inspector-protocol/debugger/debugger-step-into-dedicated-worker.js [ Slow ]
 crbug.com/535478 [ Win ] virtual/threaded/http/tests/devtools/tracing/decode-resize.html [ Slow ]
 crbug.com/548765 http/tests/inspector/console-fetch-logging.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 3455779..845ef76 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -274,7 +274,6 @@
 
 ### virtual/layout_ng Mac textarea.
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/overhanging-tall-block.html [ Failure ]
-crbug.com/763494 [ Mac ] virtual/layout_ng/fast/block/float/editable-text-overlapping-float.html [ Failure ]
 
 ### virtual/layout_ng Mac 1px glyph difference.
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/basic/015.html [ Failure ]
@@ -626,7 +625,7 @@
 crbug.com/522648 fast/events/touch/compositor-touch-hit-rects-iframes.html [ Crash Failure Pass ]
 crbug.com/521858 [ Win7 ] http/tests/security/media-element-audio-source-node-same-origin.html [ Failure Pass ]
 crbug.com/521858 [ Win7 ] virtual/mojo-loading/http/tests/security/media-element-audio-source-node-same-origin.html [ Failure Pass ]
-crbug.com/521853 [ Win ] http/tests/inspector/search/sources-search-scope.html [ Failure Pass ]
+crbug.com/521853 [ Win ] http/tests/devtools/search/sources-search-scope.html [ Failure Pass ]
 crbug.com/520170 fast/dom/timer-throttling-hidden-page.html [ Failure Pass ]
 crbug.com/652536 fast/events/mouse-cursor-change-after-image-load.html [ Failure Pass ]
 crbug.com/520188 [ Win ] http/tests/local/fileapi/file-last-modified-after-delete.html [ Failure Pass ]
@@ -1354,8 +1353,8 @@
 crbug.com/479533 accessibility/show-context-menu-shadowdom.html [ Skip ]
 crbug.com/483653 accessibility/scroll-containers.html [ Skip ]
 
-crbug.com/491764 http/tests/inspector/service-workers/user-agent-override.html [ Pass Timeout ]
-crbug.com/491764 virtual/mojo-loading/http/tests/inspector/service-workers/user-agent-override.html [ Pass Timeout ]
+crbug.com/491764 http/tests/devtools/service-workers/user-agent-override.html [ Pass Timeout ]
+crbug.com/491764 virtual/mojo-loading/http/tests/devtools/service-workers/user-agent-override.html [ Pass Timeout ]
 
 # Fails with leak detector.
 crbug.com/622915 [ Linux ] ietestcenter/css3/grid/grid-column-003.htm [ Skip ]
@@ -2290,9 +2289,9 @@
 
 crbug.com/697971 [ Mac10.12 ] fast/text/flexbox-selection-nested.html [ Skip ]
 crbug.com/697971 [ Mac10.12 ] fast/text/flexbox-selection.html [ Skip ]
-crbug.com/678481 http/tests/inspector/appcache/appcache-manifest-with-non-existing-file.html [ Timeout Failure Pass ]
-crbug.com/678481 http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout Failure Pass ]
-crbug.com/678481 virtual/mojo-loading/http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout Failure Pass ]
+crbug.com/678481 http/tests/devtools/appcache/appcache-manifest-with-non-existing-file.html [ Timeout Failure Pass ]
+crbug.com/678481 http/tests/devtools/appcache/appcache-iframe-manifests.html [ Timeout Failure Pass ]
+crbug.com/678481 virtual/mojo-loading/http/tests/devtools/appcache/appcache-iframe-manifests.html [ Timeout Failure Pass ]
 
 crbug.com/701047 [ Mac10.12 ] editing/caret/caret-color.html [ Failure ]
 crbug.com/701047 [ Mac10.12 ] editing/deleting/delete-at-paragraph-boundaries-011.html [ Failure ]
@@ -2713,8 +2712,8 @@
 crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ]
 crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ]
 
-crbug.com/678487 http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
-crbug.com/678487 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
+crbug.com/678487 http/tests/devtools/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
+crbug.com/678487 virtual/mojo-loading/http/tests/devtools/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
 crbug.com/678492 http/tests/misc/webtiming-ssl.php [ Failure Pass ]
 crbug.com/678492 virtual/mojo-loading/http/tests/misc/webtiming-ssl.php [ Failure Pass ]
 crbug.com/678493 http/tests/permissions/chromium/test-request-window.html [ Timeout Pass ]
@@ -3481,7 +3480,7 @@
 crbug.com/757165 [ Win ] http/tests/devtools/console/console-filter-test.js [ Skip ]
 crbug.com/757165 [ Win ] http/tests/devtools/console/console-links-in-errors-with-trace.js [ Skip ]
 crbug.com/757165 [ Win ] http/tests/inspector/extensions/extensions-panel.html [ Skip ]
-crbug.com/757165 [ Win ] http/tests/inspector/sources/ui-source-code-metadata.html [ Skip ]
+crbug.com/757165 [ Win ] http/tests/devtools/sources/ui-source-code-metadata.html [ Skip ]
 crbug.com/757165 [ Win ] http/tests/misc/client-hints-accept-meta-preloader.html [ Skip ]
 crbug.com/757165 [ Win ] inspector-protocol/debugger/debugger-evaluate-in-worker-while-pause-in-page.js [ Skip ]
 crbug.com/757165 [ Win ] paint/invalidation/filter-repaint-accelerated-child-with-filter-child.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index c2016a8c..14456da 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -91,8 +91,6 @@
 external/wpt/css/css-gcpm-3 [ Skip ]
 external/wpt/css/css-images-3 [ Skip ]
 external/wpt/css/css-lists-3 [ Skip ]
-external/wpt/css/css-logical-properties-1 [ Skip ]
-external/wpt/css/css-logical-props-1 [ Skip ]
 external/wpt/css/css-masking-1 [ Skip ]
 external/wpt/css/css-multicol-1 [ Skip ]
 external/wpt/css/css-page-3 [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/WebCryptoAPI/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/WebCryptoAPI/OWNERS
index 6b60858..36ec465 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/WebCryptoAPI/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/WebCryptoAPI/OWNERS
@@ -1,2 +1,3 @@
+# COMPONENT: Blink>WebCrypto
 eroman@chromium.org
 rsleevi@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/WebIDL/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/WebIDL/OWNERS
index 82c8165..215d2ff 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/WebIDL/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/WebIDL/OWNERS
@@ -1 +1 @@
-jsbell@chromium.org
+file://third_party/WebKit/Source/bindings/OWNERS
diff --git a/third_party/WebKit/LayoutTests/external/wpt/battery-status/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/battery-status/OWNERS
index 1fd89e0..f34b5e2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/battery-status/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/battery-status/OWNERS
@@ -1 +1,2 @@
+# TEAM: device-dev@chromium.org
 timvolodine@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-logical-1/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/css/css-logical-1/OWNERS
new file mode 100644
index 0000000..7c1ec12
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-logical-1/OWNERS
@@ -0,0 +1,2 @@
+# TEAM: layout-dev@chromium.org
+# COMPONENT: Blink>Layout
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/OWNERS
index 806af33..f850950 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/OWNERS
@@ -1,3 +1,5 @@
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Geometry
 xlai@chromium.org
 jinho.bang@samsung.com
 hs1217.lee@samsung.com
diff --git a/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/OWNERS
index 0e594c4..13a42cc 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/OWNERS
@@ -1,3 +1,5 @@
+# TEAM: device-dev@chromium.org
+# COMPONENT: Blink>Sensor
 alexander.shalamov@intel.com
 mikhail.pozdnyakov@intel.com
 rijubrata.bhaumik@intel.com
diff --git a/third_party/WebKit/LayoutTests/external/wpt/geolocation-API/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/geolocation-API/OWNERS
index ad80981..6d678d8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/geolocation-API/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/geolocation-API/OWNERS
@@ -1 +1,3 @@
+# TEAM: device-dev@chromium.org
+# COMPONENT: Blink>Location
 mcasas@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/hr-time/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/hr-time/OWNERS
index 82c8165..512c125a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/hr-time/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/hr-time/OWNERS
@@ -1 +1,2 @@
-jsbell@chromium.org
+# COMPONENT: Blink>PerformanceAPIs
+tdresser@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html-media-capture/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/html-media-capture/OWNERS
index 760a95a..5db6e74 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html-media-capture/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/html-media-capture/OWNERS
@@ -1,2 +1,4 @@
+# TEAM: media-dev@chromium.org
+# COMPONENT: Blink>ImageCapture
 rijubrata.bhaumik@intel.com
 mcasas@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/longtask-timing/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/longtask-timing/OWNERS
index 7124712..3264c0f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/longtask-timing/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/longtask-timing/OWNERS
@@ -1 +1,2 @@
+# COMPONENT: Blink>PerformanceAPIs
 panicker@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/OWNERS
index ad80981..681555b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/OWNERS
@@ -1 +1,3 @@
+# TEAM: media-dev@chromium.org
+# COMPONENT: Blink>MediaRecording
 mcasas@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/OWNERS
index 2cb971d..e3f972f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/OWNERS
@@ -1 +1,2 @@
+# COMPONENT: Blink>MediaStream
 phoglund@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediasession/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/mediasession/OWNERS
index f5ecf0f..ee18e77c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/mediasession/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/mediasession/OWNERS
@@ -1,3 +1,4 @@
 # TEAM: media-dev@chromium.org
+# COMPONENT: Blink>Media>Session
 mlamouri@chromium.org
 zqzhang@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/OWNERS
index 536d4e7..b7e17f3d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/OWNERS
@@ -1,2 +1,2 @@
-sunjian@chromium.org
-panicker@chromium.org
+# COMPONENT: Blink>PerformanceAPIs>NavigationTiming
+tyoshino@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/notifications/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/notifications/OWNERS
index 4b8a529..1c13657 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/notifications/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/notifications/OWNERS
@@ -1 +1 @@
-platform-capabilities@chromium.org
+# TEAM: platform-capabilities@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/paint-timing/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/paint-timing/OWNERS
index 961833bd..51b9940 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/paint-timing/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/paint-timing/OWNERS
@@ -1,2 +1,3 @@
+# COMPONENT: Blink>PerformanceAPIs
 panicker@chromium.org
 tdresser@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/performance-timeline/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/performance-timeline/OWNERS
index e2bc148e..c48c479 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/performance-timeline/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/performance-timeline/OWNERS
@@ -1,2 +1,3 @@
+# COMPONENT: Blink>PerformanceAPIs
 igrigorik@chromium.org
 panicker@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/presentation-api/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/presentation-api/OWNERS
index 0d7e44d..f9d59ea 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/presentation-api/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/presentation-api/OWNERS
@@ -1 +1,2 @@
-media-dev@chromium.org
+# TEAM: media-dev@chromium.org
+# COMPONENT: Blink>PresentationAPI
diff --git a/third_party/WebKit/LayoutTests/external/wpt/remote-playback/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/remote-playback/OWNERS
index dc2593f..f5ae13d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/remote-playback/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/remote-playback/OWNERS
@@ -1,2 +1,4 @@
+# TEAM: media-dev@chromium.org
+# COMPONENT: Blink>Media>RemotePlayback
 avayvod@chromium.org
 mlamouri@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resource-timing/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/resource-timing/OWNERS
index 5c41d86..a50dd2d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/resource-timing/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/resource-timing/OWNERS
@@ -1 +1,2 @@
+# COMPONENT: Blink>PerformanceAPIs>ResourceTiming
 ksakamoto@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/screen-orientation/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/screen-orientation/OWNERS
index 2d28246..af79dee 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/screen-orientation/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/screen-orientation/OWNERS
@@ -1 +1,2 @@
+# COMPONENT: Blink>ScreenOrientation
 mlamouri@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/storage/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/storage/OWNERS
index 82c8165..dae5a38 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/storage/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/storage/OWNERS
@@ -1 +1,3 @@
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>Quota
 jsbell@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/uievents/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/uievents/OWNERS
index 26a49787..e83df7e2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/uievents/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/uievents/OWNERS
@@ -1 +1,3 @@
+# TEAM: input-dev@chromium.org
+# COMPONENT: Blink>Input
 dtapuska@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/user-timing/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/user-timing/OWNERS
index 82c8165..3264c0f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/user-timing/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/user-timing/OWNERS
@@ -1 +1,2 @@
-jsbell@chromium.org
+# COMPONENT: Blink>PerformanceAPIs
+panicker@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/vibration/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/vibration/OWNERS
index 4b8a529..4d14efd 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/vibration/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/vibration/OWNERS
@@ -1 +1,2 @@
-platform-capabilities@chromium.org
+# TEAM: platform-capabilities@chromium.org
+# COMPONENT: Blink>Vibration
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-nfc/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/web-nfc/OWNERS
index c316160..3ce5e1e 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-nfc/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-nfc/OWNERS
@@ -1,3 +1,5 @@
+# TEAM: device-dev@chromium.org
+# COMPONENT: Blink>NFC
 alexander.shalamov@intel.com
 kenneth.r.christiansen@intel.com
 rijubrata.bhaumik@intel.com
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/webaudio/OWNERS
index a837fc9b..53b19d0 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webaudio/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/OWNERS
@@ -1,2 +1,3 @@
+# COMPONENT: Blink>WebAudio
 hongchan@chromium.org
 rtoy@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webmessaging/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/webmessaging/OWNERS
index 1b10b343..9f8c4a0f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webmessaging/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/webmessaging/OWNERS
@@ -1 +1,2 @@
+# COMPONENT: Blink>Messaging
 mek@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/webrtc/OWNERS
index da0fa7eb5..bb3cc83 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/OWNERS
@@ -1 +1,2 @@
+# COMPONENT: Blink>WebRTC
 hta@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/webvr/OWNERS
index 428f610..59931fa8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webvr/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/OWNERS
@@ -1 +1,3 @@
+# TEAM: hoverboard-team@chromium.org
+# COMPONENT: Blink>WebVR
 bsheedy@chromium.org
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/webvtt/OWNERS
index 52f73a6..36a8294 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webvtt/OWNERS
+++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/OWNERS
@@ -1,2 +1,4 @@
+# TEAM: media-dev@chromium.org
+# COMPONENT: Blink>Media>Track
 foolip@chromium.org
 msisov@igalia.com
diff --git a/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-scrollBoundaryBehavior-serialization.html b/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-scrollBoundaryBehavior-serialization.html
new file mode 100644
index 0000000..57691496
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-scrollBoundaryBehavior-serialization.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<!-- https://wicg.github.io/scroll-boundary-behavior/#scroll-boundary-behavior-properties -->
+
+<style>
+  #container {
+    scroll-boundary-behavior-x: none;
+    scroll-boundary-behavior-y: contain;
+  }
+  #child {
+    scroll-boundary-behavior: inherit;
+  }
+</style>
+<div id="container">
+  <div id="child"></div>
+</div>
+<div id="target"></div>
+
+<script>
+'use strict';
+
+test(function() {
+  assert_equals(getComputedStyle(document.body).scrollBoundaryBehavior, 'auto auto');
+  assert_equals(getComputedStyle(container).scrollBoundaryBehavior, 'none contain');
+  assert_equals(getComputedStyle(child).scrollBoundaryBehavior, 'none contain');
+}, "Test that getComputedStyle serializes scroll-boundary-behavior-x and scroll-boundary-behavior-y");
+
+var values = [
+  // single keyword
+  {input: 'contain', expected: 'contain contain'},
+  {input: 'none', expected: 'none none'},
+  {input: 'auto', expected: 'auto auto'},
+
+  // two keywords
+  {input: 'contain none', expected: 'contain none'},
+  {input: 'none auto', expected: 'none auto'},
+  {input: 'auto contain', expected: 'auto contain'},
+];
+
+test(function() {
+  for (var value of values) {
+    target.style.scrollBoundaryBehavior = value.input;
+    assert_equals(getComputedStyle(target).scrollBoundaryBehavior, value.expected);
+  }
+}, "Test that getComputedStyle serializes scrollBoundaryBehavior as per the spec");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/harness/test-expectations.html b/third_party/WebKit/LayoutTests/fast/harness/test-expectations.html
index 275a8ce..452b07c 100644
--- a/third_party/WebKit/LayoutTests/fast/harness/test-expectations.html
+++ b/third_party/WebKit/LayoutTests/fast/harness/test-expectations.html
@@ -708,7 +708,7 @@
   updateFilters: function(traversal) {
     for (let el of Array.from(
           document.querySelectorAll("#filters > label"))) {
-      let count = traversal.resultCounts[el.id];
+      let count = traversal.resultCounts[el.id.replace("_", "+")];
       if (count > 0) {
         el.classList.remove("hidden");
         el.querySelector('input').checked = true;
@@ -730,7 +730,7 @@
     for (let el of Array.from(
           document.querySelectorAll("#filters > label"))) {
         if (el.querySelector('input').checked)
-          filterMap.set(el.id, true);
+          filterMap.set(el.id.replace("_", "+"), true);
     }
     return test => queryFilter(test) && filterMap.has(test.actualFinal);
   },
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-iframe-manifests-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-iframe-manifests-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-iframe-manifests-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-iframe-manifests-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-iframe-manifests.html b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-iframe-manifests.html
similarity index 93%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-iframe-manifests.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-iframe-manifests.html
index 6f1f775..efeb594 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-iframe-manifests.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-iframe-manifests.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="appcache-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/appcache/appcache-test.js"></script>
 <script>
 function test() {
   var frameId1;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-manifest-with-non-existing-file-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-manifest-with-non-existing-file-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-manifest-with-non-existing-file-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-manifest-with-non-existing-file-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-manifest-with-non-existing-file.html b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-manifest-with-non-existing-file.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-manifest-with-non-existing-file.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-manifest-with-non-existing-file.html
index 7121bfd..b30e72b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-manifest-with-non-existing-file.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-manifest-with-non-existing-file.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="appcache-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/appcache/appcache-test.js"></script>
 <script>
 function test() {
   var frameId1;
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-swap-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-swap-expected.txt
new file mode 100644
index 0000000..4a76ee3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-swap-expected.txt
@@ -0,0 +1,42 @@
+CONSOLE MESSAGE: line 6: XHR loaded: 1
+Tests that application cache model keeps track of manifest urls and statuses correctly after UPDATEREADY event and swapCache() call.
+
+Bug 72123  
+Dumping application cache tree:
+    (empty)
+Dumping application cache model:
+    (empty)
+
+Dumping application cache tree:
+    Manifest URL: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        Frame: frame1 (with-versioned-manifest.php)
+Dumping application cache model:
+    Frame: frame1
+        manifest url: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        status:       IDLE
+
+Dumping application cache tree:
+    Manifest URL: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        Frame: frame1 (with-versioned-manifest.php)
+        Frame: frame2 (with-versioned-manifest.php)
+Dumping application cache model:
+    Frame: frame1
+        manifest url: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        status:       UPDATEREADY
+    Frame: frame2
+        manifest url: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        status:       UPDATEREADY
+
+Dumping application cache tree:
+    Manifest URL: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        Frame: frame1 (with-versioned-manifest.php)
+        Frame: frame2 (with-versioned-manifest.php)
+Dumping application cache model:
+    Frame: frame1
+        manifest url: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        status:       IDLE
+    Frame: frame2
+        manifest url: http://127.0.0.1:8000/devtools/appcache/resources/versioned-manifest.php
+        status:       UPDATEREADY
+
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-swap.html b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-swap.html
similarity index 88%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-swap.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-swap.html
index 06ef914..e259c4bf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-swap.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/appcache-swap.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="appcache-test.js"></script>
-<script src="../network-test.js"></script>
-<script src="../resources-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/appcache/appcache-test.js"></script>
+<script src="../../inspector/network-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
 <script>
 function test() {
   var frameId1;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/manifest.php b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/manifest.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/manifest.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/manifest.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/page-with-manifest.php b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/page-with-manifest.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/page-with-manifest.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/page-with-manifest.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/versioned-manifest.php b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/versioned-manifest.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/versioned-manifest.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/versioned-manifest.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/with-versioned-manifest.php b/third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/with-versioned-manifest.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/appcache/resources/with-versioned-manifest.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/appcache/resources/with-versioned-manifest.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/audits/resources/abe.png b/third_party/WebKit/LayoutTests/http/tests/devtools/audits/resources/abe.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/audits/resources/abe.png
rename to third_party/WebKit/LayoutTests/http/tests/devtools/audits/resources/abe.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/audits/set-cookie-header-audit-no-false-positive-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/audits/set-cookie-header-audit-no-false-positive-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/audits/set-cookie-header-audit-no-false-positive-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/audits/set-cookie-header-audit-no-false-positive-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/audits/set-cookie-header-audit-no-false-positive.html b/third_party/WebKit/LayoutTests/http/tests/devtools/audits/set-cookie-header-audit-no-false-positive.html
similarity index 82%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/audits/set-cookie-header-audit-no-false-positive.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/audits/set-cookie-header-audit-no-false-positive.html
index 47b702b0..779118e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/audits/set-cookie-header-audit-no-false-positive.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/audits/set-cookie-header-audit-no-false-positive.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../network-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/network-test.js"></script>
 <script>
 var test = function() {
   TestRunner.reloadPage(step1);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-data-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-data-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data.html b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-data.html
similarity index 91%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-data.html
index 54ff777..eb82f3e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-data.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="cache-storage-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/cache-storage/cache-storage-test.js"></script>
 <script>
 function test() {
   var cacheStorageModel = TestRunner.mainTarget.model(SDK.ServiceWorkerCacheModel);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-deletion-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-deletion-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion.html b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-deletion.html
similarity index 92%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-deletion.html
index 2919f9ca..b347fab 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-deletion.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="cache-storage-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/cache-storage/cache-storage-test.js"></script>
 <script>
 function test() {
   var cacheStorageModel = TestRunner.mainTarget.model(SDK.ServiceWorkerCacheModel);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-entry-deletion-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-entry-deletion-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion.html b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-entry-deletion.html
similarity index 92%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-entry-deletion.html
index 0e9c26b..d2c88c1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-entry-deletion.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="cache-storage-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/cache-storage/cache-storage-test.js"></script>
 <script>
 function test() {
   var cacheStorageModel = TestRunner.mainTarget.model(SDK.ServiceWorkerCacheModel);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-cache-content-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-cache-content-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content.html b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-cache-content.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-cache-content.html
index f5633fa6..841daafe 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-cache-content.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="cache-storage-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/cache-storage/cache-storage-test.js"></script>
 <script>
 
 async function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-list-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-list-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-list-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-list-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-list.html b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-list.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-list.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-list.html
index 9030841..1e52c450 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-list.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-live-update-list.html
@@ -1,8 +1,8 @@
 <html>
 <head>
 <meta name="timeout" content="long">
-<script src="../inspector-test.js"></script>
-<script src="cache-storage-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/cache-storage/cache-storage-test.js"></script>
 <script>
 
 async function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-names-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-names-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-names-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-names-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-names.html b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-names.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-names.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-names.html
index 30ce0b3..afade49 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-names.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/cache-storage/cache-names.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="cache-storage-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/cache-storage/cache-storage-test.js"></script>
 <script>
 function test() {
   var cacheStorageModel = TestRunner.mainTarget.model(SDK.ServiceWorkerCacheModel);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/debugger/fetch-breakpoints-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/debugger/fetch-breakpoints-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html b/third_party/WebKit/LayoutTests/http/tests/devtools/debugger/fetch-breakpoints.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/debugger/fetch-breakpoints.html
index 9c24942..02a53e3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/debugger/fetch-breakpoints.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
 <script>
 
 function sendRequest(url)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/elements-linkify-attributes-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/elements-linkify-attributes-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/elements-linkify-attributes-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/elements-linkify-attributes-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/elements-linkify-attributes.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/elements-linkify-attributes.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/elements-linkify-attributes.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/elements-linkify-attributes.html
index 2da3038..8763944 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/elements-linkify-attributes.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/elements-linkify-attributes.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../elements-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/elements-test.js"></script>
 <script>
 function test() {
   var i = 0;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker.html
similarity index 80%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker.html
index 844d070f..18d1eca 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker.html
@@ -1,14 +1,14 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="../console-test.js"></script>
-<script src="../service-workers/service-workers-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/console-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
 <script>
 function test() {
   Common.settingForTest('showEventListenersForAncestors').set(false);
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-empty.js';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/scope1/';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-empty.js';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/scope1/';
 
   ApplicationTestRunner.waitForServiceWorker(step1);
   ApplicationTestRunner.registerServiceWorker(scriptURL, scope);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/html-link-import-expected.txt
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/html-link-import-expected.txt
index 7cf2d2b..ce7c9d3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/html-link-import-expected.txt
@@ -31,8 +31,8 @@
                       </body>
                   </html>
           </link>
-          <script src="../inspector-test.js"></script>
-          <script src="../elements-test.js"></script>
+          <script src="../../inspector/inspector-test.js"></script>
+          <script src="../../inspector/elements-test.js"></script>
         - <script>
               \nfunction test() {\n  // Warm up highlighter module.\n  runtime.loadModulePromise('source_frame').then(function() {\n    ElementsTestRunner.expandElementsTree(callback);\n  });\n\n  function callback() {\n    ElementsTestRunner.dumpElementsTree();\n    TestRunner.completeTest();\n  }\n}\n
           </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/html-link-import.html
similarity index 81%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/html-link-import.html
index 329589e..2c664482 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/html-link-import.html
@@ -1,8 +1,8 @@
 <html>
 <head>
 <link rel="import" href="../resources/imported-document.html">
-<script src="../inspector-test.js"></script>
-<script src="../elements-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/elements-test.js"></script>
 <script>
 
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/edit-css-with-source-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/edit-css-with-source-url-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/edit-css-with-source-url-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/edit-css-with-source-url-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/edit-css-with-source-url.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/edit-css-with-source-url.html
similarity index 87%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/edit-css-with-source-url.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/edit-css-with-source-url.html
index 0c946f63..15a1122f7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/edit-css-with-source-url.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/edit-css-with-source-url.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../debugger-test.js"></script>
-<script src="../../elements-test.js"></script>
-<script src="../../isolated-filesystem-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/debugger-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
+<script src="../../../inspector/isolated-filesystem-test.js"></script>
 <style>#inspected {
     color: red;
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/import-added-through-js-crash-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/import-added-through-js-crash-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/import-added-through-js-crash-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/import-added-through-js-crash-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/import-added-through-js-crash.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/import-added-through-js-crash.html
similarity index 87%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/import-added-through-js-crash.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/import-added-through-js-crash.html
index f515ffb..7e1da038 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/import-added-through-js-crash.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/import-added-through-js-crash.html
@@ -2,8 +2,8 @@
 <head>
 <style>
 </style>
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
 <script>
 
 function addImportRule()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html
index 10477b4b..87fb8d9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../bindings/bindings-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/bindings/bindings-test.js"></script>
 <script>
 
 function addStyleSheet() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/modify-cross-domain-rule.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/modify-cross-domain-rule.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/modify-cross-domain-rule.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/modify-cross-domain-rule.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/import-added-through-js-crash.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/import-added-through-js-crash.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/import-added-through-js-crash.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/import-added-through-js-crash.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-deprecated.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-deprecated.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-deprecated.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-deprecated.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header-deprecated.php b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header-deprecated.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header-deprecated.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header-deprecated.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header-deprecated.php.map b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header-deprecated.php.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header-deprecated.php.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header-deprecated.php.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header.php b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header.php.map b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header.php.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header.php.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header.php.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header.scss b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header.scss
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line-sourcemap-header.scss
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line-sourcemap-header.scss
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line.css.map b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line.css.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line.css.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line.css.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line.scss b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line.scss
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/selector-line.scss
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/selector-line.scss
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/styles-redirected-css.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/styles-redirected-css.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/styles-redirected-css.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/styles-redirected-css.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/styles-redirected-css.php b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/styles-redirected-css.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/styles-redirected-css.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/styles-redirected-css.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-iframe.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-iframe.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-iframe.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-iframe.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-import-1.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-import-1.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-import-1.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-import-1.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-import-2.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-import-2.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-import-2.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-import-2.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-import.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-import.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking-import.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking-import.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/stylesheet-tracking.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/stylesheet-tracking.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/update-locations-on-filesystem-scss-load.css b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/update-locations-on-filesystem-scss-load.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/update-locations-on-filesystem-scss-load.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/update-locations-on-filesystem-scss-load.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/update-locations-on-filesystem-scss-load.css.map b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/update-locations-on-filesystem-scss-load.css.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/update-locations-on-filesystem-scss-load.css.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/update-locations-on-filesystem-scss-load.css.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/xsl-transformed.xsl b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/xsl-transformed.xsl
similarity index 81%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/xsl-transformed.xsl
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/xsl-transformed.xsl
index 6061e56c..a310ece4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/resources/xsl-transformed.xsl
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/resources/xsl-transformed.xsl
@@ -5,9 +5,9 @@
     <xsl:template match="items">
         <html>
         <head>
-        <script src="../../inspector-test.js"></script>
-        <script src="../../elements-test.js"></script>
-        <script src="../../resources-test.js"></script>
+        <script src="../../../inspector/inspector-test.js"></script>
+        <script src="../../../inspector/elements-test.js"></script>
+        <script src="../../../inspector/resources-test.js"></script>
         <script>
         function test()
         {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-deprecated-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-deprecated-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-deprecated-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-deprecated-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-deprecated.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-deprecated.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-deprecated.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-deprecated.html
index 24289955b..262fc47 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-deprecated.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-deprecated.html
@@ -6,8 +6,8 @@
   color: green;
 }
 </style>
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
 <script>
 
 function addStylesheet()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header-deprecated-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header-deprecated-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header-deprecated.html
similarity index 88%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header-deprecated.html
index b3c0a3b..e6d3b50 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header-deprecated.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
 <script>
 
 function addStylesheet()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header.html
similarity index 78%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header.html
index 56d28c41..7ac059f3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line-sourcemap-header.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line-sourcemap-header.html
@@ -1,9 +1,9 @@
 <html>
 <head>
 <link rel="stylesheet" href="../styles/resources/selector-line-sourcemap-header.php" />
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
-<script src="../../debugger-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
+<script src="../../../inspector/debugger-test.js"></script>
 <script>
 
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line.html
similarity index 80%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line.html
index 0aacbda..081253e3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/selector-line.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/selector-line.html
@@ -7,9 +7,9 @@
 }
 </style>
 <link rel="stylesheet" href="../styles/resources/selector-line.css" />
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
-<script src="../../debugger-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
+<script src="../../../inspector/debugger-test.js"></script>
 <script>
 
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
similarity index 61%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
index 566feafd..6ac5cc6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
@@ -2,9 +2,9 @@
 
 top
   127.0.0.1:8000
+    devtools/elements/styles
+      styles-do-not-add-inline-stylesheets-in-navigator.html
     inspector
-      elements/styles
-        styles-do-not-add-inline-stylesheets-in-navigator.html
       elements-test.js
       inspector-test.js
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
similarity index 84%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
index 9bfe788..30656d8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
 <style>
 </style>
 <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-redirected-css-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-redirected-css-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-redirected-css-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-redirected-css-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-redirected-css.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-redirected-css.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-redirected-css.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-redirected-css.html
index 345817ff..65afa7a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-redirected-css.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-redirected-css.html
@@ -1,8 +1,8 @@
 <html>
 <head>
 <link rel="stylesheet" href="../styles/resources/styles-redirected-css.php" type="text/css">
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
 <script>
 
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/stylesheet-tracking-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/stylesheet-tracking-expected.txt
similarity index 70%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/stylesheet-tracking-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/stylesheet-tracking-expected.txt
index fbfb6c4..9355c74f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/stylesheet-tracking-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/stylesheet-tracking-expected.txt
@@ -2,17 +2,17 @@
 
 Text
 2 headers known:
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking.css
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking.css
     origin=regular
     isInline=false
     hasSourceURL=false
-    URL=.../inspector/elements/styles/stylesheet-tracking.html
+    URL=.../devtools/elements/styles/stylesheet-tracking.html
     origin=regular
     isInline=true
     hasSourceURL=false
 === Adding iframe... ===
 Stylesheets added:
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-iframe.html
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-iframe.html
     origin=regular
     isInline=true
     hasSourceURL=false
@@ -32,7 +32,7 @@
     origin=regular
     isInline=false
     hasSourceURL=false
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-iframe.html
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-iframe.html
     origin=regular
     isInline=true
     hasSourceURL=false
@@ -41,7 +41,7 @@
     isInline=false
     hasSourceURL=true
 Stylesheets added:
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-iframe.html
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-iframe.html
     origin=regular
     isInline=true
     hasSourceURL=false
@@ -71,29 +71,29 @@
     origin=regular
     isInline=false
     hasSourceURL=false
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-import-1.css
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-import-1.css
     origin=regular
     isInline=false
     hasSourceURL=false
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-import-2.css
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-import-2.css
     origin=regular
     isInline=false
     hasSourceURL=false
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-import.css
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-import.css
     origin=regular
     isInline=false
     hasSourceURL=false
 === Removing @import... ===
 Stylesheets removed:
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-import-1.css
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-import-1.css
     origin=regular
     isInline=false
     hasSourceURL=false
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-import-2.css
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-import-2.css
     origin=regular
     isInline=false
     hasSourceURL=false
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-import.css
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-import.css
     origin=regular
     isInline=false
     hasSourceURL=false
@@ -112,7 +112,7 @@
 Rule added
 === Removing iframe... ===
 Stylesheets removed:
-    URL=.../inspector/elements/styles/resources/stylesheet-tracking-iframe.html
+    URL=.../devtools/elements/styles/resources/stylesheet-tracking-iframe.html
     origin=regular
     isInline=true
     hasSourceURL=false
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/stylesheet-tracking.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/stylesheet-tracking.html
similarity index 97%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/stylesheet-tracking.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/stylesheet-tracking.html
index 4b970a7..c7dbc3b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/stylesheet-tracking.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/stylesheet-tracking.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../elements-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/elements-test.js"></script>
 <link rel="stylesheet" href="../styles/resources/stylesheet-tracking.css" />
 
 <style>
@@ -223,7 +223,7 @@
   function trimURL(url) {
     if (!url)
       return url;
-    var lastIndex = url.lastIndexOf('inspector/');
+    var lastIndex = url.lastIndexOf('devtools/');
     if (lastIndex < 0)
       return url;
     return '.../' + url.substr(lastIndex);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/xsl-transformed-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/xsl-transformed-expected.txt
similarity index 81%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/xsl-transformed-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/xsl-transformed-expected.txt
index 96eee71..1f6b9e7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/xsl-transformed-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/xsl-transformed-expected.txt
@@ -4,9 +4,9 @@
 - <html>
     - <head>
           <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-          <script src="../../inspector-test.js"></script>
-          <script src="../../elements-test.js"></script>
-          <script src="../../resources-test.js"></script>
+          <script src="../../../inspector/inspector-test.js"></script>
+          <script src="../../../inspector/elements-test.js"></script>
+          <script src="../../../inspector/resources-test.js"></script>
         - <script>
               function test()\n        {\n            ElementsTestRunner.expandElementsTree(step2);\n\n            function step2()\n            {\n                ElementsTestRunner.dumpElementsTree();\n                TestRunner.completeTest();\n            }\n        }\n
           </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/xsl-transformed.xml b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/xsl-transformed.xml
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/xsl-transformed.xml
rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/xsl-transformed.xml
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/cached-resource-metadata-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/cached-resource-metadata-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/cached-resource-metadata-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/cached-resource-metadata-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/cached-resource-metadata.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/cached-resource-metadata.html
similarity index 82%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/cached-resource-metadata.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/cached-resource-metadata.html
index bda9c23..a759b70 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/cached-resource-metadata.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/cached-resource-metadata.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../network-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/network-test.js"></script>
 <script>
 function addScript()
 {
@@ -24,7 +24,7 @@
 
 function test() {
   var resource = TestRunner.resourceTreeModel.resourceForURL(
-      'http://127.0.0.1:8000/inspector/resource-tree/resources/script-with-constant-last-modified.php');
+      'http://127.0.0.1:8000/devtools/resource-tree/resources/script-with-constant-last-modified.php');
   if (!resource) {
     TestRunner.addResult('ERROR: Failed to find resource.');
     TestRunner.completeTest();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/iframe-main-resource-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/iframe-main-resource-expected.txt
similarity index 63%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/iframe-main-resource-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/iframe-main-resource-expected.txt
index 1a437930..9fefb661 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/iframe-main-resource-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/iframe-main-resource-expected.txt
@@ -2,9 +2,9 @@
 
 
 Reported resources:
+  http://127.0.0.1:8000/devtools/resource-tree/iframe-main-resource.html
+  http://127.0.0.1:8000/devtools/resource-tree/resources/dummy-iframe.html
   http://127.0.0.1:8000/inspector/inspector-test.js
-  http://127.0.0.1:8000/inspector/resource-tree/iframe-main-resource.html
   http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-  http://127.0.0.1:8000/inspector/resource-tree/resources/dummy-iframe.html
   http://127.0.0.1:8000/inspector/resources-test.js
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/iframe-main-resource.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/iframe-main-resource.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/iframe-main-resource.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/iframe-main-resource.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-metadata-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-metadata-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-metadata-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-metadata-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-metadata.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-metadata.html
similarity index 81%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-metadata.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-metadata.html
index 6a46f76..06b5d561 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-metadata.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-metadata.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../network-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/network-test.js"></script>
 <script>
 function addScript()
 {
@@ -20,7 +20,7 @@
 
   function step2() {
     var resource = TestRunner.resourceTreeModel.resourceForURL(
-        'http://127.0.0.1:8000/inspector/resource-tree/resources/script-with-constant-last-modified.php');
+        'http://127.0.0.1:8000/devtools/resource-tree/resources/script-with-constant-last-modified.php');
     if (!resource) {
       TestRunner.addResult('ERROR: Failed to find resource.');
       TestRunner.completeTest();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-after-loading-and-clearing-cache-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-after-loading-and-clearing-cache-expected.txt
similarity index 75%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-after-loading-and-clearing-cache-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-after-loading-and-clearing-cache-expected.txt
index b8ebfc5..da28c3e0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-after-loading-and-clearing-cache-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-after-loading-and-clearing-cache-expected.txt
@@ -5,7 +5,7 @@
 Waiting for script request to finish: 
 Clearing memory cache: 
 Requesting content: 
-Resource url: http://127.0.0.1:8000/inspector/resource-tree/resources/dynamic-script.js
+Resource url: http://127.0.0.1:8000/devtools/resource-tree/resources/dynamic-script.js
 Resource content: function foo() {
 }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-after-loading-and-clearing-cache.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-after-loading-and-clearing-cache.html
similarity index 88%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-after-loading-and-clearing-cache.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-after-loading-and-clearing-cache.html
index 3a9288ca..89d40b0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-after-loading-and-clearing-cache.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-after-loading-and-clearing-cache.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 <link rel="stylesheet" href="resources/styles-initial.css">
 <script>
 function createScriptTag()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-while-loading-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-while-loading-expected.txt
similarity index 67%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-while-loading-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-while-loading-expected.txt
index 7e2c379..4fb2d7a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-while-loading-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-while-loading-expected.txt
@@ -1,7 +1,7 @@
 Tests resource content is correctly loaded if Resource.requestContent was called before network request was finished.
 
 Bug 90153
-Resource url: http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
+Resource url: http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
 Resource content: html {
     background-color: green;
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-while-loading.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-while-loading.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-while-loading.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-while-loading.html
index 32c2385..7158eaa 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-request-content-while-loading.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-request-content-while-loading.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 <script>
 function loadStylesheet()
 {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-crafted-frame-add-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-crafted-frame-add-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-crafted-frame-add-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-crafted-frame-add-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-crafted-frame-add.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.html
similarity index 79%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-crafted-frame-add.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.html
index b0b2a17..6cad85b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-crafted-frame-add.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 
 <script>
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-document-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-document-url-expected.txt
new file mode 100644
index 0000000..d981d73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-document-url-expected.txt
@@ -0,0 +1,9 @@
+Tests that resources have proper documentURL set in the tree model.
+
+
+http://127.0.0.1:8000/devtools/resource-tree/resource-tree-document-url.html => http://127.0.0.1:8000/devtools/resource-tree/resource-tree-document-url.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/dummy-iframe.html => http://127.0.0.1:8000/devtools/resource-tree/resources/dummy-iframe.html
+http://127.0.0.1:8000/inspector/inspector-test.js => http://127.0.0.1:8000/devtools/resource-tree/resource-tree-document-url.html
+http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js => http://127.0.0.1:8000/devtools/resource-tree/resource-tree-document-url.html
+http://127.0.0.1:8000/inspector/resources-test.js => http://127.0.0.1:8000/devtools/resource-tree/resource-tree-document-url.html
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-document-url.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-document-url.html
similarity index 84%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-document-url.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-document-url.html
index 7110e0c..92bffc9f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-document-url.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-document-url.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 
 <script>
 function loadIframe()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-events-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-events-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-events-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-events-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-events.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-events.html
similarity index 93%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-events.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-events.html
index 893c68b..52a3ce5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-events.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-events.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 
 <script>
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-add-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add-expected.txt
similarity index 68%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-add-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add-expected.txt
index 66bf1ab..68c226f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-add-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add-expected.txt
@@ -5,17 +5,17 @@
 Before addition
 ====================================
 Resources:
+document http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html
+stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
 script http://127.0.0.1:8000/inspector/inspector-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-add.html
 script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-stylesheet http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
 script http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources URL Map:
+http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html == http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
 http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-add.html == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-add.html
 http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
 http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources Tree:
@@ -49,11 +49,12 @@
 -------- Setting mode: [frame/domain/folder]
 top
   127.0.0.1:8000
+    devtools/resource-tree
+      resources
+        styles-initial.css
+      resource-tree-frame-add.html
     inspector
       resource-tree
-        resources
-          styles-initial.css
-        resource-tree-frame-add.html
         resource-tree-test.js
       inspector-test.js
       resources-test.js
@@ -68,11 +69,12 @@
 Sources:
 -------- Setting mode: [domain/folder]
 127.0.0.1:8000
+  devtools/resource-tree
+    resources
+      styles-initial.css
+    resource-tree-frame-add.html
   inspector
     resource-tree
-      resources
-        styles-initial.css
-      resource-tree-frame-add.html
       resource-tree-test.js
     inspector-test.js
     resources-test.js
@@ -80,23 +82,23 @@
 After addition
 ====================================
 Resources:
+document http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html
+document http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-add-iframe.html
+script http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js
+stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
+stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css
 script http://127.0.0.1:8000/inspector/inspector-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-add.html
 script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-add-iframe.html
-script http://127.0.0.1:8000/inspector/resource-tree/resources/script-navigated.js
-stylesheet http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
-stylesheet http://127.0.0.1:8000/inspector/resource-tree/resources/styles-navigated.css
 script http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources URL Map:
+http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html == http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-add-iframe.html == http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-add-iframe.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js == http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js
+http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
+http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css
 http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-add.html == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-add.html
 http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-add-iframe.html == http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-add-iframe.html
-http://127.0.0.1:8000/inspector/resource-tree/resources/script-navigated.js == http://127.0.0.1:8000/inspector/resource-tree/resources/script-navigated.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
-http://127.0.0.1:8000/inspector/resource-tree/resources/styles-navigated.css == http://127.0.0.1:8000/inspector/resource-tree/resources/styles-navigated.css
 http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources Tree:
@@ -145,17 +147,18 @@
 -------- Setting mode: [frame/domain/folder]
 top
   127.0.0.1:8000
+    devtools/resource-tree
+      resources
+        styles-initial.css
+      resource-tree-frame-add.html
     inspector
       resource-tree
-        resources
-          styles-initial.css
-        resource-tree-frame-add.html
         resource-tree-test.js
       inspector-test.js
       resources-test.js
   resource-tree-frame-add-iframe.html
     127.0.0.1:8000
-      inspector/resource-tree/resources
+      devtools/resource-tree/resources
         resource-tree-frame-add-iframe.html
         script-navigated.js
         styles-navigated.css
@@ -173,14 +176,15 @@
 Sources:
 -------- Setting mode: [domain/folder]
 127.0.0.1:8000
+  devtools/resource-tree
+    resources
+      resource-tree-frame-add-iframe.html
+      script-navigated.js
+      styles-initial.css
+      styles-navigated.css
+    resource-tree-frame-add.html
   inspector
     resource-tree
-      resources
-        resource-tree-frame-add-iframe.html
-        script-navigated.js
-        styles-initial.css
-        styles-navigated.css
-      resource-tree-frame-add.html
       resource-tree-test.js
     inspector-test.js
     resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-add.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add.html
similarity index 83%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-add.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add.html
index 1233c39..d161377 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-add.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 
 <link rel="stylesheet" href="resources/styles-initial.css">
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.html
index 83527a4..3f88e0d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-in-crafted-frame.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 
 <script>
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-navigate-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate-expected.txt
similarity index 64%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-navigate-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate-expected.txt
index 7e6f60f6..ef827ba 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-navigate-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate-expected.txt
@@ -5,23 +5,23 @@
 Before navigation
 ====================================
 Resources:
+document http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-navigate.html
+document http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html
+script http://127.0.0.1:8000/devtools/resource-tree/resources/script-initial.js
+stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial-2.css
+stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
 script http://127.0.0.1:8000/inspector/inspector-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-navigate.html
 script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html
-script http://127.0.0.1:8000/inspector/resource-tree/resources/script-initial.js
-stylesheet http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial-2.css
-stylesheet http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
 script http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources URL Map:
+http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-navigate.html == http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-navigate.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html == http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/script-initial.js == http://127.0.0.1:8000/devtools/resource-tree/resources/script-initial.js
+http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial-2.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial-2.css
+http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
 http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-navigate.html == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-navigate.html
 http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html == http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html
-http://127.0.0.1:8000/inspector/resource-tree/resources/script-initial.js == http://127.0.0.1:8000/inspector/resource-tree/resources/script-initial.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial-2.css == http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial-2.css
-http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
 http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources Tree:
@@ -70,17 +70,18 @@
 -------- Setting mode: [frame/domain/folder]
 top
   127.0.0.1:8000
+    devtools/resource-tree
+      resources
+        styles-initial.css
+      resource-tree-frame-navigate.html
     inspector
       resource-tree
-        resources
-          styles-initial.css
-        resource-tree-frame-navigate.html
         resource-tree-test.js
       inspector-test.js
       resources-test.js
   iframe (resource-tree-frame-navigate-iframe-before.html)
     127.0.0.1:8000
-      inspector/resource-tree/resources
+      devtools/resource-tree/resources
         resource-tree-frame-navigate-iframe-before.html
         script-initial.js
         styles-initial-2.css
@@ -98,14 +99,15 @@
 Sources:
 -------- Setting mode: [domain/folder]
 127.0.0.1:8000
+  devtools/resource-tree
+    resources
+      resource-tree-frame-navigate-iframe-before.html
+      script-initial.js
+      styles-initial-2.css
+      styles-initial.css
+    resource-tree-frame-navigate.html
   inspector
     resource-tree
-      resources
-        resource-tree-frame-navigate-iframe-before.html
-        script-initial.js
-        styles-initial-2.css
-        styles-initial.css
-      resource-tree-frame-navigate.html
       resource-tree-test.js
     inspector-test.js
     resources-test.js
@@ -113,23 +115,23 @@
 After navigation
 ====================================
 Resources:
+document http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-navigate.html
+document http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html
+script http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js
+stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
+stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css
 script http://127.0.0.1:8000/inspector/inspector-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-navigate.html
 script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html
-script http://127.0.0.1:8000/inspector/resource-tree/resources/script-navigated.js
-stylesheet http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
-stylesheet http://127.0.0.1:8000/inspector/resource-tree/resources/styles-navigated.css
 script http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources URL Map:
+http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-navigate.html == http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-navigate.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html == http://127.0.0.1:8000/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js == http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js
+http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
+http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css
 http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-navigate.html == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-frame-navigate.html
 http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html == http://127.0.0.1:8000/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html
-http://127.0.0.1:8000/inspector/resource-tree/resources/script-navigated.js == http://127.0.0.1:8000/inspector/resource-tree/resources/script-navigated.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
-http://127.0.0.1:8000/inspector/resource-tree/resources/styles-navigated.css == http://127.0.0.1:8000/inspector/resource-tree/resources/styles-navigated.css
 http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources Tree:
@@ -178,17 +180,18 @@
 -------- Setting mode: [frame/domain/folder]
 top
   127.0.0.1:8000
+    devtools/resource-tree
+      resources
+        styles-initial.css
+      resource-tree-frame-navigate.html
     inspector
       resource-tree
-        resources
-          styles-initial.css
-        resource-tree-frame-navigate.html
         resource-tree-test.js
       inspector-test.js
       resources-test.js
   iframe (resource-tree-frame-navigate-iframe-after.html)
     127.0.0.1:8000
-      inspector/resource-tree/resources
+      devtools/resource-tree/resources
         resource-tree-frame-navigate-iframe-after.html
         script-navigated.js
         styles-navigated.css
@@ -206,14 +209,15 @@
 Sources:
 -------- Setting mode: [domain/folder]
 127.0.0.1:8000
+  devtools/resource-tree
+    resources
+      resource-tree-frame-navigate-iframe-after.html
+      script-navigated.js
+      styles-initial.css
+      styles-navigated.css
+    resource-tree-frame-navigate.html
   inspector
     resource-tree
-      resources
-        resource-tree-frame-navigate-iframe-after.html
-        script-navigated.js
-        styles-initial.css
-        styles-navigated.css
-      resource-tree-frame-navigate.html
       resource-tree-test.js
     inspector-test.js
     resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-navigate.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-navigate.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate.html
index da07e44..33eaafd4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-frame-navigate.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 
 <link rel="stylesheet" href="resources/styles-initial.css">
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-htmlimports-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports-expected.txt
similarity index 64%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-htmlimports-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports-expected.txt
index f709981..0924bbf3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-htmlimports-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports-expected.txt
@@ -1,21 +1,21 @@
 Tests resource tree model for imports.
 
 Resources:
+document http://127.0.0.1:8000/devtools/resource-tree/resource-tree-htmlimports.html
+document http://127.0.0.1:8000/devtools/resource-tree/resources/import-child.html
+document http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.html
+script http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.js
 script http://127.0.0.1:8000/inspector/inspector-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resource-tree-htmlimports.html
 script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-document http://127.0.0.1:8000/inspector/resource-tree/resources/import-child.html
-document http://127.0.0.1:8000/inspector/resource-tree/resources/import-hello.html
-script http://127.0.0.1:8000/inspector/resource-tree/resources/import-hello.js
 script http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources URL Map:
+http://127.0.0.1:8000/devtools/resource-tree/resource-tree-htmlimports.html == http://127.0.0.1:8000/devtools/resource-tree/resource-tree-htmlimports.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/import-child.html == http://127.0.0.1:8000/devtools/resource-tree/resources/import-child.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.html == http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.html
+http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.js == http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.js
 http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resource-tree-htmlimports.html == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-htmlimports.html
 http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-http://127.0.0.1:8000/inspector/resource-tree/resources/import-child.html == http://127.0.0.1:8000/inspector/resource-tree/resources/import-child.html
-http://127.0.0.1:8000/inspector/resource-tree/resources/import-hello.html == http://127.0.0.1:8000/inspector/resource-tree/resources/import-hello.html
-http://127.0.0.1:8000/inspector/resource-tree/resources/import-hello.js == http://127.0.0.1:8000/inspector/resource-tree/resources/import-hello.js
 http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js
 
 Resources Tree:
@@ -54,13 +54,14 @@
 -------- Setting mode: [frame/domain/folder]
 top
   127.0.0.1:8000
+    devtools/resource-tree
+      resources
+        import-child.html
+        import-hello.html
+        import-hello.js
+      resource-tree-htmlimports.html
     inspector
       resource-tree
-        resources
-          import-child.html
-          import-hello.html
-          import-hello.js
-        resource-tree-htmlimports.html
         resource-tree-test.js
       inspector-test.js
       resources-test.js
@@ -77,13 +78,14 @@
 Sources:
 -------- Setting mode: [domain/folder]
 127.0.0.1:8000
+  devtools/resource-tree
+    resources
+      import-child.html
+      import-hello.html
+      import-hello.js
+    resource-tree-htmlimports.html
   inspector
     resource-tree
-      resources
-        import-child.html
-        import-hello.html
-        import-hello.js
-      resource-tree-htmlimports.html
       resource-tree-test.js
     inspector-test.js
     resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-htmlimports.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports.html
similarity index 74%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-htmlimports.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports.html
index fb727f0c..91cbacc 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-htmlimports.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports.html
@@ -4,9 +4,9 @@
 <link rel="import" href="resources/import-hello.html">
 <!-- import-hello.html shouldn't be shown twice as it shares same resource as above -->
 <link rel="import" href="resources/import-hello.html">
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 <script>
 
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-invalid-mime-type-css-content-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-invalid-mime-type-css-content-expected.txt
similarity index 66%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-invalid-mime-type-css-content-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-invalid-mime-type-css-content-expected.txt
index 8912051..e2d2780 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-invalid-mime-type-css-content-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-invalid-mime-type-css-content-expected.txt
@@ -1,7 +1,7 @@
 Tests that content is correctly shown for css loaded with invalid mime type in quirks mode.
 
 Bug 80528
-http://127.0.0.1:8000/inspector/resource-tree/resources/stylesheet-text-plain.php
+http://127.0.0.1:8000/devtools/resource-tree/resources/stylesheet-text-plain.php
 Resource.content: body {
     background-color: green:
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-invalid-mime-type-css-content.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-invalid-mime-type-css-content.html
similarity index 91%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-invalid-mime-type-css-content.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-invalid-mime-type-css-content.html
index 9b948767..21274cd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-invalid-mime-type-css-content.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-invalid-mime-type-css-content.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
 <link rel="stylesheet" href="resources/stylesheet-text-plain.php" type="text/css">
 <script>
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-no-xhrs-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-no-xhrs-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-no-xhrs-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-no-xhrs-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-no-xhrs.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-no-xhrs.html
similarity index 73%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-no-xhrs.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-no-xhrs.html
index 8e94413a..3a0f3c4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-no-xhrs.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-no-xhrs.html
@@ -1,14 +1,14 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../network-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/network-test.js"></script>
 <script>
 function test() {
   NetworkTestRunner.makeSimpleXHR('GET', 'resources/resource.php', false, step2);
 
   function step2() {
     var resource = TestRunner.resourceTreeModel.resourceForURL(
-        'http://127.0.0.1:8000/inspector/resource-tree/resources/resource.php');
+        'http://127.0.0.1:8000/devtools/resource-tree/resources/resource.php');
     TestRunner.assertTrue(!resource, 'XHR resource should not be added to resourceTreeModel.');
     TestRunner.completeTest();
   }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-non-unique-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url-expected.txt
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-non-unique-url-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url-expected.txt
index 1863f0be..8874372d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-non-unique-url-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url-expected.txt
@@ -41,15 +41,16 @@
 -------- Setting mode: [frame/domain/folder]
 top
   127.0.0.1:8000
+    devtools/resource-tree
+      resource-tree-non-unique-url.html
     inspector
       resource-tree
-        resource-tree-non-unique-url.html
         resource-tree-test.js
       inspector-test.js
       resources-test.js
   resource-tree-non-unique-url-iframe.html
     127.0.0.1:8000
-      inspector/resource-tree/resources
+      devtools/resource-tree/resources
         resource-tree-non-unique-url-iframe.html
         styles-non-unique-url.css
 Sources:
@@ -64,12 +65,13 @@
 Sources:
 -------- Setting mode: [domain/folder]
 127.0.0.1:8000
+  devtools/resource-tree
+    resources
+      resource-tree-non-unique-url-iframe.html
+      styles-non-unique-url.css
+    resource-tree-non-unique-url.html
   inspector
     resource-tree
-      resources
-        resource-tree-non-unique-url-iframe.html
-        styles-non-unique-url.css
-      resource-tree-non-unique-url.html
       resource-tree-test.js
     inspector-test.js
     resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-non-unique-url.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url.html
similarity index 81%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-non-unique-url.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url.html
index f7e9805..f188eb7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-non-unique-url.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 <script>
 function loadIframe()
 {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-reload-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-reload-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-reload-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-reload-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-reload.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-reload.html
similarity index 83%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-reload.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-reload.html
index c4c43e49..b73ccb7e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-reload.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-reload.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="resource-tree-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/resource-tree/resource-tree-test.js"></script>
 
 <link rel="stylesheet" href="resources/styles-initial.css">
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/dummy-iframe.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/dummy-iframe.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/dummy-iframe.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/dummy-iframe.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/dynamic-script.js b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/dynamic-script.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/dynamic-script.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/dynamic-script.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/empty.png b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/empty.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/empty.png
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/empty.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/import-child.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/import-child.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/import-child.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/import-child.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/import-hello.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/import-hello.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/import-hello.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/import-hello.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/import-hello.js b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/import-hello.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/import-hello.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/import-hello.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-frame-add-iframe.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-frame-add-iframe.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-frame-add-iframe.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-frame-add-iframe.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-after.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-frame-navigate-iframe-before.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-non-unique-url-iframe.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-non-unique-url-iframe.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-non-unique-url-iframe.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-non-unique-url-iframe.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-reload-iframe.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-reload-iframe.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/resource-tree-reload-iframe.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/resource-tree-reload-iframe.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/script-initial.js b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/script-initial.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/script-initial.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/script-initial.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/script-navigated.js b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/script-navigated.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/script-navigated.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/script-navigated.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/script-with-constant-last-modified.php b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/script-with-constant-last-modified.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/script-with-constant-last-modified.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/script-with-constant-last-modified.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-initial-2.css b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-initial-2.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-initial-2.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-initial-2.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-initial.css b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-initial.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-initial.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-initial.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-navigated.css b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-navigated.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-navigated.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-navigated.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-non-unique-url.css b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-non-unique-url.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/styles-non-unique-url.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/styles-non-unique-url.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/stylesheet-text-plain.php b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/stylesheet-text-plain.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resources/stylesheet-text-plain.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resources/stylesheet-text-plain.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resources/imported-document-2.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resources/imported-document-2.html
new file mode 100644
index 0000000..87d9de76
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resources/imported-document-2.html
@@ -0,0 +1,15 @@
+<div class="warning">
+  <style scoped>
+    h3 {
+      color: red;
+    }
+  </style>
+  <h3>Warning!</h3>
+  <p>This page is under construction</p>
+</div>
+
+<div class="outdated">
+  <h3>Heads up!</h3>
+  <p>This content may be out of date</p>
+</div>
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resources/imported-document.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resources/imported-document.html
new file mode 100644
index 0000000..045e208
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resources/imported-document.html
@@ -0,0 +1,7 @@
+<head>
+<link rel="import" href="imported-document.html">
+<link rel="import" href="imported-document-2.html">
+</head>
+<div class="first-level">
+</div>
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/pink.jpg b/third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/pink.jpg
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/pink.jpg
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/pink.jpg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search-concatenated.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search-concatenated.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search-concatenated.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search-concatenated.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search.css b/third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search.js b/third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/search.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/resources/search.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-ignore-binary-files-expected.txt
similarity index 63%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-ignore-binary-files-expected.txt
index 1e83af9..6c025576 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-ignore-binary-files-expected.txt
@@ -1,6 +1,6 @@
 Verify that search doesn't search in binary resources.
 
 
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/search-ignore-binary-files.html
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/search-ignore-binary-files.html
   search match #1: lineNumber = 12, lineContent = '    var searchConfig = new Workspace.SearchConfig('AAAAAAA', true, false);'
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-ignore-binary-files.html
similarity index 75%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-ignore-binary-files.html
index 67711d04..d19221c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-ignore-binary-files.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-non-existing-resource-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-non-existing-resource-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-non-existing-resource-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-non-existing-resource-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-non-existing-resource.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-non-existing-resource.html
similarity index 72%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-non-existing-resource.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-non-existing-resource.html
index 94b645d..479a02fc 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-non-existing-resource.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-non-existing-resource.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 function test() {
   // This file should not match search query.
@@ -11,8 +11,8 @@
   ApplicationTestRunner.runAfterResourcesAreFinished(['search.js'], step2);
 
   async function step2() {
-    var resource = Bindings.resourceForURL('http://127.0.0.1:8000/inspector/search/resources/search.js');
-    var url = 'http://127.0.0.1:8000/inspector/search/resources/non-existing.js';
+    var resource = Bindings.resourceForURL('http://127.0.0.1:8000/devtools/search/resources/search.js');
+    var url = 'http://127.0.0.1:8000/devtools/search/resources/non-existing.js';
     var response = await TestRunner.PageAgent.invoke_searchInResource({frameId: resource.frameId, url, query: text});
     TestRunner.addResult(response[Protocol.Error]);
     TestRunner.completeTest();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-resource-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-resource-expected.txt
similarity index 95%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-resource-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-resource-expected.txt
index ba4532bf..f4332df 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-resource-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-resource-expected.txt
@@ -1,7 +1,7 @@
 Tests single resource search in inspector page agent.
 
 Bug 68998  
-http://127.0.0.1:8000/inspector/search/resources/search.js
+http://127.0.0.1:8000/devtools/search/resources/search.js
 Search matches: 
 lineNumber: 0, line: 'function searchTestUniqueString()'
 lineNumber: 3, line: '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-resource.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-resource.html
similarity index 81%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-resource.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-resource.html
index 0b651842..35d509a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-resource.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-resource.html
@@ -1,15 +1,15 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 function test() {
   ApplicationTestRunner.runAfterResourcesAreFinished(['search.js'], step2);
   var resource;
 
   async function step2() {
-    resource = Bindings.resourceForURL('http://127.0.0.1:8000/inspector/search/resources/search.js');
+    resource = Bindings.resourceForURL('http://127.0.0.1:8000/devtools/search/resources/search.js');
     TestRunner.addResult(resource.url);
 
     // This file should not match search query.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-script-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-script-expected.txt
similarity index 95%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-script-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-script-expected.txt
index 3d16b58..3e983fdb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-script-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-script-expected.txt
@@ -1,7 +1,7 @@
 Tests script search in inspector debugger agent.
 
 Bug 69015  
-http://127.0.0.1:8000/inspector/search/resources/search.js
+http://127.0.0.1:8000/devtools/search/resources/search.js
 Search matches: 
 lineNumber: 0, line: 'function searchTestUniqueString()'
 lineNumber: 3, line: '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-script.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-script.html
similarity index 83%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-script.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-script.html
index 48ff99d..e17ca66 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-script.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-script.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 function test() {
   SourcesTestRunner.startDebuggerTest(step1);
@@ -18,7 +18,7 @@
   }
 
   async function step3() {
-    var url = 'http://127.0.0.1:8000/inspector/search/resources/search.js';
+    var url = 'http://127.0.0.1:8000/devtools/search/resources/search.js';
     var scripts = SourcesTestRunner.queryScripts(function(s) {
       return s.sourceURL === url;
     });
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-static-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-static-expected.txt
similarity index 95%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-static-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-static-expected.txt
index 615eac2..ad6299e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-static-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-static-expected.txt
@@ -1,7 +1,7 @@
 Tests static content provider search.
 
 Bug 70354  
-http://127.0.0.1:8000/inspector/search/resources/search.js
+http://127.0.0.1:8000/devtools/search/resources/search.js
 Search matches: 
 lineNumber: 0, line: 'function searchTestUniqueString()'
 lineNumber: 3, line: '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-static.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-static.html
similarity index 83%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-static.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-static.html
index 5994347..8f90afb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-in-static.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/search-in-static.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 function test() {
   ApplicationTestRunner.runAfterResourcesAreFinished(['search.js'], step2);
@@ -10,7 +10,7 @@
   var staticContentProvider;
 
   function step2() {
-    resource = Bindings.resourceForURL('http://127.0.0.1:8000/inspector/search/resources/search.js');
+    resource = Bindings.resourceForURL('http://127.0.0.1:8000/devtools/search/resources/search.js');
     resource.requestContent().then(step3);
   }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-1-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-1-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-1-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-1-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-1.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-1.html
similarity index 76%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-1.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-1.html
index 460a1e5..0cfed1c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-1.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-1.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="../sources-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/sources-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script src="resources/search.js"></script>
 <script>
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-2-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-2-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-2-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-2-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-2.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-2.html
similarity index 76%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-2.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-2.html
index bc5619a..5bb7ce4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-2.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-2.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="../sources-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/sources-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script src="resources/search.js"></script>
 <script>
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-3-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-3-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-3-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-3-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-3.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-3.html
similarity index 76%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-3.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-3.html
index 7325c96..88c3eb4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-3.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-3.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="../sources-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/sources-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script src="resources/search.js"></script>
 <script>
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-4-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-4-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-4-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-4-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-4.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-4.html
similarity index 76%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-4.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-4.html
index e8f92f1..9da73f0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-replace-4.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-replace-4.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="../sources-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/sources-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script src="resources/search.js"></script>
 <script>
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-search-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-search-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-search.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-search.html
index 5bc432d..e8592b1d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/source-frame-search.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="../sources-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/sources-test.js"></script>
 <script src="resources/search.js"></script>
 <script>
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-expected.txt
similarity index 79%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-expected.txt
index 350ba2a6..95115df 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-expected.txt
@@ -1,16 +1,16 @@
 
 
 Running: testIgnoreCaseAndIgnoreDynamicScript
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.css
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.css
   search match #1: lineNumber = 0, lineContent = 'div.searchTestUniqueString {'
   search match #2: lineNumber = 4, lineContent = 'div.searchTestUniqueString:hover {'
   search match #3: lineNumber = 5, lineContent = '    /* another searchTestUniqueString occurence */'
-Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #2: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
   search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>'
-Search result #3: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #3: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString()'
   search match #2: lineNumber = 3, lineContent = '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
   search match #3: lineNumber = 4, lineContent = '    // searchTestUniqueString on the next line.'
@@ -20,16 +20,16 @@
 Running: testIgnoreCase
 Search result #1: uiSourceCode.url = debugger:///VMXX
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString() {}'
-Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.css
+Search result #2: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.css
   search match #1: lineNumber = 0, lineContent = 'div.searchTestUniqueString {'
   search match #2: lineNumber = 4, lineContent = 'div.searchTestUniqueString:hover {'
   search match #3: lineNumber = 5, lineContent = '    /* another searchTestUniqueString occurence */'
-Search result #3: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #3: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
   search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>'
-Search result #4: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #4: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString()'
   search match #2: lineNumber = 3, lineContent = '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
   search match #3: lineNumber = 4, lineContent = '    // searchTestUniqueString on the next line.'
@@ -39,30 +39,30 @@
 Running: testCaseSensitive
 Search result #1: uiSourceCode.url = debugger:///VMXX
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString() {}'
-Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.css
+Search result #2: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.css
   search match #1: lineNumber = 0, lineContent = 'div.searchTestUniqueString {'
   search match #2: lineNumber = 4, lineContent = 'div.searchTestUniqueString:hover {'
   search match #3: lineNumber = 5, lineContent = '    /* another searchTestUniqueString occurence */'
-Search result #3: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #3: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
   search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>'
-Search result #4: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #4: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString()'
   search match #2: lineNumber = 3, lineContent = '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
   search match #3: lineNumber = 4, lineContent = '    // searchTestUniqueString on the next line.'
   search match #4: lineNumber = 10, lineContent = '    searchTestUniqueString();'
 
 Running: testFileHTML
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
   search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>'
 
 Running: testFileJS
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString()'
   search match #2: lineNumber = 3, lineContent = '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
   search match #3: lineNumber = 4, lineContent = '    // searchTestUniqueString on the next line.'
@@ -72,25 +72,25 @@
 Running: testFileHTMLJS
 
 Running: testSpaceQueries
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.css
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.css
   search match #1: lineNumber = 9, lineContent = '/* searchTestUnique space String */'
-Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #2: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 14, lineContent = '<!-- searchTestUnique space String -->'
-Search result #3: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #3: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 14, lineContent = '// searchTestUnique space String'
 
 Running: testSpaceQueriesFileHTML
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 14, lineContent = '<!-- searchTestUnique space String -->'
 
 Running: testSpaceQueriesFileHTML_SEARCH
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 14, lineContent = '<!-- searchTestUnique space String -->'
 
 Running: testSpaceQueriesFileJS_SEARCH_HTML
 
 Running: testSeveralQueriesFileHTML
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
@@ -98,7 +98,7 @@
   search match #5: lineNumber = 14, lineContent = '<!-- searchTestUnique space String -->'
 
 Running: testSeveralQueriesFileHTML_SEARCH
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
@@ -108,13 +108,13 @@
 Running: testSeveralQueriesFileJS_SEARCH_HTML
 
 Running: testSeveralQueriesFileNotCSS
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
   search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>'
   search match #5: lineNumber = 14, lineContent = '<!-- searchTestUnique space String -->'
-Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #2: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString()'
   search match #2: lineNumber = 3, lineContent = '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
   search match #3: lineNumber = 4, lineContent = '    // searchTestUniqueString on the next line.'
@@ -124,18 +124,18 @@
 
 Running: testFileQueryWithProjectName
 Running a file query with existing project name first:
-Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.css
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.css
   search match #1: lineNumber = 0, lineContent = 'div.searchTestUniqueString {'
   search match #2: lineNumber = 4, lineContent = 'div.searchTestUniqueString:hover {'
   search match #3: lineNumber = 5, lineContent = '    /* another searchTestUniqueString occurence */'
   search match #4: lineNumber = 9, lineContent = '/* searchTestUnique space String */'
-Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #2: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
   search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>'
   search match #5: lineNumber = 14, lineContent = '<!-- searchTestUnique space String -->'
-Search result #3: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #3: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString()'
   search match #2: lineNumber = 3, lineContent = '    // searchTestUniqueString two occurences on the same line searchTestUniqueString'
   search match #3: lineNumber = 4, lineContent = '    // searchTestUniqueString on the next line.'
@@ -147,15 +147,15 @@
 Running: testDirtyFiles
 Search result #1: uiSourceCode.url = debugger:///VMXX
   search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString() {}'
-Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.css
+Search result #2: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.css
   search match #1: lineNumber = 0, lineContent = 'div.searchTestUniqueString {'
   search match #2: lineNumber = 4, lineContent = 'div.searchTestUniqueString:hover {'
   search match #3: lineNumber = 5, lineContent = '    /* another searchTestUniqueString occurence */'
-Search result #3: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html
+Search result #3: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.html
   search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>'
   search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>'
   search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->'
   search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>'
-Search result #4: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js
+Search result #4: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/resources/search.js
   search match #1: lineNumber = 0, lineContent = 'FOO searchTestUniqueString BAR'
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-in-files-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-in-files-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-in-files.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-in-files.html
index 57d8cdaf..12654e0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-in-files.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-in-files.html
@@ -1,10 +1,10 @@
 <html>
 <head>
 <title>Test search in sources.</title>
-<script src="../inspector-test.js"></script>
-<script src="../isolated-filesystem-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/isolated-filesystem-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 function test() {
   function fileSystemUISourceCodes() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-many-projects-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-many-projects-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-many-projects-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-many-projects-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-many-projects.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-many-projects.html
similarity index 93%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-many-projects.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-many-projects.html
index b5bf4a86..30bb609 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-many-projects.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope-many-projects.html
@@ -1,10 +1,10 @@
 <html>
 <head>
 <title>Test search in sources.</title>
-<script src="../inspector-test.js"></script>
-<script src="../isolated-filesystem-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/isolated-filesystem-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 function test() {
   function fileSystemUISourceCodes() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope.html b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope.html
similarity index 98%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope.html
index c5bd691..3fd6e8e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/search/sources-search-scope.html
@@ -5,7 +5,7 @@
 <script src="../../inspector/resources-test.js"></script>
 <script src="../../inspector/network-test.js"></script>
 <script src="../../inspector/debugger-test.js"></script>
-<script src="./search-test.js"></script>
+<script src="../../inspector/search/search-test.js"></script>
 <script>
 function test() {
   UI.viewManager.showView('sources.search');
@@ -192,7 +192,7 @@
 </script>
 </head>
 <body onload="runTest()">
-<iframe src="../../inspector/search/resources/search.html">
+<iframe src="resources/search.html">
 <p>Tests that ScriptSearchScope performs search across all sources correctly.</p>
 See <a href="https://bugs.webkit.org/show_bug.cgi?id=41350">bug 41350</a>.
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/blank-origins-not-shown-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/blank-origins-not-shown-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/blank-origins-not-shown-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/blank-origins-not-shown-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/blank-origins-not-shown.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/blank-origins-not-shown.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/blank-origins-not-shown.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/blank-origins-not-shown.html
index 9321160..a75d708 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/blank-origins-not-shown.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/blank-origins-not-shown.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   var request1 = new SDK.NetworkRequest(0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/blocked-mixed-content-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/blocked-mixed-content-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/blocked-mixed-content-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/blocked-mixed-content-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/blocked-mixed-content.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/blocked-mixed-content.html
similarity index 92%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/blocked-mixed-content.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/blocked-mixed-content.html
index e36ee1ba..086f459 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/blocked-mixed-content.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/blocked-mixed-content.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   /** @type {!Protocol.Security.InsecureContentStatus} */
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/failed-request-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/failed-request-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/failed-request-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/failed-request-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/failed-request.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/failed-request.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/failed-request.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/failed-request.html
index 42c0e41b1..b71707c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/failed-request.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/failed-request.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   var request1 = new SDK.NetworkRequest(0, 'https://foo.test/foo.jpg', 'https://foo.test', 0, 0, null);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/interstitial-sidebar-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/interstitial-sidebar-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/interstitial-sidebar.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/interstitial-sidebar.html
index 93bb2ca..792a057 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/interstitial-sidebar.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   var request1 = new SDK.NetworkRequest(0, 'https://foo.test/', 'https://foo.test', 0, 0, null);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/main-origin-assigned-despite-request-missing-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/main-origin-assigned-despite-request-missing-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/main-origin-assigned-despite-request-missing-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/main-origin-assigned-despite-request-missing-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/main-origin-assigned-despite-request-missing.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/main-origin-assigned-despite-request-missing.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/main-origin-assigned-despite-request-missing.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/main-origin-assigned-despite-request-missing.html
index ab8ff92..18cbae5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/main-origin-assigned-despite-request-missing.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/main-origin-assigned-despite-request-missing.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
   function test() {
   //** @type {!Protocol.Security.InsecureContentStatus} */
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-active-and-passive-reload-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-active-and-passive-reload-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-active-and-passive-reload-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-active-and-passive-reload-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-active-and-passive-reload.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-active-and-passive-reload.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-active-and-passive-reload.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-active-and-passive-reload.html
index 7c850024..e34a374 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-active-and-passive-reload.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-active-and-passive-reload.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   /** @type {!Protocol.Security.InsecureContentStatus} */
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-reload-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-reload-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-reload-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-reload-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-reload.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-reload.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-reload.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-reload.html
index 5d402d50..1a4f67e9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/mixed-content-reload.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/mixed-content-reload.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   /** @type {!Protocol.Security.InsecureContentStatus} */
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-group-names-unique-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-group-names-unique-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-group-names-unique-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-group-names-unique-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-group-names-unique.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-group-names-unique.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-group-names-unique.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-group-names-unique.html
index 1f047ab..c09c14c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-group-names-unique.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-group-names-unique.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   var originGroupNameSize = Object.keys(Security.SecurityPanelSidebarTree.OriginGroupName).length;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-view-then-interstitial-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-view-then-interstitial-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-view-then-interstitial-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-view-then-interstitial-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-view-then-interstitial.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-view-then-interstitial.html
similarity index 91%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-view-then-interstitial.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-view-then-interstitial.html
index 32cc6c0..074b0c2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/origin-view-then-interstitial.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/origin-view-then-interstitial.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   var request1 = new SDK.NetworkRequest(0, 'https://foo.test/', 'https://foo.test', 0, 0, null);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-blocked-mixed-content-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-blocked-mixed-content-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-blocked-mixed-content-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-blocked-mixed-content-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-blocked-mixed-content.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-blocked-mixed-content.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-blocked-mixed-content.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-blocked-mixed-content.html
index 9ed8e81..46c31c91 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-blocked-mixed-content.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-blocked-mixed-content.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   /** @type {!Protocol.Security.InsecureContentStatus} */
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-details-updated-with-security-state-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-details-updated-with-security-state-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-details-updated-with-security-state-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-details-updated-with-security-state-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-details-updated-with-security-state.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-details-updated-with-security-state.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-details-updated-with-security-state.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-details-updated-with-security-state.html
index 9712764..54163c7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-details-updated-with-security-state.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-details-updated-with-security-state.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   // Add a request without security details.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-explanation-ordering-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-explanation-ordering-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-explanation-ordering-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-explanation-ordering-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-explanation-ordering.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-explanation-ordering.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-explanation-ordering.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-explanation-ordering.html
index 3a4e26b..1802274 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-explanation-ordering.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-explanation-ordering.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   /** @type {!Protocol.Security.InsecureContentStatus} */
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-state-comparator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-state-comparator-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-state-comparator-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-state-comparator-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-state-comparator.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-state-comparator.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-state-comparator.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-state-comparator.html
index 63c36f4..6c88c1b8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-state-comparator.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-state-comparator.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
 <!-- Since we are testing a static function, we can save work by not (pre)loading the Security panel. -->
 <script>
 function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-summary-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-summary-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-summary-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-summary-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-summary.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-summary.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-summary.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-summary.html
index 2f5f6ed..78a717b5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-summary.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-summary.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   /** @type {!Protocol.Security.InsecureContentStatus} */
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-unknown-resource-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-unknown-resource-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-unknown-resource-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-unknown-resource-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-unknown-resource.html b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-unknown-resource.html
similarity index 79%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/security/security-unknown-resource.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/security/security-unknown-resource.html
index c450004..4ce87c1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/security/security-unknown-resource.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/security/security-unknown-resource.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../security-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/security-test.js"></script>
 <script>
 function test() {
   var request = new SDK.NetworkRequest(0, 'http://unknown', 'https://foo.test', 0, 0, null);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/lazy-addeventlisteners-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/lazy-addeventlisteners-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/lazy-addeventlisteners.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/lazy-addeventlisteners.html
new file mode 100644
index 0000000..0a55360
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/lazy-addeventlisteners.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/console-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script>
+function test() {
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-lazy-addeventlistener.js';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/lazy-scope';
+  ConsoleTestRunner.waitForConsoleMessages(1, () => {
+    ConsoleTestRunner.dumpConsoleMessages();
+    TestRunner.completeTest();
+  });
+  ApplicationTestRunner.registerServiceWorker(scriptURL, scope);
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests that a warning is shown in the console if addEventListener is called after initial evaluation of the service worker script.</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/bypass-for-network-redirect.php b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/bypass-for-network-redirect.php
new file mode 100644
index 0000000..5b80a62
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/bypass-for-network-redirect.php
@@ -0,0 +1,5 @@
+<?php
+  $url = "http://127.0.0.1:8000/devtools/service-workers/resources/" .
+         "bypass-for-network-redirected.html";
+  header("Location: $url");
+?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirected.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/bypass-for-network-redirected.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirected.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/bypass-for-network-redirected.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/changing-worker.php b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/changing-worker.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/changing-worker.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/changing-worker.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/force-update-on-page-load-worker.php b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/force-update-on-page-load-worker.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/force-update-on-page-load-worker.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/force-update-on-page-load-worker.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/navigation-preload-redirected.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/navigation-preload-redirected.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/navigation-preload-redirected.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/navigation-preload-redirected.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/navigation-preload-scope.php b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/navigation-preload-scope.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/navigation-preload-scope.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/navigation-preload-scope.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/navigation-preload-worker.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/navigation-preload-worker.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/navigation-preload-worker.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/navigation-preload-worker.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/network-fetch-worker.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/network-fetch-worker.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/network-fetch-worker.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/network-fetch-worker.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/service-worker-debugger.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/service-worker-debugger.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/service-worker-debugger.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/service-worker-debugger.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/service-worker-empty.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/service-worker-empty.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/service-worker-empty.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/service-worker-empty.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/service-worker-lazy-addeventlistener.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/service-worker-lazy-addeventlistener.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/service-worker-lazy-addeventlistener.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/service-worker-lazy-addeventlistener.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/user-agent-override-worker.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/user-agent-override-worker.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/user-agent-override-worker.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/resources/user-agent-override-worker.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-agents-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-agents-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-agents-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-agents-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-agents.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-agents.html
similarity index 83%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-agents.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-agents.html
index 378debb1..cb385427 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-agents.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-agents.html
@@ -1,12 +1,12 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
 <script>
 
 function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-empty.js';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/scope1/';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-empty.js';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/scope1/';
 
   TestRunner.addSniffer(SDK.MainConnection.prototype, 'sendMessage', function(messageString) {
     var message = JSON.parse(messageString);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-manager-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-manager-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-manager-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-manager-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-manager.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-manager.html
similarity index 78%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-manager.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-manager.html
index c8a5a05..99aa9b4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-manager.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-manager.html
@@ -1,12 +1,12 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
 <script>
 
 function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-empty.js';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/scope1/';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-empty.js';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/scope1/';
   ApplicationTestRunner.registerServiceWorker(scriptURL, scope);
 
   SDK.targetManager.observeTargets({
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-blocked-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-blocked-expected.txt
new file mode 100644
index 0000000..e335206
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-blocked-expected.txt
@@ -0,0 +1,10 @@
+Tests blocking fetch in Service Workers.
+
+Fetch in worker result: FETCH_FAILED
+http://127.0.0.1:8000/devtools/service-workers/resources/network-fetch-worker.js
+resource.type: other
+request.failed: false
+http://127.0.0.1:8000/devtools/network/resources/resource.php
+resource.type: other
+request.failed: true
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-blocked.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-blocked.html
similarity index 68%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-blocked.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-blocked.html
index 7263908..843a2a2b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-blocked.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-blocked.html
@@ -1,14 +1,14 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="../console-test.js"></script>
-<script src="../network-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/console-test.js"></script>
+<script src="../../inspector/network-test.js"></script>
 <script>
 
 function test() {
-  let scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/network-fetch-worker-blocked-scope';
+  let scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/network-fetch-worker-blocked-scope';
 
   NetworkTestRunner.recordNetwork();
   SDK.multitargetNetworkManager.setBlockingEnabled(true);
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-expected.txt
new file mode 100644
index 0000000..92b7012f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch-expected.txt
@@ -0,0 +1,10 @@
+Tests fetch in Service Workers.
+
+Fetch in worker result: Hello world
+http://127.0.0.1:8000/devtools/service-workers/resources/network-fetch-worker.js
+resource.type: other
+request.failed: false
+http://127.0.0.1:8000/devtools/network/resources/resource.php
+resource.type: fetch
+request.failed: false
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch.html
similarity index 63%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch.html
index 448a53e0..e773f88 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-network-fetch.html
@@ -1,14 +1,14 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="../console-test.js"></script>
-<script src="../network-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/console-test.js"></script>
+<script src="../../inspector/network-test.js"></script>
 <script>
 
 function test() {
-  let scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/network-fetch-worker-scope';
+  let scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/network-fetch-worker-scope';
 
   NetworkTestRunner.recordNetwork();
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-pause-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-pause-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-pause-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-pause-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-pause.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-pause.html
new file mode 100644
index 0000000..d807e94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-pause.html
@@ -0,0 +1,30 @@
+<html>
+<head>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script>
+
+function test() {
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-debugger.js';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/scope-debugger/';
+
+  SourcesTestRunner.startDebuggerTest(start);
+
+  function start() {
+    SourcesTestRunner.waitUntilPaused(onPaused);
+    ApplicationTestRunner.registerServiceWorker(scriptURL, scope);
+  }
+
+  function onPaused(frames, reason, breakpointIds, async) {
+    SourcesTestRunner.captureStackTrace(frames, async);
+    SourcesTestRunner.completeDebuggerTest();
+  }
+}
+
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests that we can pause in service worker.</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.html
similarity index 80%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.html
index bb14829..be963f5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.html
@@ -1,14 +1,14 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script src="../resources-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
 <script>
 
 function loadIframe()
 {
     var frame = document.createElement('iframe');
-    frame.src = "http://localhost:8000/inspector/service-workers/resources/" +
+    frame.src = "http://localhost:8000/devtools/service-workers/resources/" +
                 "bypass-for-network-redirect.php"
     document.body.appendChild(frame);
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.html
index 0113804..77be9ff 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script src="../resources-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
 <script>
 
 function loadIframe(url)
@@ -17,8 +17,8 @@
 }
 
 function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/force-update-on-page-load-worker.php';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-force-update-on-page-load/';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/force-update-on-page-load-worker.php';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-force-update-on-page-load/';
 
   function waitForWorkerActivated(scope) {
     return new Promise(function(resolve) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-navigation-preload-expected.txt
similarity index 72%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-navigation-preload-expected.txt
index 2ee62a6..02ee441 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-navigation-preload-expected.txt
@@ -4,7 +4,7 @@
 -----------------
 Loading an iframe.
 onRequestStarted:
-  url: http://127.0.0.1:8000/inspector/service-workers/resources/navigation-preload-scope.php
+  url: http://127.0.0.1:8000/devtools/service-workers/resources/navigation-preload-scope.php
 onResponseReceived:
   statusCode: 200
   timing available: true
@@ -14,7 +14,7 @@
 -----------------
 Loading another iframe.
 onRequestStarted:
-  url: http://127.0.0.1:8000/inspector/service-workers/resources/navigation-preload-scope.php?BrokenChunked
+  url: http://127.0.0.1:8000/devtools/service-workers/resources/navigation-preload-scope.php?BrokenChunked
 onResponseReceived:
   statusCode: 200
   timing available: true
@@ -25,7 +25,7 @@
 -----------------
 Loading another iframe.
 onRequestStarted:
-  url: http://127.0.0.1:8000/inspector/service-workers/resources/navigation-preload-scope.php?Redirect
+  url: http://127.0.0.1:8000/devtools/service-workers/resources/navigation-preload-scope.php?Redirect
 onResponseReceived:
   statusCode: 302
   timing available: true
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-navigation-preload.html
similarity index 91%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-navigation-preload.html
index 7636562..b21a5db 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-navigation-preload.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
 <script>
 
 function initializeServiceWorker(script, scope) {
@@ -34,8 +34,8 @@
 }
 
 function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/navigation-preload-worker.js';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/navigation-preload-scope.php';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/navigation-preload-worker.js';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/navigation-preload-scope.php';
   var preloadRequestIDs = {};
 
   function onRequestStarted(event) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-redundant-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-redundant-expected.txt
similarity index 73%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-redundant-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-redundant-expected.txt
index 9a63dc4..6dfffe3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-redundant-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-redundant-expected.txt
@@ -2,7 +2,7 @@
 
 The first ServiceWorker is activated.
 ==== ServiceWorkersView ====
-127.0.0.1/inspector/service-workers/resources/service-worker-redundant-scope
+127.0.0.1/devtools/service-workers/resources/service-worker-redundant-scope
 Update
 Push
 Sync
@@ -21,7 +21,7 @@
 ============================
 The second Serviceworker is installed.
 ==== ServiceWorkersView ====
-127.0.0.1/inspector/service-workers/resources/service-worker-redundant-scope
+127.0.0.1/devtools/service-workers/resources/service-worker-redundant-scope
 Update
 Push
 Sync
@@ -36,7 +36,7 @@
 skipWaiting
 Received
 Clients
-http://127.0.0.1:8000/inspector/service-workers/service-workers-redundant.html
+http://127.0.0.1:8000/devtools/service-workers/service-workers-redundant.html
 focus
 Errors
 0
@@ -45,7 +45,7 @@
 ============================
 The first ServiceWorker worker became redundant and stopped.
 ==== ServiceWorkersView ====
-127.0.0.1/inspector/service-workers/resources/service-worker-redundant-scope
+127.0.0.1/devtools/service-workers/resources/service-worker-redundant-scope
 Update
 Push
 Sync
@@ -64,7 +64,7 @@
 ============================
 DevTools frontend is reopened.
 ==== ServiceWorkersView ====
-127.0.0.1/inspector/service-workers/resources/service-worker-redundant-scope
+127.0.0.1/devtools/service-workers/resources/service-worker-redundant-scope
 Update
 Push
 Sync
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-redundant.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-redundant.html
similarity index 87%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-redundant.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-redundant.html
index 8d191a7..d48f401 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-redundant.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-redundant.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="../console-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/console-test.js"></script>
 <script>
 
 var iframe;
@@ -21,8 +21,8 @@
 }
 
 function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/changing-worker.php';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-redundant-scope/';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/changing-worker.php';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-redundant-scope/';
   var step = 0;
   var firstVersionId = -1;
   var secondVersionId = -1;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-view-expected.txt
similarity index 75%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-view-expected.txt
index f9628fa..a1ec8e0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-view-expected.txt
@@ -2,7 +2,7 @@
 
 Select ServiceWorkers tree element.
 Register ServiceWorker for scope1
-127.0.0.1/inspector/service-workers/resources/scope1
+127.0.0.1/devtools/service-workers/resources/scope1
 Update
 Push
 Sync
@@ -19,7 +19,7 @@
 details
 clear
 Register ServiceWorker for scope2
-127.0.0.1/inspector/service-workers/resources/scope1
+127.0.0.1/devtools/service-workers/resources/scope1
 Update
 Push
 Sync
@@ -35,7 +35,7 @@
 0
 details
 clear
-127.0.0.1/inspector/service-workers/resources/scope2
+127.0.0.1/devtools/service-workers/resources/scope2
 Update
 Push
 Sync
@@ -52,7 +52,7 @@
 details
 clear
 Unegister ServiceWorker for scope1
-127.0.0.1/inspector/service-workers/resources/scope1 - deleted
+127.0.0.1/devtools/service-workers/resources/scope1 - deleted
 Update
 Push
 Sync
@@ -64,7 +64,7 @@
 0
 details
 clear
-127.0.0.1/inspector/service-workers/resources/scope2
+127.0.0.1/devtools/service-workers/resources/scope2
 Update
 Push
 Sync
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-view.html
similarity index 79%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-view.html
index 9b6d3e2..c73a9d15 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-view.html
@@ -1,14 +1,14 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="../console-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/console-test.js"></script>
 <script>
 function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-empty.js';
-  var scope1 = 'http://127.0.0.1:8000/inspector/service-workers/resources/scope1/';
-  var scope2 = 'http://127.0.0.1:8000/inspector/service-workers/resources/scope2/';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-empty.js';
+  var scope1 = 'http://127.0.0.1:8000/devtools/service-workers/resources/scope1/';
+  var scope2 = 'http://127.0.0.1:8000/devtools/service-workers/resources/scope2/';
   var step = 0;
   Resources.ServiceWorkersView._noThrottle = true;
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/user-agent-override-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/user-agent-override-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override.html b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/user-agent-override.html
similarity index 84%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/user-agent-override.html
index b4f35df..7f1cb57c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/user-agent-override.html
@@ -1,9 +1,9 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script src="../resources-test.js"></script>
-<script src="../console-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/service-workers/service-workers-test.js"></script>
+<script src="../../inspector/resources-test.js"></script>
+<script src="../../inspector/console-test.js"></script>
 <script>
 function test() {
   function waitForTarget() {
@@ -35,8 +35,8 @@
     });
   }
 
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/user-agent-override-worker.js';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/user-agent-override/';
+  var scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/user-agent-override-worker.js';
+  var scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/user-agent-override/';
   var userAgentString = 'Mozilla/5.0 (Overridden User Agent)';
   var originalUserAgent = navigator.userAgent;
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled-expected.txt
new file mode 100644
index 0000000..63dea994
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled-expected.txt
@@ -0,0 +1,40 @@
+Verify that CSS sourcemap enabling and disabling adds/removes sourcemap sources.
+
+
+Running: dumpInitialNavigator
+top
+  127.0.0.1:8000
+    devtools/sources
+      resources
+        sourcemap-style-1.css
+        sourcemap-style-1.scss
+        sourcemap-style-2.css
+        sourcemap-style-2.scss
+      css-sourcemaps-toggle-enabled.html
+    inspector
+      inspector-test.js
+
+Running: disableCSSSourceMaps
+top
+  127.0.0.1:8000
+    devtools/sources
+      resources
+        sourcemap-style-1.css
+        sourcemap-style-2.css
+      css-sourcemaps-toggle-enabled.html
+    inspector
+      inspector-test.js
+
+Running: enableCSSSourceMaps
+top
+  127.0.0.1:8000
+    devtools/sources
+      resources
+        sourcemap-style-1.css
+        sourcemap-style-1.scss
+        sourcemap-style-2.css
+        sourcemap-style-2.scss
+      css-sourcemaps-toggle-enabled.html
+    inspector
+      inspector-test.js
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/css-sourcemaps-toggle-enabled.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/css-sourcemaps-toggle-enabled.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled.html
index 955dbead..9de2eeb6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/css-sourcemaps-toggle-enabled.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
 
 <script>
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-fetch-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-fetch-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-fetch-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-fetch-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-fetch.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-fetch.html
similarity index 82%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-fetch.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-fetch.html
index e765689..ff90050 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-fetch.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-fetch.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../debugger-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/debugger-test.js"></script>
 <script>
 
 function testFunction()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-image-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator-image-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-image-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator-image-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-image.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator-image.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-image.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator-image.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/async-callstack-network-initiator.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/pause-in-removed-frame-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/pause-in-removed-frame-expected.txt
similarity index 91%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/pause-in-removed-frame-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/pause-in-removed-frame-expected.txt
index 8571dcf7..7dbdf09 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/pause-in-removed-frame-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/pause-in-removed-frame-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 7: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 16: Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://127.0.0.1:8000/inspector/sources/debugger/resources/resource/unreachable'.
+CONSOLE ERROR: line 16: Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://127.0.0.1:8000/devtools/sources/debugger/resources/resource/unreachable'.
 Parent Frame
 Tests "pause" functionality in detached frame.
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/pause-in-removed-frame.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/pause-in-removed-frame.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/pause-in-removed-frame.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/pause-in-removed-frame.html
index 8a7d7fa..b3835aa6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/pause-in-removed-frame.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/pause-in-removed-frame.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../debugger-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/debugger-test.js"></script>
 <script>
 
 window.removeIframe = function()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/child.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/child.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/child.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/child.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/image.png b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/image.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/image.png
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/image.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/source-map.php b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/source-map.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/source-map.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/source-map.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/worker-compiled.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/worker-compiled.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/worker-compiled.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/worker-compiled.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/worker-source-map.json b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/worker-source-map.json
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/worker-source-map.json
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/worker-source-map.json
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/worker-source.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/worker-source.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/worker-source.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/worker-source.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/x-source-map.php b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/x-source-map.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/resources/x-source-map.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/resources/x-source-map.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/source-map-http-header-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/source-map-http-header-expected.txt
similarity index 61%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/source-map-http-header-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/source-map-http-header-expected.txt
index 0e7e838..4117dc5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/source-map-http-header-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/source-map-http-header-expected.txt
@@ -2,10 +2,10 @@
 
 Reloading...
 Added script:
-  url: http://127.0.0.1:8000/inspector/sources/debugger/resources/source-map.php
+  url: http://127.0.0.1:8000/devtools/sources/debugger/resources/source-map.php
   sourceMapUrl: http://localhost/source.map.js
 Added script:
-  url: http://127.0.0.1:8000/inspector/sources/debugger/resources/x-source-map.php
+  url: http://127.0.0.1:8000/devtools/sources/debugger/resources/x-source-map.php
   sourceMapUrl: http://localhost/x-source.map.js
 Page reloaded.
 Finished reload.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/source-map-http-header.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/source-map-http-header.html
similarity index 91%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/source-map-http-header.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/source-map-http-header.html
index bd9ea58d..12c6d1e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/source-map-http-header.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/source-map-http-header.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="./resources/source-map.php"></script>
-<script src="./resources/x-source-map.php"></script>
+<script src="resources/source-map.php"></script>
+<script src="resources/x-source-map.php"></script>
 <script src="/inspector/inspector-test.js"></script>
 <script src="/inspector/debugger-test.js"></script>
 <script src="/inspector/console-test.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging-script-mapping-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging-script-mapping-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging-script-mapping-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging-script-mapping-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging-script-mapping.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging-script-mapping.html
similarity index 83%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging-script-mapping.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging-script-mapping.html
index 96769105..d1d1650 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging-script-mapping.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging-script-mapping.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../debugger-test.js"></script>
-<script src="../../console-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/debugger-test.js"></script>
+<script src="../../../inspector/console-test.js"></script>
 
 <script>
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging.html
similarity index 76%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging.html
index 4e5f644f..48106b4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/worker-debugging.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/worker-debugging.html
@@ -1,8 +1,8 @@
 <html>
 <head>
-<script src="../../inspector-test.js"></script>
-<script src="../../debugger-test.js"></script>
-<script src="../../console-test.js"></script>
+<script src="../../../inspector/inspector-test.js"></script>
+<script src="../../../inspector/debugger-test.js"></script>
+<script src="../../../inspector/console-test.js"></script>
 
 <script>
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/event-listener-breakpoints-script-fst-stmt-for-module-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/event-listener-breakpoints-script-fst-stmt-for-module-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/event-listener-breakpoints-script-fst-stmt-for-module.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/event-listener-breakpoints-script-fst-stmt-for-module.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.html
index e053856..127ecfaf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/event-listener-breakpoints-script-fst-stmt-for-module.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.html
@@ -1,7 +1,7 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
+<script src="../../inspector/debugger-test.js"></script>
 <script>
 
 function testFunction()
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled-expected.txt
new file mode 100644
index 0000000..4a8ec4c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled-expected.txt
@@ -0,0 +1,35 @@
+Verify that JavaScript sourcemap enabling and disabling adds/removes sourcemap sources.
+
+
+Running: dumpInitialNavigator
+top
+  127.0.0.1:8000
+    devtools/sources
+      resources
+        sourcemap-script.js
+        sourcemap-typescript.ts
+      js-sourcemaps-toggle-enabled.html
+    inspector
+      inspector-test.js
+
+Running: disableJSSourceMaps
+top
+  127.0.0.1:8000
+    devtools/sources
+      resources
+        sourcemap-script.js
+      js-sourcemaps-toggle-enabled.html
+    inspector
+      inspector-test.js
+
+Running: enableJSSourceMaps
+top
+  127.0.0.1:8000
+    devtools/sources
+      resources
+        sourcemap-script.js
+        sourcemap-typescript.ts
+      js-sourcemaps-toggle-enabled.html
+    inspector
+      inspector-test.js
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/js-sourcemaps-toggle-enabled.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/js-sourcemaps-toggle-enabled.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled.html
index 372315ca..73c11a7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/js-sourcemaps-toggle-enabled.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
 
 <script>
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts-expected.txt
similarity index 81%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts-expected.txt
index 936351fe..c77838b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts-expected.txt
@@ -6,9 +6,9 @@
 Adding urls
 top
   127.0.0.1:8000
+    devtools/sources
+      navigator-view-content-scripts.html
     inspector
-      sources
-        navigator-view-content-scripts.html
       inspector-test.js
   localhost:8080
     LayoutTests/inspector/debugger/foo/bar
@@ -19,9 +19,9 @@
 Removing contentScripts project
 top
   127.0.0.1:8000
+    devtools/sources
+      navigator-view-content-scripts.html
     inspector
-      sources
-        navigator-view-content-scripts.html
       inspector-test.js
   localhost:8080
     LayoutTests/inspector/debugger/foo/bar
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts.html
index a253239..cac1580 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<script src="../inspector-test.js"></script>
+<script src="../../inspector/inspector-test.js"></script>
 
 <script>
 async function test() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/empty-module.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/empty-module.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/empty-module.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/empty-module.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/script.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/script.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/script.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/script.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-script.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-script.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-script.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-script.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-script.js.map b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-script.js.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-script.js.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-script.js.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-1.css b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-1.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-1.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-1.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-1.css.map b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-1.css.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-1.css.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-1.css.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-1.scss b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-1.scss
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-1.scss
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-1.scss
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-2.css b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-2.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-2.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-2.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-2.css.map b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-2.css.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-2.css.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-2.css.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-2.scss b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-2.scss
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-style-2.scss
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-style-2.scss
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-typescript.ts b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-typescript.ts
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/sourcemap-typescript.ts
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/sourcemap-typescript.ts
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/style.css b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/style.css
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/style.css
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/style.css
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/style.css.map b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/style.css.map
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/resources/style.css.map
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/resources/style.css.map
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-highlight-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-highlight-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-highlight-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-highlight-expected.txt
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-highlight.php b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-highlight.php
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-highlight.php
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-highlight.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-metadata-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-metadata-expected.txt
new file mode 100644
index 0000000..d559633
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-metadata-expected.txt
@@ -0,0 +1,19 @@
+CONSOLE MESSAGE: line 1: Script loaded.
+Verify that network UISourceCode has metadata.
+
+
+Running: testCachedResource
+Metadata for UISourceCode: http://127.0.0.1:8000/devtools/sources/resources/style.css
+    content size: 63
+    modification time: <Date>
+
+Running: testDynamicResource
+Metadata for UISourceCode: http://127.0.0.1:8000/devtools/sources/resources/script.js
+    content size: 31
+    modification time: <Date>
+
+Running: testInlinedSourceMapSource
+Metadata for UISourceCode: http://127.0.0.1:8000/devtools/sources/resources/style.scss
+    content size: 26
+    modification time: null
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-metadata.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-metadata.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-metadata.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/sources/ui-source-code-metadata.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-inline-warning-contains-stacktrace-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-inline-warning-contains-stacktrace-expected.txt
similarity index 90%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-inline-warning-contains-stacktrace-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-inline-warning-contains-stacktrace-expected.txt
index 69b0e1d..a21cd390 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-inline-warning-contains-stacktrace-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-inline-warning-contains-stacktrace-expected.txt
@@ -6,7 +6,7 @@
 
 Stack Trace:
 
-    url: http://127.0.0.1:8000/inspector/stacktraces/resources/csp-inline-test.js
+    url: http://127.0.0.1:8000/devtools/stacktraces/resources/csp-inline-test.js
     function: thisTest
     line: 3
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-inline-warning-contains-stacktrace.html b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-inline-warning-contains-stacktrace.html
similarity index 73%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-inline-warning-contains-stacktrace.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-inline-warning-contains-stacktrace.html
index 8d851d0a..2c06ac4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-inline-warning-contains-stacktrace.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-inline-warning-contains-stacktrace.html
@@ -5,8 +5,8 @@
         <script src='/inspector/console-test.js'></script>
         <script src='/inspector/debugger-test.js'></script>
         <script src='/inspector/inspector-test.js'></script>
-        <script src='/inspector/stacktraces/resources/stacktrace-test.js'></script>
-        <script src='/inspector/stacktraces/resources/csp-inline-test.js'></script>
+        <script src='/devtools/stacktraces/resources/stacktrace-test.js'></script>
+        <script src='/devtools/stacktraces/resources/csp-inline-test.js'></script>
     </head>
     <body>
         <p>This test injects an inline script from JavaScript. The resulting
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace-expected.txt
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace-expected.txt
index 0d0c0c5b..e382523 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace-expected.txt
@@ -6,7 +6,7 @@
 
 Stack Trace:
 
-    url: http://127.0.0.1:8000/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace.html
+    url: http://127.0.0.1:8000/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace.html
     function: thisTest
     line: 10
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace.html b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace.html
index a767bf30..ab668a2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setInterval-warning-contains-stacktrace.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setInterval-warning-contains-stacktrace.html
@@ -5,7 +5,7 @@
         <script src='/inspector/console-test.js'></script>
         <script src='/inspector/debugger-test.js'></script>
         <script src='/inspector/inspector-test.js'></script>
-        <script src='/inspector/stacktraces/resources/stacktrace-test.js'></script>
+        <script src='/devtools/stacktraces/resources/stacktrace-test.js'></script>
         <script>
             function thisTest() {
                 var id = setInterval('log("FAIL")', 0);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace-expected.txt
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace-expected.txt
index d0b9167..0e3d5d4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace-expected.txt
@@ -6,7 +6,7 @@
 
 Stack Trace:
 
-    url: http://127.0.0.1:8000/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace.html
+    url: http://127.0.0.1:8000/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace.html
     function: thisTest
     line: 10
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace.html b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace.html
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace.html
index ccd7446..9c92e63 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/csp-setTimeout-warning-contains-stacktrace.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/csp-setTimeout-warning-contains-stacktrace.html
@@ -5,7 +5,7 @@
         <script src='/inspector/console-test.js'></script>
         <script src='/inspector/debugger-test.js'></script>
         <script src='/inspector/inspector-test.js'></script>
-        <script src='/inspector/stacktraces/resources/stacktrace-test.js'></script>
+        <script src='/devtools/stacktraces/resources/stacktrace-test.js'></script>
         <script>
             function thisTest() {
                 var id = setTimeout('log("FAIL")', 0);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/resources/csp-inline-test.js b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/resources/csp-inline-test.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/resources/csp-inline-test.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/resources/csp-inline-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/resources/stacktrace-test.js b/third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/resources/stacktrace-test.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/inspector/stacktraces/resources/stacktrace-test.js
rename to third_party/WebKit/LayoutTests/http/tests/devtools/stacktraces/resources/stacktrace-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype-expected.txt
index 1c51701a..8a693e8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype-expected.txt
@@ -1,9 +1,9 @@
 Tests that resources panel correctly shows mime type when it loads data from memory cache.
 
 Bug 63701 
+image image/png http://127.0.0.1:8000/devtools/resource-tree/resources/empty.png
+stylesheet text/css http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css
 document text/html http://127.0.0.1:8000/inspector-enabled/resource-tree/resource-tree-mimetype.html
 script application/x-javascript http://127.0.0.1:8000/inspector/inspector-test.js
 script application/x-javascript http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js
-image image/png http://127.0.0.1:8000/inspector/resource-tree/resources/empty.png
-stylesheet text/css http://127.0.0.1:8000/inspector/resource-tree/resources/styles-initial.css
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype.html b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype.html
index 688863f..680ec4c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/resource-tree/resource-tree-mimetype.html
@@ -2,7 +2,7 @@
 <head>
 <script src="../../inspector/inspector-test.js"></script>
 <script src="../../inspector/resource-tree/resource-tree-test.js"></script>
-<link rel="stylesheet" href="../../inspector/resource-tree/resources/styles-initial.css">
+<link rel="stylesheet" href="../../devtools/resource-tree/resources/styles-initial.css">
 <script>
 function onload()
 {
@@ -33,6 +33,6 @@
 <body onload="onload()">
 <p>Tests that resources panel correctly shows mime type when it loads data from memory cache.</p>
 <a href="https://bugs.webkit.org/show_bug.cgi?id=63701">Bug 63701</a>
-<img src="../../inspector/resource-tree/resources/empty.png">
+<img src="../../devtools/resource-tree/resources/empty.png">
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-swap-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-swap-expected.txt
deleted file mode 100644
index 0ad70dc..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-swap-expected.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-CONSOLE MESSAGE: line 6: XHR loaded: 1
-Tests that application cache model keeps track of manifest urls and statuses correctly after UPDATEREADY event and swapCache() call.
-
-Bug 72123  
-Dumping application cache tree:
-    (empty)
-Dumping application cache model:
-    (empty)
-
-Dumping application cache tree:
-    Manifest URL: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        Frame: frame1 (with-versioned-manifest.php)
-Dumping application cache model:
-    Frame: frame1
-        manifest url: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        status:       IDLE
-
-Dumping application cache tree:
-    Manifest URL: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        Frame: frame1 (with-versioned-manifest.php)
-        Frame: frame2 (with-versioned-manifest.php)
-Dumping application cache model:
-    Frame: frame1
-        manifest url: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        status:       UPDATEREADY
-    Frame: frame2
-        manifest url: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        status:       UPDATEREADY
-
-Dumping application cache tree:
-    Manifest URL: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        Frame: frame1 (with-versioned-manifest.php)
-        Frame: frame2 (with-versioned-manifest.php)
-Dumping application cache model:
-    Frame: frame1
-        manifest url: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        status:       IDLE
-    Frame: frame2
-        manifest url: http://127.0.0.1:8000/inspector/appcache/resources/versioned-manifest.php
-        status:       UPDATEREADY
-
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/modify-cross-domain-rule.html b/third_party/WebKit/LayoutTests/http/tests/inspector/modify-cross-domain-rule.html
index f9dd85b..72edb201 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/modify-cross-domain-rule.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/modify-cross-domain-rule.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<link rel="stylesheet" href="http://localhost:8000/inspector/elements/styles/modify-cross-domain-rule.css">
+<link rel="stylesheet" href="http://localhost:8000/devtools/elements/styles/modify-cross-domain-rule.css">
 <script src="inspector-test.js"></script>
 <script src="elements-test.js"></script>
 <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-document-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-document-url-expected.txt
deleted file mode 100644
index 766c6bc5..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-document-url-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Tests that resources have proper documentURL set in the tree model.
-
-
-http://127.0.0.1:8000/inspector/inspector-test.js => http://127.0.0.1:8000/inspector/resource-tree/resource-tree-document-url.html
-http://127.0.0.1:8000/inspector/resource-tree/resource-tree-document-url.html => http://127.0.0.1:8000/inspector/resource-tree/resource-tree-document-url.html
-http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js => http://127.0.0.1:8000/inspector/resource-tree/resource-tree-document-url.html
-http://127.0.0.1:8000/inspector/resource-tree/resources/dummy-iframe.html => http://127.0.0.1:8000/inspector/resource-tree/resources/dummy-iframe.html
-http://127.0.0.1:8000/inspector/resources-test.js => http://127.0.0.1:8000/inspector/resource-tree/resource-tree-document-url.html
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners.html
deleted file mode 100644
index dfa9b69..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<html>
-<head>
-<script src="../inspector-test.js"></script>
-<script src="../console-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script>
-function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-lazy-addeventlistener.js';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/lazy-scope';
-  ConsoleTestRunner.waitForConsoleMessages(1, () => {
-    ConsoleTestRunner.dumpConsoleMessages();
-    TestRunner.completeTest();
-  });
-  ApplicationTestRunner.registerServiceWorker(scriptURL, scope);
-}
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests that a warning is shown in the console if addEventListener is called after initial evaluation of the service worker script.</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirect.php b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirect.php
deleted file mode 100644
index 2cfb1fc..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirect.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-  $url = "http://127.0.0.1:8000/inspector/service-workers/resources/" .
-         "bypass-for-network-redirected.html";
-  header("Location: $url");
-?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-blocked-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-blocked-expected.txt
deleted file mode 100644
index 52e811c..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-blocked-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Tests blocking fetch in Service Workers.
-
-Fetch in worker result: FETCH_FAILED
-http://127.0.0.1:8000/inspector/service-workers/resources/network-fetch-worker.js
-resource.type: other
-request.failed: false
-http://127.0.0.1:8000/inspector/network/resources/resource.php
-resource.type: other
-request.failed: true
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-expected.txt
deleted file mode 100644
index 0bc4472..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-network-fetch-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Tests fetch in Service Workers.
-
-Fetch in worker result: Hello world
-http://127.0.0.1:8000/inspector/service-workers/resources/network-fetch-worker.js
-resource.type: other
-request.failed: false
-http://127.0.0.1:8000/inspector/network/resources/resource.php
-resource.type: fetch
-request.failed: false
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-pause.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-pause.html
deleted file mode 100644
index 63920cc23..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-worker-pause.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<html>
-<head>
-<script src="../inspector-test.js"></script>
-<script src="../debugger-test.js"></script>
-<script src="service-workers-test.js"></script>
-<script>
-
-function test() {
-  var scriptURL = 'http://127.0.0.1:8000/inspector/service-workers/resources/service-worker-debugger.js';
-  var scope = 'http://127.0.0.1:8000/inspector/service-workers/resources/scope-debugger/';
-
-  SourcesTestRunner.startDebuggerTest(start);
-
-  function start() {
-    SourcesTestRunner.waitUntilPaused(onPaused);
-    ApplicationTestRunner.registerServiceWorker(scriptURL, scope);
-  }
-
-  function onPaused(frames, reason, breakpointIds, async) {
-    SourcesTestRunner.captureStackTrace(frames, async);
-    SourcesTestRunner.completeDebuggerTest();
-  }
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests that we can pause in service worker.</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/css-sourcemaps-toggle-enabled-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/css-sourcemaps-toggle-enabled-expected.txt
deleted file mode 100644
index 09f3f42..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/css-sourcemaps-toggle-enabled-expected.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Verify that CSS sourcemap enabling and disabling adds/removes sourcemap sources.
-
-
-Running: dumpInitialNavigator
-top
-  127.0.0.1:8000
-    inspector
-      sources
-        resources
-          sourcemap-style-1.css
-          sourcemap-style-1.scss
-          sourcemap-style-2.css
-          sourcemap-style-2.scss
-        css-sourcemaps-toggle-enabled.html
-      inspector-test.js
-
-Running: disableCSSSourceMaps
-top
-  127.0.0.1:8000
-    inspector
-      sources
-        resources
-          sourcemap-style-1.css
-          sourcemap-style-2.css
-        css-sourcemaps-toggle-enabled.html
-      inspector-test.js
-
-Running: enableCSSSourceMaps
-top
-  127.0.0.1:8000
-    inspector
-      sources
-        resources
-          sourcemap-style-1.css
-          sourcemap-style-1.scss
-          sourcemap-style-2.css
-          sourcemap-style-2.scss
-        css-sourcemaps-toggle-enabled.html
-      inspector-test.js
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/js-sourcemaps-toggle-enabled-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/js-sourcemaps-toggle-enabled-expected.txt
deleted file mode 100644
index dbf0872..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/js-sourcemaps-toggle-enabled-expected.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-Verify that JavaScript sourcemap enabling and disabling adds/removes sourcemap sources.
-
-
-Running: dumpInitialNavigator
-top
-  127.0.0.1:8000
-    inspector
-      sources
-        resources
-          sourcemap-script.js
-          sourcemap-typescript.ts
-        js-sourcemaps-toggle-enabled.html
-      inspector-test.js
-
-Running: disableJSSourceMaps
-top
-  127.0.0.1:8000
-    inspector
-      sources
-        resources
-          sourcemap-script.js
-        js-sourcemaps-toggle-enabled.html
-      inspector-test.js
-
-Running: enableJSSourceMaps
-top
-  127.0.0.1:8000
-    inspector
-      sources
-        resources
-          sourcemap-script.js
-          sourcemap-typescript.ts
-        js-sourcemaps-toggle-enabled.html
-      inspector-test.js
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-metadata-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-metadata-expected.txt
deleted file mode 100644
index bd2e5e29b..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/ui-source-code-metadata-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-CONSOLE MESSAGE: line 1: Script loaded.
-Verify that network UISourceCode has metadata.
-
-
-Running: testCachedResource
-Metadata for UISourceCode: http://127.0.0.1:8000/inspector/sources/resources/style.css
-    content size: 63
-    modification time: <Date>
-
-Running: testDynamicResource
-Metadata for UISourceCode: http://127.0.0.1:8000/inspector/sources/resources/script.js
-    content size: 31
-    modification time: <Date>
-
-Running: testInlinedSourceMapSource
-Metadata for UISourceCode: http://127.0.0.1:8000/inspector/sources/resources/style.scss
-    content size: 26
-    modification time: null
-
diff --git a/third_party/WebKit/OWNERS b/third_party/WebKit/OWNERS
index 60a1066..a9055c9 100644
--- a/third_party/WebKit/OWNERS
+++ b/third_party/WebKit/OWNERS
@@ -6,6 +6,9 @@
 thakis@chromium.org
 
 per-file PRESUBMIT*.py=dpranke@chromium.org
+per-file PRESUBMIT*.py=foolip@chromium.org
+per-file PRESUBMIT*.py=qyearsley@chromium.org
 per-file PRESUBMIT*.py=thakis@chromium.org
+per-file PRESUBMIT*.py=tkent@chromium.org
 
 # COMPONENT: Blink
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index 6a55295..634350f6 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -11,7 +11,7 @@
     alias_for: {
     },
 
-    // - runtime_flag: "CSSGridLayout"
+    // - runtime_flag: "CSSScrollBoundaryBehavior"
     // The flag on RuntimeEnabledFeatures conditionally enables the property.
     // This doesn't currently work with alias_for.
     runtime_flag: {
@@ -667,7 +667,7 @@
       field_template: "external",
       type_name: "StyleSelfAlignmentData",
       field_group: "*",
-      default_value: "StyleSelfAlignmentData(RuntimeEnabledFeatures::CSSGridLayoutEnabled() ? kItemPositionNormal : kItemPositionStretch, kOverflowAlignmentDefault)",
+      default_value: "StyleSelfAlignmentData(kItemPositionNormal, kOverflowAlignmentDefault)",
       include_paths: ["core/style/StyleSelfAlignmentData.h"],
     },
     {
@@ -1405,7 +1405,6 @@
       api_class: "CSSPropertyAPIGridAutoLine",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertGridTrackSizeList",
-      runtime_flag: "CSSGridLayout",
       type_name: "Vector<GridTrackSize>",
       field_template: "external",
       default_value: "Vector<GridTrackSize>(1, GridTrackSize(Length(kAuto)))",
@@ -1417,7 +1416,6 @@
       api_class: true,
       api_methods: ["ParseSingleValue"],
       converter: "ConvertGridAutoFlow",
-      runtime_flag: "CSSGridLayout",
       type_name: "GridAutoFlow",
       field_template: "primitive",
       default_value: "kAutoFlowRow",
@@ -1430,7 +1428,6 @@
       api_class: "CSSPropertyAPIGridAutoLine",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertGridTrackSizeList",
-      runtime_flag: "CSSGridLayout",
       type_name: "Vector<GridTrackSize>",
       field_template: "external",
       default_value: "Vector<GridTrackSize>(1, GridTrackSize(Length(kAuto)))",
@@ -1442,7 +1439,6 @@
       api_class: "CSSPropertyAPIGridLine",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertGridPosition",
-      runtime_flag: "CSSGridLayout",
       type_name: "GridPosition",
       field_template: "external",
       default_value: "GridPosition()",
@@ -1454,7 +1450,6 @@
       api_class: "CSSPropertyAPIGridGap",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertLength",
-      runtime_flag: "CSSGridLayout",
       field_template: "<length>",
       default_value: "Length(kFixed)",
       field_group: "*",
@@ -1464,7 +1459,6 @@
       api_class: "CSSPropertyAPIGridLine",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertGridPosition",
-      runtime_flag: "CSSGridLayout",
       type_name: "GridPosition",
       field_template: "external",
       default_value: "GridPosition()",
@@ -1476,7 +1470,6 @@
       api_class: "CSSPropertyAPIGridLine",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertGridPosition",
-      runtime_flag: "CSSGridLayout",
       type_name: "GridPosition",
       field_template: "external",
       default_value: "GridPosition()",
@@ -1488,7 +1481,6 @@
       api_class: "CSSPropertyAPIGridGap",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertLength",
-      runtime_flag: "CSSGridLayout",
       field_template: "<length>",
       default_value: "Length(kFixed)",
       field_group: "*",
@@ -1498,7 +1490,6 @@
       api_class: "CSSPropertyAPIGridLine",
       api_methods: ["ParseSingleValue"],
       converter: "ConvertGridPosition",
-      runtime_flag: "CSSGridLayout",
       type_name: "GridPosition",
       field_template: "external",
       default_value: "GridPosition()",
@@ -1510,14 +1501,12 @@
       api_class: true,
       api_methods: ["ParseSingleValue"],
       custom_all: true,
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "grid-template-columns",
       api_class: "CSSPropertyAPIGridTemplateLine",
       api_methods: ["ParseSingleValue"],
       custom_all: true,
-      runtime_flag: "CSSGridLayout",
       field_template: "external",
       type_name: "Vector<GridTrackSize>",
       field_group: "*",
@@ -1529,7 +1518,6 @@
       api_class: "CSSPropertyAPIGridTemplateLine",
       api_methods: ["ParseSingleValue"],
       custom_all: true,
-      runtime_flag: "CSSGridLayout",
       field_template: "external",
       type_name: "Vector<GridTrackSize>",
       field_group: "*",
@@ -1605,7 +1593,6 @@
       api_class: true,
       api_methods: ["ParseSingleValue"],
       converter: "ConvertSelfOrDefaultAlignmentData",
-      runtime_flag: "CSSGridLayout",
       field_template: "external",
       type_name: "StyleSelfAlignmentData",
       field_group: "*",
@@ -1617,7 +1604,6 @@
       api_class: true,
       api_methods: ["ParseSingleValue"],
       converter: "ConvertSelfOrDefaultAlignmentData",
-      runtime_flag: "CSSGridLayout",
       field_template: "external",
       type_name: "StyleSelfAlignmentData",
       field_group: "*",
@@ -3970,63 +3956,54 @@
       longhands: ["grid-template-rows", "grid-template-columns", "grid-template-areas", "grid-auto-flow", "grid-auto-rows", "grid-auto-columns"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "place-content",
       longhands: ["align-content", "justify-content"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "place-items",
       longhands: ["align-items", "justify-items"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "place-self",
       longhands: ["align-self", "justify-self"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "grid-area",
       longhands: ["grid-row-start", "grid-column-start", "grid-row-end", "grid-column-end"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "grid-column",
       longhands: ["grid-column-start", "grid-column-end"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "grid-gap",
       longhands: ["grid-row-gap", "grid-column-gap"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "grid-row",
       longhands: ["grid-row-start", "grid-row-end"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "grid-template",
       longhands: ["grid-template-rows", "grid-template-columns", "grid-template-areas"],
       api_class: true,
       api_methods: ["ParseShorthand"],
-      runtime_flag: "CSSGridLayout",
     },
     {
       name: "list-style",
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 073a823..ebe174f 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -661,8 +661,7 @@
 
 static CSSValueList*
 ValueForContentPositionAndDistributionWithOverflowAlignment(
-    const StyleContentAlignmentData& data,
-    CSSValueID normal_behavior_value_id) {
+    const StyleContentAlignmentData& data) {
   CSSValueList* result = CSSValueList::CreateSpaceSeparated();
   // Handle content-distribution values
   if (data.Distribution() != kContentDistributionDefault)
@@ -673,10 +672,7 @@
     case kContentPositionNormal:
       // Handle 'normal' value, not valid as content-distribution fallback.
       if (data.Distribution() == kContentDistributionDefault) {
-        result->Append(*CSSIdentifierValue::Create(
-            RuntimeEnabledFeatures::CSSGridLayoutEnabled()
-                ? CSSValueNormal
-                : normal_behavior_value_id));
+        result->Append(*CSSIdentifierValue::Create(CSSValueNormal));
       }
       break;
     case kContentPositionLastBaseline:
@@ -2553,7 +2549,7 @@
     }
     case CSSPropertyAlignContent:
       return ValueForContentPositionAndDistributionWithOverflowAlignment(
-          style.AlignContent(), CSSValueStretch);
+          style.AlignContent());
     case CSSPropertyAlignItems:
       return ValueForItemPositionWithOverflowAlignment(style.AlignItems());
     case CSSPropertyAlignSelf:
@@ -2579,7 +2575,7 @@
       return CSSIdentifierValue::Create(style.FlexWrap());
     case CSSPropertyJustifyContent:
       return ValueForContentPositionAndDistributionWithOverflowAlignment(
-          style.JustifyContent(), CSSValueFlexStart);
+          style.JustifyContent());
     case CSSPropertyOrder:
       return CSSPrimitiveValue::Create(style.Order(),
                                        CSSPrimitiveValue::UnitType::kNumber);
@@ -3885,10 +3881,14 @@
     case CSSPropertyScrollSnapMarginInlineEnd:
       return ZoomAdjustedPixelValueForLength(style.ScrollSnapMarginInlineEnd(),
                                              style);
-    case CSSPropertyScrollBoundaryBehavior:
-      if (style.ScrollBoundaryBehaviorX() == style.ScrollBoundaryBehaviorY())
-        return CSSIdentifierValue::Create(style.ScrollBoundaryBehaviorX());
-      return nullptr;
+    case CSSPropertyScrollBoundaryBehavior: {
+      CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+      list->Append(
+          *CSSIdentifierValue::Create(style.ScrollBoundaryBehaviorX()));
+      list->Append(
+          *CSSIdentifierValue::Create(style.ScrollBoundaryBehaviorY()));
+      return list;
+    }
     case CSSPropertyScrollBoundaryBehaviorX:
       return CSSIdentifierValue::Create(style.ScrollBoundaryBehaviorX());
     case CSSPropertyScrollBoundaryBehaviorY:
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
index d40ae25..da934b2 100644
--- a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
+++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
@@ -481,7 +481,7 @@
     case CSSPropertyOverflow:
       return GetCommonValue(overflowShorthand());
     case CSSPropertyScrollBoundaryBehavior:
-      return GetCommonValue(scrollBoundaryBehaviorShorthand());
+      return GetShorthandValue(scrollBoundaryBehaviorShorthand());
     case CSSPropertyPadding:
       return Get4Values(paddingShorthand());
     case CSSPropertyTextDecoration:
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
index 4cf82ff4..8124e362 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
@@ -574,8 +574,7 @@
       return (value_id >= CSSValueInline && value_id <= CSSValueInlineFlex) ||
              value_id == CSSValueWebkitFlex ||
              value_id == CSSValueWebkitInlineFlex || value_id == CSSValueNone ||
-             (RuntimeEnabledFeatures::CSSGridLayoutEnabled() &&
-              (value_id == CSSValueGrid || value_id == CSSValueInlineGrid)) ||
+             value_id == CSSValueGrid || value_id == CSSValueInlineGrid ||
              (RuntimeEnabledFeatures::CSSDisplayContentsEnabled() &&
               value_id == CSSValueContents);
     case CSSPropertyDominantBaseline:
@@ -975,11 +974,6 @@
     case CSSPropertyWritingMode:
     case CSSPropertyScrollSnapStop:
       return true;
-    case CSSPropertyJustifyContent:
-    case CSSPropertyAlignContent:
-    case CSSPropertyAlignItems:
-    case CSSPropertyAlignSelf:
-      return !RuntimeEnabledFeatures::CSSGridLayoutEnabled();
     default:
       return false;
   }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignItems.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignItems.cpp
index 6979124..59772e0 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignItems.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignItems.cpp
@@ -15,7 +15,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   // align-items property does not allow the 'auto' value.
   if (CSSPropertyParserHelpers::IdentMatches<CSSValueAuto>(range.Peek().Id()))
     return nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignOrJustifyContent.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignOrJustifyContent.cpp
index da160ae..467b10f5 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignOrJustifyContent.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignOrJustifyContent.cpp
@@ -14,7 +14,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   return CSSPropertyAlignmentUtils::ConsumeContentDistributionOverflowPosition(
       range);
 }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignSelf.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignSelf.cpp
index de7388c..822247f 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignSelf.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAlignSelf.cpp
@@ -14,7 +14,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   return CSSPropertyAlignmentUtils::ConsumeSelfPositionOverflowPosition(range);
 }
 
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoFlow.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoFlow.cpp
index 5da4824..e146eeb 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoFlow.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoFlow.cpp
@@ -16,7 +16,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   CSSIdentifierValue* row_or_column_value =
       CSSPropertyParserHelpers::ConsumeIdent<CSSValueRow, CSSValueColumn>(
           range);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoLine.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoLine.cpp
index 41f0770..21f9213 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoLine.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoLine.cpp
@@ -16,7 +16,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   return CSSPropertyGridUtils::ConsumeGridTrackList(
       range, context.Mode(), CSSPropertyGridUtils::kGridAuto);
 }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridLine.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridLine.cpp
index d05f4e0..90f2c08 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridLine.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridLine.cpp
@@ -14,7 +14,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext&,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   return CSSPropertyGridUtils::ConsumeGridLine(range);
 }
 
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateAreas.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateAreas.cpp
index cdc212f..c8dda27 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateAreas.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateAreas.cpp
@@ -20,7 +20,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext&,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   if (range.Peek().Id() == CSSValueNone)
     return CSSPropertyParserHelpers::ConsumeIdent(range);
 
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateLine.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateLine.cpp
index 6f935ed..2f05891 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateLine.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridTemplateLine.cpp
@@ -15,7 +15,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   return CSSPropertyGridUtils::ConsumeGridTemplatesRowsOrColumns(
       range, context.Mode());
 }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifyItems.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifyItems.cpp
index b088d51..e6dcf071 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifyItems.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifyItems.cpp
@@ -16,7 +16,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   CSSParserTokenRange range_copy = range;
   CSSIdentifierValue* legacy =
       CSSPropertyParserHelpers::ConsumeIdent<CSSValueLegacy>(range_copy);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifySelf.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifySelf.cpp
index 26820a6c..6d2a40de 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifySelf.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIJustifySelf.cpp
@@ -14,7 +14,6 @@
     CSSParserTokenRange& range,
     const CSSParserContext& context,
     const CSSParserLocalContext&) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   return CSSPropertyAlignmentUtils::ConsumeSelfPositionOverflowPosition(range);
 }
 
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyGridUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyGridUtils.cpp
index a0a87d1..aaa2a41 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyGridUtils.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyGridUtils.cpp
@@ -504,7 +504,6 @@
   // Input should be nullptrs.
   DCHECK(!start_value);
   DCHECK(!end_value);
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
 
   start_value = ConsumeGridLine(range);
   if (!start_value)
@@ -534,7 +533,6 @@
   DCHECK(!template_columns);
   DCHECK(!template_areas);
 
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   DCHECK_EQ(gridTemplateShorthand().length(), 3u);
 
   CSSParserTokenRange range_copy = range;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp
index cad070e..5d8db469 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp
@@ -45,7 +45,6 @@
     const CSSParserContext& context,
     const CSSParserLocalContext&,
     HeapVector<CSSProperty, 256>& properties) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   DCHECK_EQ(shorthandForProperty(CSSPropertyGrid).length(), 6u);
 
   CSSParserTokenRange range_copy = range;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp
index 871ad8f..b0f2a27 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp
@@ -18,7 +18,6 @@
     const CSSParserContext&,
     const CSSParserLocalContext&,
     HeapVector<CSSProperty, 256>& properties) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   DCHECK_EQ(gridAreaShorthand().length(), 4u);
 
   CSSValue* row_start_value = CSSPropertyGridUtils::ConsumeGridLine(range);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp
index e10a0bd..fcf2b34e 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp
@@ -18,7 +18,6 @@
     const CSSParserContext& context,
     const CSSParserLocalContext&,
     HeapVector<CSSProperty, 256>& properties) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   DCHECK_EQ(shorthandForProperty(CSSPropertyGridGap).length(), 2u);
   CSSValue* row_gap = CSSPropertyParserHelpers::ConsumeLengthOrPercent(
       range, context.Mode(), kValueRangeNonNegative);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp
index e036144..4babcdf 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp
@@ -19,7 +19,6 @@
     const CSSParserContext&,
     const CSSParserLocalContext&,
     HeapVector<CSSProperty, 256>& properties) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceContent).length(), 2u);
 
   CSSValue* align_content_value = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp
index 6269b42..31d601db 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp
@@ -19,7 +19,6 @@
     const CSSParserContext&,
     const CSSParserLocalContext&,
     HeapVector<CSSProperty, 256>& properties) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceItems).length(), 2u);
 
   // align-items property does not allow the 'auto' value.
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp
index 9fd46f32..f43f9d8b 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp
@@ -19,7 +19,6 @@
     const CSSParserContext&,
     const CSSParserLocalContext&,
     HeapVector<CSSProperty, 256>& properties) const {
-  DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
   DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceSelf).length(), 2u);
 
   CSSValue* align_self_value = nullptr;
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
index 2621da09..e19704e 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -720,26 +720,6 @@
     const CSSValue& value) {
   StyleContentAlignmentData alignment_data =
       ComputedStyle::InitialContentAlignment();
-  if (!RuntimeEnabledFeatures::CSSGridLayoutEnabled()) {
-    const CSSIdentifierValue& identifier_value = ToCSSIdentifierValue(value);
-    switch (identifier_value.GetValueID()) {
-      case CSSValueStretch:
-      case CSSValueSpaceBetween:
-      case CSSValueSpaceAround:
-        alignment_data.SetDistribution(
-            identifier_value.ConvertTo<ContentDistributionType>());
-        break;
-      case CSSValueFlexStart:
-      case CSSValueFlexEnd:
-      case CSSValueCenter:
-        alignment_data.SetPosition(
-            identifier_value.ConvertTo<ContentPosition>());
-        break;
-      default:
-        NOTREACHED();
-    }
-    return alignment_data;
-  }
   const CSSContentDistributionValue& content_value =
       ToCSSContentDistributionValue(value);
   if (content_value.Distribution()->GetValueID() != CSSValueInvalid)
diff --git a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
index 5ec346d9..1d5bbdf 100644
--- a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
@@ -2130,6 +2130,11 @@
       was_allowed, had_redirect, std::move(source));
 }
 
+void WebLocalFrameImpl::ClientDroppedNavigation() {
+  DCHECK(GetFrame());
+  GetFrame()->Loader().ClientDroppedNavigation();
+}
+
 void WebLocalFrameImpl::SendOrientationChangeEvent() {
   if (!GetFrame())
     return;
diff --git a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h
index 43ec08c..3a55ad0 100644
--- a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h
+++ b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h
@@ -282,6 +282,7 @@
                          bool was_allowed,
                          bool had_redirect,
                          const WebSourceLocation&) override;
+  void ClientDroppedNavigation() override;
   void SendOrientationChangeEvent() override;
   WebSandboxFlags EffectiveSandboxFlags() const override;
   void DidCallAddSearchProvider() override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
index 75f77e9..07f6009 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -1281,10 +1281,7 @@
     case kItemPositionEnd:
     case kItemPositionLeft:
     case kItemPositionRight:
-      // FIXME: Implement these (https://crbug.com/507690). The extended grammar
-      // is not enabled by default so we shouldn't hit this codepath.
-      // The new grammar is only used when Grid Layout feature is enabled.
-      DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled());
+      // TODO(jferanndez): Implement these (https://crbug.com/722287).
       break;
   }
   return LayoutUnit();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 2c8d2ab..4299eb8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -1664,16 +1664,18 @@
     }
   }
 
-  const auto* bottom_section = BottomNonEmptySection();
-  DCHECK(bottom_section);
   // The table's after outer border width is the maximum after outer border
   // widths of all cells in the last row. See the CSS 2.1 spec, section 17.6.2.
-  unsigned row = bottom_section->NumRows() - 1;
-  unsigned bottom_cols = bottom_section->NumCols(row);
-  for (unsigned col = 0; col < bottom_cols; ++col) {
-    if (const auto* cell = bottom_section->PrimaryCellAt(row, col)) {
-      collapsed_outer_border_after_ = std::max(
-          collapsed_outer_border_after_, cell->CollapsedOuterBorderAfter());
+  // TODO(crbug.com/764525): Because of the bug, bottom_section can be null when
+  // top_section is not null. See LayoutTableTest.OutOfOrderHeadAndBody.
+  if (const auto* bottom_section = BottomNonEmptySection()) {
+    unsigned row = bottom_section->NumRows() - 1;
+    unsigned bottom_cols = bottom_section->NumCols(row);
+    for (unsigned col = 0; col < bottom_cols; ++col) {
+      if (const auto* cell = bottom_section->PrimaryCellAt(row, col)) {
+        collapsed_outer_border_after_ = std::max(
+            collapsed_outer_border_after_, cell->CollapsedOuterBorderAfter());
+      }
     }
   }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
index 82fd163..cc4a25f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
@@ -233,6 +233,18 @@
   EXPECT_EQ(0, table->PaddingUnder());
 }
 
+TEST_F(LayoutTableTest, OutOfOrderHeadAndBody) {
+  // This should not crash.
+  SetBodyInnerHTML(
+      "<table style='border-collapse: collapse'>"
+      "  <tbody><tr><td>Body</td></tr></tbody>"
+      "  <thead></thead>"
+      "<table>");
+  // TODO(crbug.com/764525): Add tests for TopSection(), BottomSection(),
+  // TopNonEmptySection(), BottomNonEmptySection(), SectionAbove(),
+  // SectionBelow() for similar cases.
+}
+
 }  // anonymous namespace
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
index 8772cb9..d993acb 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
@@ -790,7 +790,9 @@
         break_iterator_.SetBreakType(LineBreakType::kKeepAll);
         break;
     }
-    break_iterator_.SetBreakAfterSpace(style.BreakOnlyAfterWhiteSpace());
+    break_iterator_.SetBreakSpace(style.BreakOnlyAfterWhiteSpace()
+                                      ? BreakSpaceType::kAfter
+                                      : BreakSpaceType::kBeforeSpace);
 
     enable_soft_hyphen_ = style.GetHyphens() != Hyphens::kNone;
     hyphenation_ = style.GetHyphenation();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index a5eace5..ace36848 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -118,9 +118,11 @@
 
   // TODO(ikilpatrick): Add DCHECK that any positioned floats are children.
 
-  for (const auto& positioned_float : positioned_floats)
+  for (const auto& positioned_float : positioned_floats) {
     container_builder->AddChild(positioned_float.layout_result,
                                 positioned_float.logical_offset);
+    container_builder->PropagateBreak(positioned_float.layout_result);
+  }
 
   unpositioned_floats->clear();
 }
@@ -693,6 +695,7 @@
                             border_scrollbar_padding_.InlineSum());
 
   container_builder_.AddChild(layout_result, logical_offset);
+  container_builder_.PropagateBreak(layout_result);
 
   *previous_inflow_position =
       ComputeInflowPosition(*previous_inflow_position, child, child_data,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
index 21016345..348529d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -72,11 +72,8 @@
     const NGLogicalOffset& child_offset) {
   switch (child->Type()) {
     case NGPhysicalBoxFragment::kFragmentBox:
-      // Update if we have fragmented in this flow.
-      if (child->BreakToken()) {
-        did_break_ |= !child->BreakToken()->IsFinished();
+      if (child->BreakToken())
         child_break_tokens_.push_back(child->BreakToken());
-      }
       break;
     case NGPhysicalBoxFragment::kFragmentLineBox:
       // NGInlineNode produces multiple line boxes in an anonymous box. Only
@@ -100,6 +97,22 @@
   return *this;
 }
 
+NGFragmentBuilder& NGFragmentBuilder::PropagateBreak(
+    RefPtr<NGLayoutResult> child_layout_result) {
+  if (!did_break_)
+    return PropagateBreak(child_layout_result->PhysicalFragment());
+  return *this;
+}
+
+NGFragmentBuilder& NGFragmentBuilder::PropagateBreak(
+    RefPtr<NGPhysicalFragment> child_fragment) {
+  if (!did_break_) {
+    const auto* token = child_fragment->BreakToken();
+    did_break_ = token && !token->IsFinished();
+  }
+  return *this;
+}
+
 NGFragmentBuilder& NGFragmentBuilder::SetBfcOffset(const NGBfcOffset& offset) {
   bfc_offset_ = offset;
   return *this;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
index 6039007..a6bf9e7 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -52,6 +52,10 @@
   NGFragmentBuilder& AddChild(RefPtr<NGPhysicalFragment>,
                               const NGLogicalOffset&);
 
+  // Update if we have fragmented in this flow.
+  NGFragmentBuilder& PropagateBreak(RefPtr<NGLayoutResult>);
+  NGFragmentBuilder& PropagateBreak(RefPtr<NGPhysicalFragment>);
+
   NGFragmentBuilder& SetBfcOffset(const NGBfcOffset& offset);
 
   // Builder has non-trivial out-of-flow descendant methods.
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index 8a4a39e9..200a405 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -456,9 +456,12 @@
   // We should have either finished the provisional or committed navigation if
   // this is called. Only delcare the whole frame finished if neither is in
   // progress.
-  DCHECK(document_loader_->SentDidFinishLoad() || !HasProvisionalNavigation());
-  if (!document_loader_->SentDidFinishLoad() || HasProvisionalNavigation())
+  DCHECK((document_loader_ && document_loader_->SentDidFinishLoad()) ||
+         !HasProvisionalNavigation());
+  if (!document_loader_ || !document_loader_->SentDidFinishLoad() ||
+      HasProvisionalNavigation()) {
     return;
+  }
 
   if (frame_->IsLoading()) {
     progress_tracker_->ProgressCompleted();
@@ -1390,6 +1393,13 @@
       WebTriggeringEventInfo::kNotFromEvent, form);
 }
 
+void FrameLoader::ClientDroppedNavigation() {
+  if (!provisional_document_loader_ || provisional_document_loader_->DidStart())
+    return;
+
+  DetachProvisionalDocumentLoader(provisional_document_loader_);
+}
+
 NavigationPolicy FrameLoader::CheckLoadCanStart(
     FrameLoadRequest& frame_load_request,
     FrameLoadType type,
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.h b/third_party/WebKit/Source/core/loader/FrameLoader.h
index e1f1e46..2745562 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.h
@@ -220,6 +220,8 @@
 
   static void SetReferrerForFrameRequest(FrameLoadRequest&);
 
+  void ClientDroppedNavigation();
+
  private:
   bool PrepareRequestForThisFrame(FrameLoadRequest&);
   FrameLoadType DetermineFrameLoadType(const FrameLoadRequest&);
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index aa60ceb4..d1362d87 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -293,9 +293,7 @@
   }
 
   static StyleSelfAlignmentData InitialDefaultAlignment() {
-    return StyleSelfAlignmentData(RuntimeEnabledFeatures::CSSGridLayoutEnabled()
-                                      ? kItemPositionNormal
-                                      : kItemPositionStretch,
+    return StyleSelfAlignmentData(kItemPositionNormal,
                                   kOverflowAlignmentDefault);
   }
 
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/move.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/move.js
index 8e8e4fe..25b73f9 100644
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/move.js
+++ b/third_party/WebKit/Source/devtools/scripts/migrate_test/move.js
@@ -18,7 +18,17 @@
 
 function main() {
   const originalTests = scanForTests([
-    '../../../../LayoutTests/http/tests/inspector/network',
+    '../../../../LayoutTests/http/tests/inspector/appcache',
+    '../../../../LayoutTests/http/tests/inspector/audits',
+    '../../../../LayoutTests/http/tests/inspector/cache-storage',
+    '../../../../LayoutTests/http/tests/inspector/debugger',
+    '../../../../LayoutTests/http/tests/inspector/elements',
+    '../../../../LayoutTests/http/tests/inspector/resource-tree',
+    '../../../../LayoutTests/http/tests/inspector/search',
+    '../../../../LayoutTests/http/tests/inspector/security',
+    '../../../../LayoutTests/http/tests/inspector/service-workers',
+    '../../../../LayoutTests/http/tests/inspector/sources',
+    '../../../../LayoutTests/http/tests/inspector/stacktraces',
   ]);
 
   console.log(originalTests);
@@ -30,17 +40,24 @@
       continue;
     }
     const inputPath = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', inputRelativePath);
-    const inputResourcesPath = path.resolve(inputPath, 'resources');
+    const inputResourcesPath = path.resolve(path.dirname(inputPath), 'resources');
     const outPath = migrateUtils.getOutPath(inputPath, false);
-    const outResourcesPath = path.resolve(outPath, 'resources');
+    const outResourcesPath = path.resolve(path.dirname(outPath), 'resources');
 
+    debugger;
     if (utils.isDir(inputResourcesPath))
       oldToNewResourcesPath.set(inputResourcesPath, outResourcesPath);
     mkdirp.sync(path.dirname(outPath));
 
     const original = fs.readFileSync(inputPath, 'utf-8');
-    const updatedReferences = original.replace(/src="..\/(?=.+-test)/g, 'src="../../inspector/')
-                                  .replace(/src="(?=\w.+-test)/g, 'src="../inspector/');
+    debugger;
+    const updatedReferences = original.replace(/127.0.0.1:8000\/inspector/g, '127.0.0.1:8000/devtools')
+                                  .replace(/script src="\.\//g, 'script src="')
+                                  .replace(/script src="..\/(?=.+-test)/g, 'script src="../../inspector/')
+                                  .replace(
+                                      /script src="(?=\w.+-test)/g,
+                                      `script src="${path.relative(path.dirname(outPath), path.dirname(inputPath))}/`)
+                                  .replace(/..\/..\/inspector\/..\//g, '../../../inspector/');
     fs.writeFileSync(outPath, updatedReferences);
     fs.unlinkSync(inputPath);
 
@@ -51,8 +68,10 @@
     const inputExpectationsPath =
         inputPath.replace(/\.x?html/, '-expected.txt').replace('-expected-expected', '-expected');
     const outExpectationsPath = outPath.replace(/\.x?html/, '-expected.txt').replace('-expected-expected', '-expected');
-    fs.writeFileSync(outExpectationsPath, fs.readFileSync(inputExpectationsPath, 'utf-8'));
-    fs.unlinkSync(inputExpectationsPath);
+    if (utils.isFile(inputExpectationsPath)) {
+      fs.writeFileSync(outExpectationsPath, fs.readFileSync(inputExpectationsPath, 'utf-8'));
+      fs.unlinkSync(inputExpectationsPath);
+    }
   }
 
   const newTestPaths = Array.from(oldToNewTestPath.values()).filter(x => x);
@@ -74,8 +93,10 @@
     updateExpectationsFile(filePath);
   }
 
-  for (const [oldResourcesPath, newResourcesPath] of oldToNewResourcesPath)
+  for (const [oldResourcesPath, newResourcesPath] of oldToNewResourcesPath) {
     utils.copyRecursive(oldResourcesPath, path.dirname(newResourcesPath));
+    utils.removeRecursive(oldResourcesPath);
+  }
 
   function updateExpectationsFile(filePath) {
     const expectations = fs.readFileSync(filePath, 'utf-8');
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp
index 1394a47e..6049f31 100644
--- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp
@@ -95,13 +95,9 @@
 
 }  // anonymous namespace
 
-#if defined(OS_ANDROID)
-// Often times out on Android: https://crbug.com/752511.
+// Often times out on all platforms: https://crbug.com/763550.
 #define MAYBE_TEST_P(test_case_name, test_name) \
   TEST_P(test_case_name, DISABLED_##test_name)
-#else
-#define MAYBE_TEST_P TEST_P
-#endif
 
 class BaseAudioContextAutoplayTest
     : public ::testing::TestWithParam<AutoplayPolicy::Type> {
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index 6468b1e..b1a57417 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -231,10 +231,6 @@
       status: "experimental",
     },
     {
-      name: "CSSGridLayout",
-      status: "stable",
-    },
-    {
       name: "CSSHexAlphaColor",
       status: "stable",
     },
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
index 4bf1ef7..af426d3 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
@@ -12,8 +12,6 @@
 #include "platform/fonts/FontTestUtilities.h"
 #include "platform/fonts/shaping/ShapeResultInlineHeaders.h"
 #include "platform/fonts/shaping/ShapeResultTestInfo.h"
-#include "platform/testing/FontTestHelpers.h"
-#include "platform/testing/UnitTestHelpers.h"
 #include "platform/text/TextBreakIterator.h"
 #include "platform/text/TextRun.h"
 #include "platform/wtf/Vector.h"
@@ -666,175 +664,4 @@
   EXPECT_NEAR(result->Width(), result->Bounds().Width(), result->Width() * .1);
 }
 
-TEST_F(HarfBuzzShaperTest, SafeToBreakLatinCommonLigatures) {
-  FontDescription::VariantLigatures ligatures;
-  ligatures.common = FontDescription::kEnabledLigaturesState;
-
-  // MEgalopolis Extra has a lot of ligatures which this test relies on.
-  Font testFont = blink::testing::CreateTestFont(
-      "MEgalopolis",
-      blink::testing::PlatformTestDataPath(
-          "third_party/MEgalopolis/MEgalopolisExtra.woff"),
-      16, &ligatures);
-
-  String string = To16Bit("ffi ff", 6);
-  HarfBuzzShaper shaper(string.Characters16(), string.length());
-  RefPtr<ShapeResult> result = shaper.Shape(&testFont, TextDirection::kLtr);
-
-  EXPECT_EQ(0u, result->NextSafeToBreakOffset(0));  // At start of string.
-  EXPECT_EQ(3u, result->NextSafeToBreakOffset(1));  // At end of "ffi" ligature.
-  EXPECT_EQ(3u, result->NextSafeToBreakOffset(2));  // At end of "ffi" ligature.
-  EXPECT_EQ(3u, result->NextSafeToBreakOffset(3));  // At end of "ffi" ligature.
-  EXPECT_EQ(4u, result->NextSafeToBreakOffset(4));  // After space.
-  EXPECT_EQ(6u, result->NextSafeToBreakOffset(5));  // At end of "ff" ligature.
-  EXPECT_EQ(6u, result->NextSafeToBreakOffset(6));  // At end of "ff" ligature.
-
-  // Verify safe to break information in copied results to ensure that both
-  // copying and multi-run break information works.
-  RefPtr<ShapeResult> copied_result =
-      ShapeResult::Create(&testFont, 0, TextDirection::kLtr);
-  result->CopyRange(0, 3, copied_result.Get());
-  result->CopyRange(3, string.length(), copied_result.Get());
-
-  EXPECT_EQ(0u, copied_result->NextSafeToBreakOffset(0));
-  EXPECT_EQ(3u, copied_result->NextSafeToBreakOffset(1));
-  EXPECT_EQ(3u, copied_result->NextSafeToBreakOffset(2));
-  EXPECT_EQ(3u, copied_result->NextSafeToBreakOffset(3));
-  EXPECT_EQ(4u, copied_result->NextSafeToBreakOffset(4));
-  EXPECT_EQ(6u, copied_result->NextSafeToBreakOffset(5));
-  EXPECT_EQ(6u, copied_result->NextSafeToBreakOffset(6));
-}
-
-TEST_F(HarfBuzzShaperTest, SafeToBreakPreviousLatinCommonLigatures) {
-  FontDescription::VariantLigatures ligatures;
-  ligatures.common = FontDescription::kEnabledLigaturesState;
-
-  // MEgalopolis Extra has a lot of ligatures which this test relies on.
-  Font testFont = blink::testing::CreateTestFont(
-      "MEgalopolis",
-      blink::testing::PlatformTestDataPath(
-          "third_party/MEgalopolis/MEgalopolisExtra.woff"),
-      16, &ligatures);
-
-  String string = To16Bit("ffi ff", 6);
-  HarfBuzzShaper shaper(string.Characters16(), string.length());
-  RefPtr<ShapeResult> result = shaper.Shape(&testFont, TextDirection::kLtr);
-
-  EXPECT_EQ(6u, result->PreviousSafeToBreakOffset(6));  // At end of "ff" liga.
-  EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(5));  // At end of "ff" liga.
-  EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(4));  // After space.
-  EXPECT_EQ(3u, result->PreviousSafeToBreakOffset(3));  // At end of "ffi" liga.
-  EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(2));  // At start of string.
-  EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(1));  // At start of string.
-  EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(0));  // At start of string.
-
-  // Verify safe to break information in copied results to ensure that both
-  // copying and multi-run break information works.
-  RefPtr<ShapeResult> copied_result =
-      ShapeResult::Create(&testFont, 0, TextDirection::kLtr);
-  result->CopyRange(0, 3, copied_result.Get());
-  result->CopyRange(3, string.length(), copied_result.Get());
-
-  EXPECT_EQ(6u, copied_result->PreviousSafeToBreakOffset(6));
-  EXPECT_EQ(4u, copied_result->PreviousSafeToBreakOffset(5));
-  EXPECT_EQ(4u, copied_result->PreviousSafeToBreakOffset(4));
-  EXPECT_EQ(3u, copied_result->PreviousSafeToBreakOffset(3));
-  EXPECT_EQ(0u, copied_result->PreviousSafeToBreakOffset(2));
-  EXPECT_EQ(0u, copied_result->PreviousSafeToBreakOffset(1));
-  EXPECT_EQ(0u, copied_result->PreviousSafeToBreakOffset(0));
-}
-
-TEST_F(HarfBuzzShaperTest, SafeToBreakLatinDiscretionaryLigatures) {
-  FontDescription::VariantLigatures ligatures;
-  ligatures.common = FontDescription::kEnabledLigaturesState;
-  ligatures.discretionary = FontDescription::kEnabledLigaturesState;
-
-  // MEgalopolis Extra has a lot of ligatures which this test relies on.
-  Font testFont = blink::testing::CreateTestFont(
-      "MEgalopolis",
-      blink::testing::PlatformTestDataPath(
-          "third_party/MEgalopolis/MEgalopolisExtra.woff"),
-      16, &ligatures);
-
-  // RA and CA form ligatures, most glyph pairs have kerning.
-  String string(u"ABRACADABRA");
-  HarfBuzzShaper shaper(string.Characters16(), string.length());
-  RefPtr<ShapeResult> result = shaper.Shape(&testFont, TextDirection::kLtr);
-  EXPECT_EQ(6u, result->NextSafeToBreakOffset(1));    // After CA ligature.
-  EXPECT_EQ(6u, result->NextSafeToBreakOffset(6));    // After CA ligature.
-  EXPECT_EQ(9u, result->NextSafeToBreakOffset(7));    // Before RA ligature.
-  EXPECT_EQ(9u, result->NextSafeToBreakOffset(9));    // Before RA ligature.
-  EXPECT_EQ(11u, result->NextSafeToBreakOffset(10));  // At end of string.
-
-  // Add zero-width spaces at the safe to break offsets.
-  String refString(u"ABRACA\u200BDAB\u200BRA");
-  HarfBuzzShaper refShaper(refString.Characters16(), refString.length());
-  RefPtr<ShapeResult> referenceResult =
-      refShaper.Shape(&testFont, TextDirection::kLtr);
-
-  // Results should be identical if it truly is safe to break at the designated
-  // safe-to-break offsets
-  EXPECT_EQ(result->SnappedWidth(), referenceResult->SnappedWidth());
-  EXPECT_EQ(result->Bounds(), referenceResult->Bounds());
-  EXPECT_EQ(result->SnappedStartPositionForOffset(0),
-            referenceResult->SnappedStartPositionForOffset(0));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(1),
-            referenceResult->SnappedStartPositionForOffset(1));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(2),
-            referenceResult->SnappedStartPositionForOffset(2));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(3),
-            referenceResult->SnappedStartPositionForOffset(3));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(4),
-            referenceResult->SnappedStartPositionForOffset(4));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(5),
-            referenceResult->SnappedStartPositionForOffset(5));
-
-  // First zero-width space is at position 6 so the the matching character in
-  // the reference results is 7.
-  EXPECT_EQ(result->SnappedStartPositionForOffset(6),
-            referenceResult->SnappedStartPositionForOffset(7));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(7),
-            referenceResult->SnappedStartPositionForOffset(8));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(8),
-            referenceResult->SnappedStartPositionForOffset(9));
-
-  // Second zero-width space is at position 9 so the the matching character in
-  // the reference results is 11.
-  EXPECT_EQ(result->SnappedStartPositionForOffset(9),
-            referenceResult->SnappedStartPositionForOffset(11));
-  EXPECT_EQ(result->SnappedStartPositionForOffset(10),
-            referenceResult->SnappedStartPositionForOffset(12));
-}
-
-// TODO(layout-dev): This test fails on Mac due to AAT shaping.
-TEST_F(HarfBuzzShaperTest, DISABLED_SafeToBreakArabicCommonLigatures) {
-  FontDescription::VariantLigatures ligatures;
-  ligatures.common = FontDescription::kEnabledLigaturesState;
-
-  // كسر الاختبار
-  String string(
-      u"\u0643\u0633\u0631\u0020\u0627\u0644\u0627\u062E\u062A\u0628\u0627"
-      u"\u0631");
-  HarfBuzzShaper shaper(string.Characters16(), string.length());
-  RefPtr<ShapeResult> result = shaper.Shape(&font, TextDirection::kRtl);
-
-  // Safe to break at 0, 3, 4, 5, 7, and 11.
-  EXPECT_EQ(0u, result->NextSafeToBreakOffset(0));
-  EXPECT_EQ(3u, result->NextSafeToBreakOffset(1));
-  EXPECT_EQ(3u, result->NextSafeToBreakOffset(2));
-  EXPECT_EQ(3u, result->NextSafeToBreakOffset(3));
-  EXPECT_EQ(4u, result->NextSafeToBreakOffset(4));
-  EXPECT_EQ(5u, result->NextSafeToBreakOffset(5));
-  EXPECT_EQ(7u, result->NextSafeToBreakOffset(6));
-  EXPECT_EQ(7u, result->NextSafeToBreakOffset(7));
-  EXPECT_EQ(11u, result->NextSafeToBreakOffset(8));
-  EXPECT_EQ(11u, result->NextSafeToBreakOffset(9));
-  EXPECT_EQ(11u, result->NextSafeToBreakOffset(10));
-  EXPECT_EQ(11u, result->NextSafeToBreakOffset(11));
-  EXPECT_EQ(12u, result->NextSafeToBreakOffset(12));
-}
-
-// TODO(layout-dev): Expand RTL test coverage and add tests for mixed
-// directionality strings.
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
index 1b81a36..4841df0 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
@@ -40,31 +40,6 @@
 
 namespace blink {
 
-unsigned ShapeResult::RunInfo::NextSafeToBreakOffset(unsigned offset) const {
-  DCHECK_LT(offset, num_characters_);
-  for (unsigned i = 0; i < safe_break_offsets_.size(); i++) {
-    if (safe_break_offsets_[i] >= offset)
-      return safe_break_offsets_[i];
-  }
-
-  // Next safe break is at the end of the run.
-  return num_characters_;
-}
-
-unsigned ShapeResult::RunInfo::PreviousSafeToBreakOffset(
-    unsigned offset) const {
-  if (offset >= num_characters_)
-    return num_characters_;
-
-  for (unsigned i = safe_break_offsets_.size(); i > 0; i--) {
-    if (safe_break_offsets_[i - 1] <= offset)
-      return safe_break_offsets_[i - 1];
-  }
-
-  // Next safe break is at the start of the run.
-  return 0;
-}
-
 float ShapeResult::RunInfo::XPositionForVisualOffset(
     unsigned offset,
     AdjustMidCluster adjust_mid_cluster) const {
@@ -236,52 +211,6 @@
   return ShapeResult::Create(*this);
 }
 
-unsigned ShapeResult::NextSafeToBreakOffset(unsigned absolute_offset) const {
-  if (!absolute_offset)
-    return StartIndexForResult();
-
-  // The absolute_offset argument represents the offset for the entire
-  // ShapeResult while offset is continuously updated to be relative to the
-  // current run.
-  unsigned offset = absolute_offset;
-  unsigned run_offset = 0;
-  for (const auto& run : runs_) {
-    if (!run)
-      continue;
-
-    unsigned num_characters = run->num_characters_;
-    if (offset < num_characters)
-      return run->NextSafeToBreakOffset(offset) + run_offset;
-
-    offset -= num_characters;
-    run_offset += num_characters;
-  }
-
-  return EndIndexForResult();
-}
-
-unsigned ShapeResult::PreviousSafeToBreakOffset(
-    unsigned absolute_offset) const {
-  if (absolute_offset >= NumCharacters())
-    return NumCharacters();
-
-  for (unsigned i = runs_.size(); i > 0; i--) {
-    const auto& run = runs_[i - 1];
-    if (!run)
-      continue;
-
-    unsigned run_start = run->start_index_;
-    unsigned run_end = run_start + run->num_characters_;
-    if (absolute_offset >= run_start && absolute_offset < run_end) {
-      unsigned start =
-          absolute_offset > run_start ? absolute_offset - run_start : 0;
-      return run->PreviousSafeToBreakOffset(start) + run_start;
-    }
-  }
-
-  return StartIndexForResult();
-}
-
 // If the position is outside of the result, returns the start or the end offset
 // depends on the position.
 unsigned ShapeResult::OffsetForPosition(float target_x,
@@ -332,7 +261,7 @@
   float x = 0;
   float offset_x = 0;
 
-  // The absolute_offset argument represents the offset for the entire
+  // The absoluteOffset argument represents the offset for the entire
   // ShapeResult while offset is continuously updated to be relative to the
   // current run.
   unsigned offset = absolute_offset;
@@ -446,32 +375,10 @@
   return result;
 }
 
-namespace {
-
-float HarfBuzzPositionToFloat(hb_position_t value) {
+static inline float HarfBuzzPositionToFloat(hb_position_t value) {
   return static_cast<float>(value) / (1 << 16);
 }
 
-// Checks whether it's safe to break without reshaping before the given glyph.
-bool IsSafeToBreakBefore(const hb_glyph_info_t* glyph_infos,
-                         unsigned num_glyphs,
-                         unsigned i) {
-  // At the end of the run.
-  if (i == num_glyphs - 1)
-    return true;
-
-  // Not at a cluster boundary.
-  if (glyph_infos[i].cluster == glyph_infos[i + 1].cluster)
-    return false;
-
-  // The HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag is set for all glyphs in a
-  // given cluster so we only need to check the last one.
-  hb_glyph_flags_t flags = hb_glyph_info_get_glyph_flags(glyph_infos + i);
-  return (flags & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) == 0;
-}
-
-}  // anonymous namespace
-
 // Computes glyph positions, sets advance and offset of each glyph to RunInfo.
 //
 // Also computes glyph bounding box of the run. In this function, glyph bounding
@@ -522,9 +429,8 @@
     else
       advance = -HarfBuzzPositionToFloat(pos.y_advance);
 
-    uint16_t character_index =
+    run->glyph_data_[i].character_index =
         glyph_infos[start_glyph + i].cluster - start_cluster;
-    run->glyph_data_[i].character_index = character_index;
 
     run->SetGlyphAndPositions(i, glyph, advance, offset_x, offset_y);
     total_advance += advance;
@@ -545,14 +451,6 @@
       glyph_origin.SetX(glyph_origin.X() + advance);
     else
       glyph_origin.SetY(glyph_origin.Y() + advance);
-
-    // Check if it is safe to break without reshaping before the cluster.
-    if (IsSafeToBreakBefore(glyph_infos + start_glyph, num_glyphs, i)) {
-      if (run->Rtl())
-        run->safe_break_offsets_.push_front(character_index);
-      else
-        run->safe_break_offsets_.push_back(character_index);
-    }
   }
 
   run->width_ = std::max(0.0f, total_advance);
@@ -659,22 +557,19 @@
 void ShapeResult::CopyRange(unsigned start_offset,
                             unsigned end_offset,
                             ShapeResult* target) const {
-  if (!runs_.size())
-    return;
-
   unsigned index = target->num_characters_;
   unsigned target_run_size_before = target->runs_.size();
   float total_width = 0;
   for (const auto& run : runs_) {
-    unsigned run_start = run->start_index_;
-    unsigned run_end = run_start + run->num_characters_;
+    unsigned run_start = (*run).start_index_;
+    unsigned run_end = run_start + (*run).num_characters_;
 
     if (start_offset < run_end && end_offset > run_start) {
       unsigned start = start_offset > run_start ? start_offset - run_start : 0;
       unsigned end = std::min(end_offset, run_end) - run_start;
       DCHECK(end > start);
 
-      auto sub_run = run->CreateSubRun(start, end);
+      auto sub_run = (*run).CreateSubRun(start, end);
       sub_run->start_index_ = index;
       total_width += sub_run->width_;
       index += sub_run->num_characters_;
@@ -731,9 +626,6 @@
     float advance = font->TabWidth(font_data, text_run.GetTabSize(), position);
     run->glyph_data_[i].character_index = i;
     run->SetGlyphAndPositions(i, font_data->SpaceGlyph(), advance, 0, 0);
-
-    // Assume it's safe to break after a tab character.
-    run->safe_break_offsets_.push_back(run->glyph_data_[i].character_index);
     position += advance;
   }
   run->width_ = position - start_position;
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h
index d07cde8..ef1e6e7 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h
@@ -94,11 +94,6 @@
   // For memory reporting.
   size_t ByteSize() const;
 
-  // Returns the next or previous offsets respectively at which it is safe to
-  // break without reshaping.
-  unsigned NextSafeToBreakOffset(unsigned offset) const;
-  unsigned PreviousSafeToBreakOffset(unsigned offset) const;
-
   unsigned OffsetForPosition(float target_x, bool include_partial_glyphs) const;
   float PositionForOffset(unsigned offset) const;
   LayoutUnit SnappedStartPositionForOffset(unsigned offset) const {
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultInlineHeaders.h b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultInlineHeaders.h
index d908060..4c0a1f1d 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultInlineHeaders.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultInlineHeaders.h
@@ -81,8 +81,6 @@
 
   bool Rtl() const { return HB_DIRECTION_IS_BACKWARD(direction_); }
   bool IsHorizontal() const { return HB_DIRECTION_IS_HORIZONTAL(direction_); }
-  unsigned NextSafeToBreakOffset(unsigned) const;
-  unsigned PreviousSafeToBreakOffset(unsigned) const;
   float XPositionForVisualOffset(unsigned, AdjustMidCluster) const;
   float XPositionForOffset(unsigned, AdjustMidCluster) const;
   int CharacterIndexForXPosition(float, bool include_partial_glyphs) const;
@@ -144,12 +142,6 @@
 
     run->width_ = total_advance;
     run->num_characters_ = number_of_characters;
-
-    for (unsigned i = 0; i < safe_break_offsets_.size(); i++) {
-      if (safe_break_offsets_[i] >= start && safe_break_offsets_[i] <= end)
-        run->safe_break_offsets_.push_back(safe_break_offsets_[i] - start);
-    }
-
     return run;
   }
 
@@ -211,9 +203,6 @@
   hb_direction_t direction_;
   hb_script_t script_;
   Vector<HarfBuzzRunGlyphData> glyph_data_;
-  // List of character indecies before which it's safe to break without
-  // reshaping.
-  Vector<uint16_t> safe_break_offsets_;
   unsigned start_index_;
   unsigned num_characters_;
   float width_;
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
index d57922e..744efb7 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
@@ -38,6 +38,30 @@
   return ch == kSpaceCharacter || ch == kTabulationCharacter;
 }
 
+unsigned PreviousSafeToBreakAfter(const UChar* text,
+                                  unsigned start,
+                                  unsigned offset) {
+  // TODO(eae): This is quite incorrect. It should be changed to use the
+  // HarfBuzzHarfBuzz safe to break info when available.
+  for (; offset > start; offset--) {
+    if (text[offset - 1] == kSpaceCharacter)
+      break;
+  }
+  return offset;
+}
+
+unsigned NextSafeToBreakBefore(const UChar* text,
+                               unsigned end,
+                               unsigned offset) {
+  // TODO(eae): This is quite incorrect. It should be changed to use the
+  // HarfBuzzHarfBuzz safe to break info when available.
+  for (; offset < end; offset++) {
+    if (text[offset] == kSpaceCharacter)
+      break;
+  }
+  return offset;
+}
+
 // ShapingLineBreaker computes using visual positions. This function flips
 // logical advance to visual, or vice versa.
 LayoutUnit FlipRtl(LayoutUnit value, TextDirection direction) {
@@ -121,7 +145,7 @@
   unsigned previous_break_opportunity =
       break_iterator_->PreviousBreakOpportunity(offset, start);
   unsigned word_start = previous_break_opportunity;
-  if (!break_iterator_->BreakAfterSpace()) {
+  if (break_iterator_->BreakSpace() != BreakSpaceType::kAfter) {
     while (word_start < text.length() &&
            LazyLineBreakIterator::IsBreakableSpace(text[word_start]))
       word_start++;
@@ -257,7 +281,7 @@
   candidate_break = std::max(candidate_break, start);
 
   unsigned break_opportunity;
-  if (break_iterator_->BreakAfterSpace() &&
+  if (break_iterator_->BreakSpace() == BreakSpaceType::kAfter &&
       IsHangableSpace(text[candidate_break])) {
     // If BreakAfterSpace, allow spaces to hang over the available space.
     result_out->has_hanging_spaces = true;
@@ -287,7 +311,8 @@
   // the start and the next safe-to-break boundary needs to be reshaped and the
   // available space adjusted to take the reshaping into account.
   RefPtr<ShapeResult> line_start_result;
-  unsigned first_safe = result_->NextSafeToBreakOffset(start);
+  unsigned first_safe =
+      NextSafeToBreakBefore(shaper_->GetText(), shaper_->TextLength(), start);
   DCHECK_GE(first_safe, start);
   // Reshape takes place only when first_safe is before the break opportunity.
   // Otherwise reshape will be part of line_end_result.
@@ -308,8 +333,9 @@
     // boundary reshape between the safe-to-break offset and the valid break
     // offset. If the resulting width exceeds the available space the
     // preceding boundary is tried until the available space is sufficient.
-    unsigned previous_safe =
-        std::max(result_->PreviousSafeToBreakOffset(break_opportunity), start);
+    unsigned previous_safe = std::max(
+        PreviousSafeToBreakAfter(shaper_->GetText(), start, break_opportunity),
+        start);
     DCHECK_LE(previous_safe, break_opportunity);
     if (previous_safe != break_opportunity) {
       LayoutUnit safe_position = SnapStart(
@@ -360,10 +386,8 @@
     line_end_result->CopyRange(last_safe, max_length, line_result.Get());
 
   DCHECK_GT(break_opportunity, start);
-  // TODO(layout-dev): This hits on Mac and Mac only for a number of tests in
-  // virtual/layout_ng/external/wpt/css/CSS2/floats-clear/.
-  // DCHECK_EQ(std::min(break_opportunity, range_end) - start,
-  //          line_result->NumCharacters());
+  DCHECK_EQ(std::min(break_opportunity, range_end) - start,
+            line_result->NumCharacters());
 
   result_out->break_offset = break_opportunity;
   if (!result_out->is_hyphenated &&
@@ -378,21 +402,22 @@
     unsigned start,
     LayoutUnit start_position,
     unsigned range_end) {
-  unsigned first_safe = result_->NextSafeToBreakOffset(start);
+  unsigned first_safe =
+      NextSafeToBreakBefore(shaper_->GetText(), shaper_->TextLength(), start);
   DCHECK_GE(first_safe, start);
 
   RefPtr<ShapeResult> line_result;
   TextDirection direction = result_->Direction();
   if (first_safe == start) {
-    // If |start| is safe-to-break no reshape is needed.
+    // If |start| is safe-to-break, reshape is not needed.
     line_result = ShapeResult::Create(font_, 0, direction);
     result_->CopyRange(start, range_end, line_result.Get());
   } else if (first_safe < range_end) {
-    // Otherwise reshape to |first_safe|, then copy the rest.
+    // Otherwise reshape to the first safe, then copy the rest.
     line_result = Shape(direction, start, first_safe);
     result_->CopyRange(first_safe, range_end, line_result.Get());
   } else {
-    // If no safe-to-break offset is found in range, reshape the entire range.
+    // If no safe-to-break in the ragne, reshape the whole range.
     line_result = Shape(direction, start, range_end);
   }
   return line_result;
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp
index f1f4ece..8674f80b 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp
@@ -230,9 +230,7 @@
   EXPECT_EQ(28u, break_offset);
 }
 
-// Hits DCHECK at end of ShapingLineBreaker::ShapeLine, not clear if the test
-// is correct. Disabling for now.
-TEST_F(ShapingLineBreakerTest, DISABLED_ShapeLineArabicThaiHanLatin) {
+TEST_F(ShapingLineBreakerTest, ShapeLineArabicThaiHanLatin) {
   UChar mixed_string[] = {0x628, 0x20,   0x64A, 0x629, 0x20,
                           0xE20, 0x65E5, 0x62,  0};
   LazyLineBreakIterator break_iterator(mixed_string, "ar_AE",
diff --git a/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp
index 3dd7501bc..6c63254d 100644
--- a/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp
@@ -7,6 +7,7 @@
 #include "platform/SharedBuffer.h"
 #include "platform/fonts/Font.h"
 #include "platform/fonts/FontCustomPlatformData.h"
+#include "platform/fonts/FontDescription.h"
 #include "platform/fonts/FontSelector.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "platform/wtf/PassRefPtr.h"
@@ -70,8 +71,7 @@
 
 Font CreateTestFont(const AtomicString& family_name,
                     const String& font_path,
-                    float size,
-                    const FontDescription::VariantLigatures* ligatures) {
+                    float size) {
   FontFamily family;
   family.SetFamily(family_name);
 
@@ -79,8 +79,6 @@
   font_description.SetFamily(family);
   font_description.SetSpecifiedSize(size);
   font_description.SetComputedSize(size);
-  if (ligatures)
-    font_description.SetVariantLigatures(*ligatures);
 
   Font font(font_description);
   font.Update(TestFontSelector::Create(font_path));
diff --git a/third_party/WebKit/Source/platform/testing/FontTestHelpers.h b/third_party/WebKit/Source/platform/testing/FontTestHelpers.h
index 6868c67..8dfe383 100644
--- a/third_party/WebKit/Source/platform/testing/FontTestHelpers.h
+++ b/third_party/WebKit/Source/platform/testing/FontTestHelpers.h
@@ -5,7 +5,6 @@
 #ifndef FontTestHelpers_h
 #define FontTestHelpers_h
 
-#include "platform/fonts/FontDescription.h"
 #include "platform/wtf/Forward.h"
 
 namespace blink {
@@ -17,8 +16,7 @@
 // Reads a font from a specified path, for use in unit tests only.
 Font CreateTestFont(const AtomicString& family_name,
                     const String& font_path,
-                    float size,
-                    const FontDescription::VariantLigatures* = nullptr);
+                    float size);
 
 }  // namespace testing
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/testing/data/third_party/MEgalopolis/MEgalopolisExtra.woff b/third_party/WebKit/Source/platform/testing/data/third_party/MEgalopolis/MEgalopolisExtra.woff
deleted file mode 100644
index ee37efff..0000000
--- a/third_party/WebKit/Source/platform/testing/data/third_party/MEgalopolis/MEgalopolisExtra.woff
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/Source/platform/testing/data/third_party/MEgalopolis/README b/third_party/WebKit/Source/platform/testing/data/third_party/MEgalopolis/README
deleted file mode 100644
index 8172bbd..0000000
--- a/third_party/WebKit/Source/platform/testing/data/third_party/MEgalopolis/README
+++ /dev/null
@@ -1,37 +0,0 @@
-MEgalopolis Extra Font
-from http://www.smeltery.net/fonts/megalopolis-extra
-© Jack Usine / SMeltery · All rights reserved.
-
-Font file included as a real-world example for testing fonts with extreme ligatures
-which combine two characters into the dimensions of one glyph,
-for example: fast/text/font-ligatures-linebreak*.html
-
-Permission was granted by Jack Usine to use this font in a test case and include it in the repository.
-
-License Information:
-
-http://www.smeltery.net/SMFFEULA.html (retrieved 01-15-2014):
-
-"SMELTERY FREE FONT END USER LICENSE AGREEMENT!
-SMFF EULA version 1.2, november 2008
- 
-By downloading and/or installing a SMeltery Free Font
-you agree to this license.
-
-This font is freeware. You can use it freely for all your personal and commercial work.
-
-The font files may not be modified without written permission from Jack Usine / SMeltery.
-
-This font may not be sold.
-
-This font may not be redistributed, shared, repackaged or included in any online or offline archive, font collection, web site or CD-ROM without written permission from Jack Usine / SMeltery.
-
-Embedding this font in a PDF document is allowed.
-
-Embedding this font in a web page with a @font-face declaration is allowed once you credit SMeltery with a link somewhere on your site.
-
-Except for your right to use this font, all other rights are owned and retained by Jack Usine / SMeltery.
-
-Jack Usine / SMeltery is not liable for any damage resulting from the use of this font.
-
-Thank you!"
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp b/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp
index 4de5d3c..be2765c 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp
+++ b/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp
@@ -255,7 +255,7 @@
 
 template <typename CharacterType,
           LineBreakType lineBreakType,
-          bool break_after_space>
+          BreakSpaceType break_space>
 inline int LazyLineBreakIterator::NextBreakablePosition(
     int pos,
     const CharacterType* str) const {
@@ -276,14 +276,25 @@
     ch = str[i];
 
     is_space = IsBreakableSpace(ch);
-    if (!break_after_space) {
-      if (is_space)
-        return i;
-    } else {
-      if (is_space)
-        continue;
-      if (is_last_space)
-        return i;
+    switch (break_space) {
+      case BreakSpaceType::kBefore:
+        if (is_space)
+          return i;
+        break;
+      case BreakSpaceType::kBeforeSpace:
+        if (ch == kSpaceCharacter)
+          return i;
+        if (is_space)
+          continue;
+        if (is_last_space && last_ch != kSpaceCharacter)
+          return i;
+        break;
+      case BreakSpaceType::kAfter:
+        if (is_space)
+          continue;
+        if (is_last_space)
+          return i;
+        break;
     }
 
     if (ShouldBreakAfter(last_last_ch, last_ch, ch))
@@ -318,8 +329,20 @@
           }
         }
       }
-      if (i == next_break && (break_after_space || !is_last_space))
-        return i;
+      if (i == next_break) {
+        switch (break_space) {
+          case BreakSpaceType::kBefore:
+            if (!is_last_space)
+              return i;
+            break;
+          case BreakSpaceType::kBeforeSpace:
+            if (last_ch != kSpaceCharacter)
+              return i;
+            break;
+          case BreakSpaceType::kAfter:
+            return i;
+        }
+      }
     }
   }
 
@@ -330,9 +353,20 @@
 inline int LazyLineBreakIterator::NextBreakablePosition(
     int pos,
     const CharacterType* str) const {
-  if (!break_after_space_)
-    return NextBreakablePosition<CharacterType, lineBreakType, false>(pos, str);
-  return NextBreakablePosition<CharacterType, lineBreakType, true>(pos, str);
+  switch (break_space_) {
+    case BreakSpaceType::kBefore:
+      return NextBreakablePosition<CharacterType, lineBreakType,
+                                   BreakSpaceType::kBefore>(pos, str);
+    case BreakSpaceType::kBeforeSpace:
+      return NextBreakablePosition<CharacterType, lineBreakType,
+                                   BreakSpaceType::kBeforeSpace>(pos, str);
+    case BreakSpaceType::kAfter:
+      return NextBreakablePosition<CharacterType, lineBreakType,
+                                   BreakSpaceType::kAfter>(pos, str);
+  }
+  NOTREACHED();
+  return NextBreakablePosition<CharacterType, lineBreakType,
+                               BreakSpaceType::kBefore>(pos, str);
 }
 
 template <LineBreakType lineBreakType>
@@ -402,4 +436,17 @@
   return ostream << "LineBreakType::" << static_cast<int>(line_break_type);
 }
 
+std::ostream& operator<<(std::ostream& ostream, BreakSpaceType break_space) {
+  switch (break_space) {
+    case BreakSpaceType::kBefore:
+      return ostream << "Before";
+    case BreakSpaceType::kBeforeSpace:
+      return ostream << "BeforeSpace";
+    case BreakSpaceType::kAfter:
+      return ostream << "After";
+  }
+  NOTREACHED();
+  return ostream << "BreakSpaceType::" << static_cast<int>(break_space);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIterator.h b/third_party/WebKit/Source/platform/text/TextBreakIterator.h
index 2c5e810..b8a7dee 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIterator.h
+++ b/third_party/WebKit/Source/platform/text/TextBreakIterator.h
@@ -86,7 +86,29 @@
   kKeepAll,
 };
 
+// Determines break opportunities around collapsible space characters (space,
+// newline, and tabulation characters.)
+enum class BreakSpaceType {
+  // Break before collapsible space characters.
+  // This is a specialized optimization for CSS, where leading/trailing spaces
+  // in each line are removed, and thus breaking before spaces can save
+  // computing hanging spaces.
+  kBefore,
+
+  // Break before space characters, but after newline and tabulation characters.
+  // This is for CSS line breaking as in |kBefore|, but when whitespace
+  // collapsing is already applied to the target string.
+  kBeforeSpace,
+
+  // Break after collapsible space characters.
+  // When 'white-space:pre-wrap', or when in editing, leaging/trailing spaces
+  // need to be preserved, and that the |kBefore| optimization cannot work.
+  // This mode is compatible with UAX#14/ICU. http://unicode.org/reports/tr14/
+  kAfter,
+};
+
 PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, LineBreakType);
+PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, BreakSpaceType);
 
 class PLATFORM_EXPORT LazyLineBreakIterator final {
   STACK_ALLOCATED();
@@ -210,18 +232,8 @@
 
   LineBreakType BreakType() const { return break_type_; }
   void SetBreakType(LineBreakType break_type) { break_type_ = break_type; }
-
-  // By default, this class breaks before spaces. This is a specialized
-  // optimization for CSS, where leading/trailing spaces in each line are
-  // removed, and thus breaking before spaces can save computing hanging spaces.
-  //
-  // When 'white-space:pre-wrap', or when in editing, leaging/trailing spaces
-  // need to be preserved, and this optimization needs to be disabled. This mode
-  // is compatible with UAX#14/ICU. http://unicode.org/reports/tr14/
-  bool BreakAfterSpace() const { return break_after_space_; }
-  void SetBreakAfterSpace(bool break_after_space) {
-    break_after_space_ = break_after_space;
-  }
+  BreakSpaceType BreakSpace() const { return break_space_; }
+  void SetBreakSpace(BreakSpaceType break_space) { break_space_ = break_space; }
 
   inline bool IsBreakable(int pos,
                           int& next_breakable,
@@ -261,7 +273,7 @@
     cached_prior_context_length_ = 0;
   }
 
-  template <typename CharacterType, LineBreakType, bool>
+  template <typename CharacterType, LineBreakType, BreakSpaceType>
   int NextBreakablePosition(int pos, const CharacterType* str) const;
   template <typename CharacterType, LineBreakType>
   int NextBreakablePosition(int pos, const CharacterType* str) const;
@@ -278,7 +290,7 @@
   mutable const UChar* cached_prior_context_;
   mutable unsigned cached_prior_context_length_;
   LineBreakType break_type_;
-  bool break_after_space_ = false;
+  BreakSpaceType break_space_ = BreakSpaceType::kBefore;
 };
 
 // Iterates over "extended grapheme clusters", as defined in UAX #29.
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp b/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp
index 64d4bec..d75c0c6 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp
+++ b/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp
@@ -18,15 +18,15 @@
 
   // The expected break positions must be specified UTF-16 character boundaries.
   void MatchLineBreaks(LineBreakType line_break_type,
-                       bool break_after_space,
-                       const Vector<int> expected_break_positions) {
+                       const Vector<int> expected_break_positions,
+                       BreakSpaceType break_space = BreakSpaceType::kBefore) {
     if (test_string_.Is8Bit()) {
       test_string_ = String::Make16BitFrom8BitSource(test_string_.Characters8(),
                                                      test_string_.length());
     }
     LazyLineBreakIterator lazy_break_iterator(test_string_);
     lazy_break_iterator.SetBreakType(line_break_type);
-    lazy_break_iterator.SetBreakAfterSpace(break_after_space);
+    lazy_break_iterator.SetBreakSpace(break_space);
     TestIsBreakable(expected_break_positions, lazy_break_iterator);
     TestNextBreakOpportunity(expected_break_positions, lazy_break_iterator);
   }
@@ -43,7 +43,8 @@
     }
     EXPECT_THAT(break_positions,
                 ::testing::ElementsAreArray(expected_break_positions))
-        << break_iterator.BreakType() << " for " << test_string_;
+        << test_string_ << " " << break_iterator.BreakType() << " "
+        << break_iterator.BreakSpace();
   }
 
   // Test NextBreakOpportunity() by iterating break opportunities.
@@ -57,7 +58,8 @@
     }
     EXPECT_THAT(break_positions,
                 ::testing::ElementsAreArray(expected_break_positions))
-        << break_iterator.BreakType() << " for " << test_string_;
+        << test_string_ << " " << break_iterator.BreakType() << " "
+        << break_iterator.BreakSpace();
   }
 
  private:
@@ -93,114 +95,124 @@
   EXPECT_TRUE(iterator.IsBreakable(0));
 }
 
-// Initializing Vector from an initializer list still not possible, C++ feature
-// banned in Blink.
-#define DECLARE_BREAKSVECTOR(...)                    \
-  static const int32_t kBreaksArray[] = __VA_ARGS__; \
-  Vector<int> breaks;                                \
-  breaks.Append(kBreaksArray, sizeof(kBreaksArray) / sizeof(*kBreaksArray));
-
-#define MATCH_LINE_BREAKS(LINEBREAKTYPE, ...)      \
-  {                                                \
-    DECLARE_BREAKSVECTOR(__VA_ARGS__);             \
-    MatchLineBreaks(LINEBREAKTYPE, false, breaks); \
-  }
-
-#define MATCH_BREAK_AFTER_SPACE(LINEBREAKTYPE, ...) \
-  {                                                 \
-    DECLARE_BREAKSVECTOR(__VA_ARGS__);              \
-    MatchLineBreaks(LINEBREAKTYPE, true, breaks);   \
-  }
-
 TEST_F(TextBreakIteratorTest, Basic) {
   SetTestString("a b  c");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {1, 3, 4, 6});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {2, 5, 6});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 3, 4, 6});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 3, 4, 6},
+                  BreakSpaceType::kBeforeSpace);
+  MatchLineBreaks(LineBreakType::kNormal, {2, 5, 6}, BreakSpaceType::kAfter);
+}
+
+TEST_F(TextBreakIteratorTest, Newline) {
+  SetTestString("a\nb\n\nc");
+  MatchLineBreaks(LineBreakType::kNormal, {1, 3, 4, 6});
+  MatchLineBreaks(LineBreakType::kNormal, {2, 5, 6},
+                  BreakSpaceType::kBeforeSpace);
+  MatchLineBreaks(LineBreakType::kNormal, {2, 5, 6}, BreakSpaceType::kAfter);
+}
+
+TEST_F(TextBreakIteratorTest, Tab) {
+  SetTestString("a\tb\t\tc");
+  MatchLineBreaks(LineBreakType::kNormal, {1, 3, 4, 6});
+  MatchLineBreaks(LineBreakType::kNormal, {2, 5, 6},
+                  BreakSpaceType::kBeforeSpace);
+  MatchLineBreaks(LineBreakType::kNormal, {2, 5, 6}, BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, LatinPunctuation) {
   SetTestString("(ab) cd.");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {4, 8});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {2, 4, 6, 8});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter, {1, 2, 3, 4, 5, 6, 7, 8});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {4, 8});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {5, 8});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {2, 5, 6, 8});
+  MatchLineBreaks(LineBreakType::kNormal, {4, 8});
+  MatchLineBreaks(LineBreakType::kBreakAll, {2, 4, 6, 8});
+  MatchLineBreaks(LineBreakType::kBreakCharacter, {1, 2, 3, 4, 5, 6, 7, 8});
+  MatchLineBreaks(LineBreakType::kKeepAll, {4, 8});
+  MatchLineBreaks(LineBreakType::kNormal, {5, 8}, BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {2, 5, 6, 8},
+                  BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, Chinese) {
   SetTestString("標準萬國碼");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {1, 2, 3, 4, 5});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {1, 2, 3, 4, 5});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter, {1, 2, 3, 4, 5});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {5});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {1, 2, 3, 4, 5});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {1, 2, 3, 4, 5});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 2, 3, 4, 5});
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 3, 4, 5});
+  MatchLineBreaks(LineBreakType::kBreakCharacter, {1, 2, 3, 4, 5});
+  MatchLineBreaks(LineBreakType::kKeepAll, {5});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 2, 3, 4, 5},
+                  BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 3, 4, 5},
+                  BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, ChineseMixed) {
   SetTestString("標(準)萬ab國.碼");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {1, 4, 5, 7, 9, 10});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {1, 4, 5, 6, 7, 9, 10});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter,
-                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {1, 4, 9, 10});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {1, 4, 5, 7, 9, 10});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {1, 4, 5, 6, 7, 9, 10});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 4, 5, 7, 9, 10});
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 4, 5, 6, 7, 9, 10});
+  MatchLineBreaks(LineBreakType::kBreakCharacter,
+                  {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+  MatchLineBreaks(LineBreakType::kKeepAll, {1, 4, 9, 10});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 4, 5, 7, 9, 10},
+                  BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 4, 5, 6, 7, 9, 10},
+                  BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, ChineseSpaces) {
   SetTestString("標  萬  a  國");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {1, 2, 4, 5, 7, 8, 10});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {1, 2, 4, 5, 7, 8, 10});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter,
-                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {1, 2, 4, 5, 7, 8, 10});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {3, 6, 9, 10});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {3, 6, 9, 10});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 2, 4, 5, 7, 8, 10});
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 4, 5, 7, 8, 10});
+  MatchLineBreaks(LineBreakType::kBreakCharacter,
+                  {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+  MatchLineBreaks(LineBreakType::kKeepAll, {1, 2, 4, 5, 7, 8, 10});
+  MatchLineBreaks(LineBreakType::kNormal, {1, 2, 4, 5, 7, 8, 10},
+                  BreakSpaceType::kBeforeSpace);
+  MatchLineBreaks(LineBreakType::kNormal, {3, 6, 9, 10},
+                  BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {3, 6, 9, 10},
+                  BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, KeepEmojiZWJFamilyIsolate) {
   SetTestString(u8"\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {11});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {11});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter, {11});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {11});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {11});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {11});
+  MatchLineBreaks(LineBreakType::kNormal, {11});
+  MatchLineBreaks(LineBreakType::kBreakAll, {11});
+  MatchLineBreaks(LineBreakType::kBreakCharacter, {11});
+  MatchLineBreaks(LineBreakType::kKeepAll, {11});
+  MatchLineBreaks(LineBreakType::kNormal, {11}, BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {11}, BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, KeepEmojiModifierSequenceIsolate) {
   SetTestString(u8"\u261D\U0001F3FB");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {3});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {3});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter, {3});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {3});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {3});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {3});
+  MatchLineBreaks(LineBreakType::kNormal, {3});
+  MatchLineBreaks(LineBreakType::kBreakAll, {3});
+  MatchLineBreaks(LineBreakType::kBreakCharacter, {3});
+  MatchLineBreaks(LineBreakType::kKeepAll, {3});
+  MatchLineBreaks(LineBreakType::kNormal, {3}, BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {3}, BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, KeepEmojiZWJSequence) {
   SetTestString(
       u8"abc \U0001F469\u200D\U0001F469\u200D\U0001F467\u200D\U0001F467 def");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {3, 15, 19});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {1, 2, 3, 15, 17, 18, 19});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter,
-                    {1, 2, 3, 4, 15, 16, 17, 18, 19});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {3, 15, 19});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {4, 16, 19});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {1, 2, 4, 16, 17, 18, 19});
+  MatchLineBreaks(LineBreakType::kNormal, {3, 15, 19});
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 3, 15, 17, 18, 19});
+  MatchLineBreaks(LineBreakType::kBreakCharacter,
+                  {1, 2, 3, 4, 15, 16, 17, 18, 19});
+  MatchLineBreaks(LineBreakType::kKeepAll, {3, 15, 19});
+  MatchLineBreaks(LineBreakType::kNormal, {4, 16, 19}, BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 4, 16, 17, 18, 19},
+                  BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, KeepEmojiModifierSequence) {
   SetTestString(u8"abc \u261D\U0001F3FB def");
-  MATCH_LINE_BREAKS(LineBreakType::kNormal, {3, 7, 11});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakAll, {1, 2, 3, 7, 9, 10, 11});
-  MATCH_LINE_BREAKS(LineBreakType::kBreakCharacter,
-                    {1, 2, 3, 4, 7, 8, 9, 10, 11});
-  MATCH_LINE_BREAKS(LineBreakType::kKeepAll, {3, 7, 11});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kNormal, {4, 8, 11});
-  MATCH_BREAK_AFTER_SPACE(LineBreakType::kBreakAll, {1, 2, 4, 8, 9, 10, 11});
+  MatchLineBreaks(LineBreakType::kNormal, {3, 7, 11});
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 3, 7, 9, 10, 11});
+  MatchLineBreaks(LineBreakType::kBreakCharacter,
+                  {1, 2, 3, 4, 7, 8, 9, 10, 11});
+  MatchLineBreaks(LineBreakType::kKeepAll, {3, 7, 11});
+  MatchLineBreaks(LineBreakType::kNormal, {4, 8, 11}, BreakSpaceType::kAfter);
+  MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 4, 8, 9, 10, 11},
+                  BreakSpaceType::kAfter);
 }
 
 TEST_F(TextBreakIteratorTest, NextBreakOpportunityAtEnd) {
diff --git a/third_party/WebKit/public/web/WebLocalFrame.h b/third_party/WebKit/public/web/WebLocalFrame.h
index 7916766..ed8e995 100644
--- a/third_party/WebKit/public/web/WebLocalFrame.h
+++ b/third_party/WebKit/public/web/WebLocalFrame.h
@@ -295,6 +295,11 @@
                                  bool had_redirect,
                                  const WebSourceLocation&) = 0;
 
+  // PlzNavigate
+  // Informs the frame that the navigation it asked the client to do was
+  // dropped.
+  virtual void ClientDroppedNavigation() = 0;
+
   // Orientation Changes ----------------------------------------------------
 
   // Notify the frame that the screen orientation has changed.
diff --git a/third_party/blink/tools/move_blink_source.py b/third_party/blink/tools/move_blink_source.py
index cd9c889..4b9640e 100755
--- a/third_party/blink/tools/move_blink_source.py
+++ b/third_party/blink/tools/move_blink_source.py
@@ -3,10 +3,30 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+"""Tool to move Blink source from third_party/WebKit to third_party/blink.
+
+How to use:
+1. third_party/blink/tools/move_blink_source.py update --run
+ (It would take a few minutes to complete this command.)
+2. git cl format
+3. git commit -a
+4. Land the commit
+
+5. third_party/blink/tools/move_blink_source.py move --git
+ (It would take an hour to complete this command.)
+6. third_party/WebKit/Tools/Scripts/run-bindings-test --reset-results
+7. git commit -a
+8. Land the commit
+9. Pray for successful build!
+
+TODO(tkent): More automation.
+"""
+
 import argparse
 import logging
 import os
 import re
+import subprocess
 import sys
 from functools import partial
 
@@ -16,6 +36,7 @@
                  'third_party', 'WebKit', 'Tools', 'Scripts')))
 from blinkpy.common.name_style_converter import NameStyleConverter
 from plan_blink_move import plan_blink_move
+from webkitpy.common.checkout.git import Git
 from webkitpy.common.path_finder import get_chromium_src_dir
 from webkitpy.common.system.filesystem import FileSystem
 
@@ -66,7 +87,7 @@
         self._idl_generated_impl_headers = None
         self._checked_in_header_re = None
 
-    def main(self):
+    def update(self):
         _log.info('Planning renaming ...')
         file_pairs = plan_blink_move(self._fs, [])
         _log.info('Will move %d files', len(file_pairs))
@@ -89,7 +110,26 @@
                                          [('snake_case_source_files = false',
                                            'snake_case_source_files = true')])
 
-        self._move_files(file_pairs)
+    def move(self):
+        _log.info('Planning renaming ...')
+        file_pairs = plan_blink_move(self._fs, [])
+        _log.info('Will move %d files', len(file_pairs))
+
+        git = Git(cwd=self._repo_root)
+        for i, (src, dest) in enumerate(file_pairs):
+            src_from_repo = self._fs.join('third_party', 'WebKit', src)
+            dest_from_repo = self._fs.join('third_party', 'blink', dest)
+            self._fs.maybe_make_directory(self._repo_root, 'third_party', 'blink', self._fs.dirname(dest))
+            if self._options.run_git:
+                if git.exists(src_from_repo):
+                    git.move(src_from_repo, dest_from_repo)
+                    _log.info('[%d/%d] Git moved %s', i + 1, len(file_pairs), src)
+                else:
+                    _log.info('%s is not in the repository', src)
+            else:
+                self._fs.move(self._fs.join(self._repo_root, src_from_repo),
+                              self._fs.join(self._repo_root, dest_from_repo))
+                _log.info('[%d/%d] Moved %s', i + 1, len(file_pairs), src)
 
     def _create_basename_maps(self, file_pairs):
         basename_map = {}
@@ -300,19 +340,30 @@
         else:
             _log.warning('%s does not contain specified source strings.', file_path)
 
-    def _move_files(self, file_pairs):
-        # TODO(tkent): Implement.
-        return file_pairs
-
 
 def main():
     logging.basicConfig(level=logging.DEBUG,
                         format='[%(asctime)s %(levelname)s %(name)s] %(message)s',
                         datefmt='%H:%M:%S')
     parser = argparse.ArgumentParser(description='Blink source mover')
-    parser.add_argument('--run', dest='run', action='store_true')
+    sub_parsers = parser.add_subparsers()
+
+    update_parser = sub_parsers.add_parser('update')
+    update_parser.set_defaults(command='update')
+    update_parser.add_argument('--run', dest='run', action='store_true',
+                               help='Update file contents')
+
+    move_parser = sub_parsers.add_parser('move')
+    move_parser.set_defaults(command='move')
+    move_parser.add_argument('--git', dest='run_git', action='store_true',
+                             help='Run |git mv| command instead of |mv|.')
+
     options = parser.parse_args()
-    MoveBlinkSource(FileSystem(), options, get_chromium_src_dir()).main()
+    mover = MoveBlinkSource(FileSystem(), options, get_chromium_src_dir())
+    if options.command == 'update':
+        mover.update()
+    elif options.command == 'move':
+        mover.move()
 
 
 if __name__ == '__main__':
diff --git a/third_party/crc32c/BUILD.gn b/third_party/crc32c/BUILD.gn
index af6e9d8..76283087 100644
--- a/third_party/crc32c/BUILD.gn
+++ b/third_party/crc32c/BUILD.gn
@@ -28,8 +28,7 @@
   }
 
   if (current_cpu == "arm64") {
-    # Temporarily disabled for http://crbug.com/763848
-    # defines += [ "HAVE_ARM64_CRC32C=0" ]
+    defines += [ "HAVE_ARM64_CRC32C=1" ]
   }
 
   if (is_linux || is_chromeos) {
diff --git a/third_party/crc32c/README.chromium b/third_party/crc32c/README.chromium
index 4adb768a..1df4b379 100644
--- a/third_party/crc32c/README.chromium
+++ b/third_party/crc32c/README.chromium
@@ -1,7 +1,7 @@
 Name: CRC32C
 Short Name: crc32c
 URL: https://github.com/google/crc32c
-Version: 1.0.1
+Version: 1.0.3
 License: New BSD
 License File: src/LICENSE
 Security Critical: yes
diff --git a/tools/idl_parser/idl_parser.py b/tools/idl_parser/idl_parser.py
index 9fa651b..89187bd4 100755
--- a/tools/idl_parser/idl_parser.py
+++ b/tools/idl_parser/idl_parser.py
@@ -732,7 +732,7 @@
     p[0] = self.BuildProduction('Iterable', p, 2, childlist)
 
   def p_OptionalType(self, p):
-    """OptionalType : ',' Type
+    """OptionalType : ',' TypeWithExtendedAttributes
                     |"""
     if len(p) > 1:
       p[0] = p[2]
diff --git a/tools/idl_parser/test_parser/interface_web.idl b/tools/idl_parser/test_parser/interface_web.idl
index 750eae4..e67fe2f4 100644
--- a/tools/idl_parser/test_parser/interface_web.idl
+++ b/tools/idl_parser/test_parser/interface_web.idl
@@ -324,6 +324,15 @@
  *      ExtAttributes()
  *        ExtAttribute(Clamp)
  *        ExtAttribute(XAttr)
+ *  Iterable()
+ *    Type()
+ *      PrimitiveType(long)
+ *      ExtAttributes()
+ *        ExtAttribute(Clamp)
+ *    Type()
+ *      PrimitiveType(long long)
+ *      ExtAttributes()
+ *        ExtAttribute(EnforceRange)
  */
 interface MyIfaceIterable {
   iterable<long>;
@@ -331,6 +340,7 @@
   iterable<[Clamp] long>;
   iterable<[TreatNullAs=EmptyString] DOMString>;
   iterable<[Clamp, XAttr] long>;
+  iterable<[Clamp] long, [EnforceRange] long long>;
 };
 
 /** TREE
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index acfe9a1b..9e410f9 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -8689,6 +8689,18 @@
   <int value="4" label="FAILURE_REASON_FILE_MONITOR"/>
 </enum>
 
+<enum name="DownloadAudioType">
+  <int value="0" label="UNRECOGNIZED"/>
+  <int value="1" label="AAC"/>
+  <int value="2" label="MIDI"/>
+  <int value="3" label="OGA"/>
+  <int value="4" label="WAV"/>
+  <int value="5" label="WEBA"/>
+  <int value="6" label="3GP"/>
+  <int value="7" label="3G2"/>
+  <int value="8" label="MP3"/>
+</enum>
+
 <enum name="DownloadConnectionSecurity">
   <int value="0"
       label="Final download url and the redirects before it all use https"/>
@@ -8724,13 +8736,17 @@
   <int value="4" label="VIDEO"/>
   <int value="5" label="OCTET_STREAM"/>
   <int value="6" label="PDF"/>
-  <int value="7" label="DOC"/>
-  <int value="8" label="XLS"/>
-  <int value="9" label="PPT"/>
+  <int value="7" label="DOCUMENT"/>
+  <int value="8" label="SPREADSHEET"/>
+  <int value="9" label="PRESENTATION"/>
   <int value="10" label="ARCHIVE"/>
-  <int value="11" label="EXE"/>
+  <int value="11" label="EXECUTABLE"/>
   <int value="12" label="DMG"/>
   <int value="13" label="CRX"/>
+  <int value="14" label="WEB"/>
+  <int value="15" label="EBOOK"/>
+  <int value="16" label="FONT"/>
+  <int value="17" label="APK"/>
 </enum>
 
 <enum name="DownloadCountType">
@@ -8819,6 +8835,8 @@
   <int value="4" label="TIFF"/>
   <int value="5" label="ICON"/>
   <int value="6" label="WEBP"/>
+  <int value="7" label="PSD"/>
+  <int value="8" label="SVG"/>
 </enum>
 
 <enum name="DownloadInterruptedUnknownSizeType">
@@ -9148,11 +9166,33 @@
   <int value="6" label="Initiated by Automatic Resumption"/>
 </enum>
 
+<enum name="DownloadTextType">
+  <int value="0" label="UNRECOGNIZED"/>
+  <int value="1" label="PLAIN"/>
+  <int value="2" label="CSS"/>
+  <int value="3" label="CSV"/>
+  <int value="4" label="HTML"/>
+  <int value="5" label="CALENDAR"/>
+</enum>
+
 <enum name="DownloadUploadRequestedByServer">
   <int value="0" label="No Upload"/>
   <int value="1" label="Upload Requested"/>
 </enum>
 
+<enum name="DownloadVideoType">
+  <int value="0" label="UNRECOGNIZED"/>
+  <int value="1" label="AVI"/>
+  <int value="2" label="MPEG"/>
+  <int value="3" label="OGV"/>
+  <int value="4" label="WEBM"/>
+  <int value="5" label="3GP"/>
+  <int value="6" label="3G2"/>
+  <int value="7" label="MP4"/>
+  <int value="8" label="MOV"/>
+  <int value="9" label="WMV"/>
+</enum>
+
 <enum name="DragContent">
   <int value="0" label="Unknown"/>
   <int value="1" label="Image"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 0d228e7..ae818fd 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -15577,11 +15577,6 @@
   </summary>
 </histogram>
 
-<histogram name="Download.ContentImageType" enum="DownloadImageType">
-  <owner>asanka@chromium.org</owner>
-  <summary>Types of images that are downloaded.</summary>
-</histogram>
-
 <histogram name="Download.ContentLength.Parallelizable" units="KB">
   <owner>qinmin@chromium.org</owner>
   <summary>
@@ -15598,6 +15593,26 @@
   <summary>Content types that are downloaded.</summary>
 </histogram>
 
+<histogram name="Download.ContentType.Audio" enum="DownloadAudioType">
+  <owner>jming@chromium.org</owner>
+  <summary>Types of audio files that are downloaded.</summary>
+</histogram>
+
+<histogram name="Download.ContentType.Image" enum="DownloadImageType">
+  <owner>asanka@chromium.org</owner>
+  <summary>Types of images that are downloaded.</summary>
+</histogram>
+
+<histogram name="Download.ContentType.Text" enum="DownloadTextType">
+  <owner>jming@chromium.org</owner>
+  <summary>Types of text files that are downloaded.</summary>
+</histogram>
+
+<histogram name="Download.ContentType.Video" enum="DownloadVideoType">
+  <owner>jming@chromium.org</owner>
+  <summary>Types of video files that are downloaded.</summary>
+</histogram>
+
 <histogram name="Download.Counts" enum="DownloadCountType">
   <owner>asanka@chromium.org</owner>
   <summary>
diff --git a/tools/perf/benchmarks/loading.py b/tools/perf/benchmarks/loading.py
index 8672e098..0e8ff58 100644
--- a/tools/perf/benchmarks/loading.py
+++ b/tools/perf/benchmarks/loading.py
@@ -29,10 +29,6 @@
   """ A benchmark measuring loading performance of desktop sites. """
   SUPPORTED_PLATFORMS = [story.expectations.ALL_DESKTOP]
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    return possible_browser.browser_type == 'reference'
-
   def CreateStorySet(self, options):
     return page_sets.LoadingDesktopStorySet(
         cache_temperatures=[cache_temperature.PCV1_COLD,
@@ -57,20 +53,6 @@
   """ A benchmark measuring loading performance of mobile sites. """
   SUPPORTED_PLATFORMS = [story.expectations.ALL_MOBILE]
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    # crbug.com/619254
-    if possible_browser.browser_type == 'reference':
-      return True
-
-    # crbug.com/676612
-    if ((possible_browser.platform.GetDeviceTypeName() == 'Nexus 6' or
-         possible_browser.platform.GetDeviceTypeName() == 'AOSP on Shamu') and
-        possible_browser.browser_type == 'android-webview'):
-      return True
-
-    return False
-
   def CreateStorySet(self, options):
     return page_sets.LoadingMobileStorySet(
         cache_temperatures=[cache_temperature.ANY],
@@ -79,6 +61,8 @@
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
+        self.DisableBenchmark(
+            [story.expectations.ANDROID_NEXUS6_WEBVIEW], 'crbug.com/676612')
         self.DisableStory('GFK', [story.expectations.ALL],
                           'N5X Timeout issue: crbug.com/702175')
         self.DisableStory('MLSMatrix', [story.expectations.ALL],
diff --git a/tools/perf/benchmarks/memory.py b/tools/perf/benchmarks/memory.py
index 002a498..8b225f1c 100644
--- a/tools/perf/benchmarks/memory.py
+++ b/tools/perf/benchmarks/memory.py
@@ -180,17 +180,12 @@
   def Name(cls):
     return 'memory.long_running_idle_gmail_tbmv2'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    return (cls.IsSvelte(possible_browser) or  # http://crbug.com/611167
-            # http://crbug.com/671650
-            ((possible_browser.browser_type == 'reference' and
-              possible_browser.platform.GetDeviceTypeName() == 'Nexus 5')))
-
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass # Nothing disabled.
+        self.DisableBenchmark(
+            [story.expectations.ANDROID_SVELTE],
+            'Requires a lot of memory: crbug.com/611167')
     return StoryExpectations()
 
 
@@ -208,12 +203,10 @@
   def Name(cls):
     return 'memory.long_running_idle_gmail_background_tbmv2'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):  # http://crbug.com/616530
-    return cls.IsSvelte(possible_browser)
-
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass
+        self.DisableBenchmark(
+            [story.expectations.ANDROID_SVELTE],
+            'Requires a lot of memory: crbug.com/616530')
     return StoryExpectations()
diff --git a/tools/perf/benchmarks/oortonline.py b/tools/perf/benchmarks/oortonline.py
index be3670f..08cced9 100644
--- a/tools/perf/benchmarks/oortonline.py
+++ b/tools/perf/benchmarks/oortonline.py
@@ -108,10 +108,6 @@
     return options
 
   @classmethod
-  def ShouldDisable(cls, possible_browser):
-    return possible_browser.platform.GetDeviceTypeName() == 'Nexus 9'
-
-  @classmethod
   def Name(cls):
     return 'oortonline_tbmv2'
 
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py
index fefe3bd..66f1e573 100644
--- a/tools/perf/benchmarks/smoothness.py
+++ b/tools/perf/benchmarks/smoothness.py
@@ -1,8 +1,6 @@
 # Copyright 2013 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-import multiprocessing
-
 from core import perf_benchmark
 
 from benchmarks import silk_flags
@@ -50,18 +48,6 @@
   def Name(cls):
     return 'smoothness.top_25_smooth'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    # http://crbug.com/597656
-    if (possible_browser.browser_type == 'reference' and
-        possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X'):
-      return True
-    # http://crbug.com/650762
-    if (possible_browser.browser_type == 'reference' and
-        possible_browser.platform.GetOSName() == 'win'):
-      return True
-    return False
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
@@ -88,21 +74,11 @@
   def Name(cls):
     return 'smoothness.tough_filters_cases'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    # http://crbug.com/616520
-    if (cls.IsSvelte(possible_browser) and
-        possible_browser.browser_type == 'reference'):
-      return True
-    # http://crbug.com/624032
-    if possible_browser.platform.GetDeviceTypeName() == 'Nexus 6':
-      return True
-    return False
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass # Nothing.
+        self.DisableBenchmark([story_module.expectations.ANDROID_NEXUS6],
+                              'crbug.com/624032')
     return StoryExpectations()
 
 
@@ -222,11 +198,6 @@
   def Name(cls):
     return 'smoothness.key_mobile_sites_smooth'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):  # http://crbug.com/597656
-      return (possible_browser.browser_type == 'reference' and
-              possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
@@ -245,12 +216,6 @@
   def Name(cls):
     return 'smoothness.tough_animation_cases'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):  # http://crbug.com/595737
-    # This test is flaky on low-end windows machine.
-    return (possible_browser.platform.GetOSName() == 'win' and
-            multiprocessing.cpu_count() <= 2)
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
@@ -320,11 +285,6 @@
   def Name(cls):
     return 'smoothness.gpu_rasterization.top_25_smooth'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):  # http://crbug.com/597656
-      return (possible_browser.browser_type == 'reference' and
-              possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
@@ -386,11 +346,6 @@
   def Name(cls):
     return 'smoothness.gpu_rasterization.tough_filters_cases'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):  # http://crbug.com/616540
-    return (cls.IsSvelte(possible_browser) and
-            possible_browser.browser_type == 'reference')
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
@@ -414,11 +369,6 @@
   def Name(cls):
     return 'smoothness.sync_scroll.key_mobile_sites_smooth'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):  # http://crbug.com/597656
-      return (possible_browser.browser_type == 'reference' and
-              possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
@@ -756,17 +706,11 @@
   def Name(cls):
     return 'smoothness.pathological_mobile_sites'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    # http://crbug.com/685342
-    if possible_browser.platform.GetDeviceTypeName() == 'Nexus 7':
-      return True
-    return False
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass
+        self.DisableBenchmark([story_module.expectations.ANDROID_NEXUS7],
+                              'crbug.com/685342')
     return StoryExpectations()
 
 
@@ -794,10 +738,6 @@
     return 'smoothness.tough_ad_cases'
 
   @classmethod
-  def ShouldDisable(cls, possible_browser):
-    return cls.IsSvelte(possible_browser)  # http://crbug.com/555089
-
-  @classmethod
   def ValueCanBeAddedPredicate(cls, value, is_first_result):
     del is_first_result  # unused
     # These pages don't scroll so it's not necessary to measure input latency.
@@ -806,7 +746,8 @@
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass # Nothing.
+        self.DisableBenchmark([story_module.expectations.ANDROID_SVELTE],
+                              'www.crbug.com/555089')
     return StoryExpectations()
 
 
@@ -819,14 +760,11 @@
   def Name(cls):
     return 'smoothness.tough_webgl_ad_cases'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    return cls.IsSvelte(possible_browser)  # http://crbug.com/574485
-
   def GetExpectations(self):
     class StoryExpectations(story_module.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass # Nothing.
+        self.DisableBenchmark([story_module.expectations.ANDROID_SVELTE],
+                              'crbug.com/574485')
     return StoryExpectations()
 
 
diff --git a/tools/perf/benchmarks/start_with_url.py b/tools/perf/benchmarks/start_with_url.py
index ef4daab..c142c7fae 100644
--- a/tools/perf/benchmarks/start_with_url.py
+++ b/tools/perf/benchmarks/start_with_url.py
@@ -44,11 +44,6 @@
     super(StartWithUrlColdTBM, self).SetExtraBrowserOptions(options)
 
   @classmethod
-  def ShouldDisable(cls, possible_browser):  # http://crbug.com/667470
-    return (possible_browser.platform.GetDeviceTypeName() in
-            ['Nexus 7v2', 'Nexus 9'])
-
-  @classmethod
   def Name(cls):
     return 'start_with_url.cold.startup_pages'
 
@@ -56,6 +51,8 @@
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
+        self.DisableBenchmark(
+            [story.expectations.ANDROID_NEXUS7], 'crbug.com/667470')
         self.DisableStory(
             'http://kapook.com', [story.expectations.ALL], 'crbug.com/667470')
     return StoryExpectations()
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py
index 94a85b8..1e8f43e2 100644
--- a/tools/perf/benchmarks/v8.py
+++ b/tools/perf/benchmarks/v8.py
@@ -25,13 +25,6 @@
   def Name(cls):
     return 'v8.detached_context_age_in_gc'
 
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    # http://crbug.com/685350
-    if possible_browser.platform.GetDeviceTypeName() == 'Nexus 9':
-      return True
-    return False
-
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index cf5a99a..5a688491 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -830,7 +830,10 @@
 
 # List of benchmarks that are to never be run with reference builds.
 BENCHMARK_REF_BUILD_BLACKLIST = [
-  'power.idle_platform',
+  'power.idle_platform',  # No browser used in benchmark.
+  'loading.desktop',  # Long running benchmark.
+  'loading.mobile',  # Long running benchmark.
+  'v8.runtime_stats.top_25',  # Long running benchmark.
 ]
 
 
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index e23d4eb..6467c1d 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -2448,6 +2448,10 @@
 }
 
 STDMETHODIMP AXPlatformNodeWin::removeSelection(LONG selection_index) {
+  WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_REMOVE_SELECTION);
+  COM_OBJECT_VALIDATE();
+  AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
+
   if (selection_index != 0)
     return E_INVALIDARG;
   // Simply collapse the selection to the position of the caret if a caret is
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
index 0695285..160ab8e3 100644
--- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -2207,4 +2207,29 @@
   EXPECT_EQ(4, count);
 }
 
+TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextRemoveSelection) {
+  AXNodeData text_field_node;
+  text_field_node.id = 1;
+  text_field_node.role = AX_ROLE_TEXT_FIELD;
+  text_field_node.state = 1 << AX_STATE_EDITABLE;
+  text_field_node.state |= 1 << AX_STATE_SELECTED;
+  text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_START, 1);
+  text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, 2);
+  text_field_node.SetValue("Hi");
+  Init(text_field_node);
+  ScopedComPtr<IAccessible2> ia2_text_field =
+      ToIAccessible2(GetRootIAccessible());
+  ScopedComPtr<IAccessibleText> text_field;
+  ia2_text_field.CopyTo(text_field.GetAddressOf());
+  ASSERT_NE(nullptr, text_field.Get());
+
+  EXPECT_HRESULT_SUCCEEDED(text_field->removeSelection(0));
+
+  LONG start_offset, end_offset;
+  EXPECT_HRESULT_SUCCEEDED(
+      text_field->get_selection(0, &start_offset, &end_offset));
+  ASSERT_EQ(2, start_offset);
+  ASSERT_EQ(2, end_offset);
+}
+
 }  // namespace ui
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc
index d60d44c..c15cf8f 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.cc
+++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -175,12 +175,49 @@
   return gfx::kNullAcceleratedWidget;
 }
 
+void TestAXNodeWrapper::ReplaceIntAttribute(int32_t node_id,
+                                            AXIntAttribute attribute,
+                                            int32_t value) {
+  if (!tree_)
+    return;
+
+  AXNode* node = tree_->GetFromId(node_id);
+  if (!node)
+    return;
+
+  AXNodeData new_data = node->data();
+  std::vector<std::pair<AXIntAttribute, int32_t>>& attributes =
+      new_data.int_attributes;
+
+  auto deleted = std::remove_if(
+      attributes.begin(), attributes.end(),
+      [attribute](auto& pair) { return pair.first == attribute; });
+  attributes.erase(deleted, attributes.end());
+
+  new_data.AddIntAttribute(attribute, value);
+  node->SetData(new_data);
+}
+
 bool TestAXNodeWrapper::AccessibilityPerformAction(
     const ui::AXActionData& data) {
-  if (data.action == ui::AX_ACTION_SCROLL_TO_POINT)
+  if (data.action == ui::AX_ACTION_SCROLL_TO_POINT) {
     g_offset = gfx::Vector2d(data.target_point.x(), data.target_point.x());
-  else if (data.action == ui::AX_ACTION_SCROLL_TO_MAKE_VISIBLE)
+    return true;
+  }
+
+  if (data.action == ui::AX_ACTION_SCROLL_TO_MAKE_VISIBLE) {
     g_offset = gfx::Vector2d(data.target_rect.x(), data.target_rect.x());
+    return true;
+  }
+
+  if (data.action == ui::AX_ACTION_SET_SELECTION) {
+    ReplaceIntAttribute(data.anchor_node_id, AX_ATTR_TEXT_SEL_START,
+                        data.anchor_offset);
+    ReplaceIntAttribute(data.anchor_node_id, AX_ATTR_TEXT_SEL_END,
+                        data.focus_offset);
+    return true;
+  }
+
   return true;
 }
 
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h
index 426ab51c..d0f1603 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.h
+++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -48,6 +48,9 @@
 
  private:
   TestAXNodeWrapper(AXTree* tree, AXNode* node);
+  void ReplaceIntAttribute(int32_t node_id,
+                           AXIntAttribute attribute,
+                           int32_t value);
 
   TestAXNodeWrapper* HitTestSyncInternal(int x, int y);
 
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc
index 7ee3d01..6ad16377 100644
--- a/ui/android/view_android.cc
+++ b/ui/android/view_android.cc
@@ -80,12 +80,10 @@
   return view_.get(env);
 }
 
-ViewAndroid::ViewAndroid(ViewClient* view_client)
-    : parent_(nullptr),
-      client_(view_client),
-      layout_params_(LayoutParams::MatchParent()) {}
+ViewAndroid::ViewAndroid(ViewClient* view_client, LayoutType layout_type)
+    : parent_(nullptr), client_(view_client), layout_type_(layout_type) {}
 
-ViewAndroid::ViewAndroid() : ViewAndroid(nullptr) {}
+ViewAndroid::ViewAndroid() : ViewAndroid(nullptr, LayoutType::NORMAL) {}
 
 ViewAndroid::~ViewAndroid() {
   observer_list_.Clear();
@@ -144,9 +142,8 @@
 
   // Empty view size also need not propagating down in order to prevent
   // spurious events with empty size from being sent down.
-  if (child->layout_params_.match_parent && layout_params_.width != 0 &&
-      layout_params_.height != 0) {
-    child->OnSizeChangedInternal(layout_params_.width, layout_params_.height);
+  if (child->match_parent() && !view_rect_.IsEmpty()) {
+    child->OnSizeChangedInternal(view_rect_.size());
     DispatchOnSizeChanged();
   }
 
@@ -383,31 +380,32 @@
 }
 
 void ViewAndroid::OnSizeChanged(int width, int height) {
-  // TODO(jinsukkim): Assert match-parent here. Match-parent view should keep
-  // its size in sync with its parent, ignoring the incoming size change event.
+  // Match-parent view must not receive size events.
+  DCHECK(!match_parent());
+
   float scale = GetDipScale();
-  OnSizeChangedInternal(std::ceil(width / scale), std::ceil(height / scale));
+  OnSizeChangedInternal(
+      gfx::Size(std::ceil(width / scale), std::ceil(height / scale)));
 
   // Signal resize event after all the views in the tree get the updated size.
   DispatchOnSizeChanged();
 }
 
-void ViewAndroid::OnSizeChangedInternal(int width, int height) {
-  if (layout_params_.width == width && layout_params_.height == height)
+void ViewAndroid::OnSizeChangedInternal(const gfx::Size& size) {
+  if (view_rect_.size() == size)
     return;
 
-  layout_params_.width = width;
-  layout_params_.height = height;
+  view_rect_.set_size(size);
   for (auto* child : children_) {
-    if (child->layout_params_.match_parent)
-      child->OnSizeChangedInternal(width, height);
+    if (child->match_parent())
+      child->OnSizeChangedInternal(size);
   }
 }
 
 void ViewAndroid::DispatchOnSizeChanged() {
   client_->OnSizeChanged();
   for (auto* child : children_) {
-    if (child->layout_params_.match_parent)
+    if (child->match_parent())
       child->DispatchOnSizeChanged();
   }
 }
@@ -487,18 +485,14 @@
 
   if (!children_.empty()) {
     gfx::PointF offset_point(point);
-    offset_point.Offset(-layout_params_.x, -layout_params_.y);
+    offset_point.Offset(-view_rect_.x(), -view_rect_.y());
     gfx::Point int_point = gfx::ToFlooredPoint(offset_point);
 
     // Match from back to front for hit testing.
     for (auto* child : base::Reversed(children_)) {
-      bool matched = child->layout_params_.match_parent;
-      if (!matched) {
-        gfx::Rect bound(child->layout_params_.x, child->layout_params_.y,
-                        child->layout_params_.width,
-                        child->layout_params_.height);
-        matched = bound.Contains(int_point);
-      }
+      bool matched = child->match_parent();
+      if (!matched)
+        matched = child->view_rect_.Contains(int_point);
       if (matched && child->HitTest(send_to_client, event, offset_point))
         return true;
     }
@@ -506,4 +500,8 @@
   return false;
 }
 
+void ViewAndroid::SetLayoutForTesting(int x, int y, int width, int height) {
+  view_rect_.SetRect(x, y, width, height);
+}
+
 }  // namespace ui
diff --git a/ui/android/view_android.h b/ui/android/view_android.h
index 0cc1a9a..be27534 100644
--- a/ui/android/view_android.h
+++ b/ui/android/view_android.h
@@ -24,6 +24,7 @@
 
 namespace gfx {
 class Point;
+class Size;
 }
 
 namespace ui {
@@ -83,33 +84,14 @@
     // Default copy/assign disabled by move constructor.
   };
 
-  // Layout parameters used to set the view's position and size.
-  // Position is in parent's coordinate space, and all the values
-  // are in CSS pixel.
-  struct LayoutParams {
-    static LayoutParams MatchParent() { return {true, 0, 0, 0, 0}; }
-    static LayoutParams Normal(int x, int y, int width, int height) {
-      return {false, x, y, width, height};
-    };
-
-    bool match_parent;  // Bounds matches that of the parent if true.
-    int x;
-    int y;
-    int width;
-    int height;
-
-    LayoutParams(const LayoutParams& p) = default;
-
-   private:
-    LayoutParams(bool match_parent, int x, int y, int width, int height)
-        : match_parent(match_parent),
-          x(x),
-          y(y),
-          width(width),
-          height(height) {}
+  enum class LayoutType {
+    // Can have its own size given by |OnSizeChanged| events.
+    NORMAL,
+    // Always follows its parent's size.
+    MATCH_PARENT
   };
 
-  explicit ViewAndroid(ViewClient* view_client);
+  ViewAndroid(ViewClient* view_client, LayoutType layout_type);
 
   ViewAndroid();
   virtual ~ViewAndroid();
@@ -205,6 +187,8 @@
   void OnAttachedToWindow();
   void OnDetachedFromWindow();
 
+  void SetLayoutForTesting(int x, int y, int width, int height);
+
   template <typename E>
   using ViewClientCallback =
       const base::Callback<bool(ViewClient*, const E&, const gfx::PointF&)>;
@@ -229,6 +213,8 @@
 
   bool has_event_forwarder() const { return !!event_forwarder_; }
 
+  bool match_parent() const { return layout_type_ == LayoutType::MATCH_PARENT; }
+
   // Checks if there is any event forwarder in any node up to root.
   static bool RootPathHasEventForwarder(ViewAndroid* view);
 
@@ -236,7 +222,7 @@
   // each leaf of subtree.
   static bool SubtreeHasEventForwarder(ViewAndroid* view);
 
-  void OnSizeChangedInternal(int width, int height);
+  void OnSizeChangedInternal(const gfx::Size& size);
   void DispatchOnSizeChanged();
 
   // Returns the Java delegate for this view. This is used to delegate work
@@ -253,8 +239,9 @@
   ViewClient* const client_;
 
   // Basic view layout information. Used to do hit testing deciding whether
-  // the passed events should be processed by the view.
-  LayoutParams layout_params_;
+  // the passed events should be processed by the view. Unit in DIP.
+  gfx::Rect view_rect_;
+  const LayoutType layout_type_;
 
   // In physical pixel.
   gfx::Size physical_size_;
diff --git a/ui/android/view_android_unittests.cc b/ui/android/view_android_unittests.cc
index e267dd04..4466ffb 100644
--- a/ui/android/view_android_unittests.cc
+++ b/ui/android/view_android_unittests.cc
@@ -17,7 +17,8 @@
 
 class TestViewAndroid : public ViewAndroid {
  public:
-  explicit TestViewAndroid(ViewClient* client) : ViewAndroid(client) {}
+  TestViewAndroid(ViewClient* client, ViewAndroid::LayoutType layout_type)
+      : ViewAndroid(client, layout_type) {}
 
   float GetDipScale() override { return 1.f; }
 };
@@ -50,18 +51,19 @@
 class ViewAndroidBoundsTest : public testing::Test {
  public:
   ViewAndroidBoundsTest()
-      : root_(nullptr),
-        view1_(&client1_),
-        view2_(&client2_),
-        view3_(&client3_) {
+      : root_(nullptr, ViewAndroid::LayoutType::MATCH_PARENT),
+        view1_(&client1_, ViewAndroid::LayoutType::NORMAL),
+        view2_(&client2_, ViewAndroid::LayoutType::NORMAL),
+        view3_(&client3_, ViewAndroid::LayoutType::NORMAL),
+        viewm_(&clientm_, ViewAndroid::LayoutType::MATCH_PARENT) {
     root_.GetEventForwarder();
-    root_.layout_params_ = ViewAndroid::LayoutParams::MatchParent();
   }
 
   void Reset() {
     client1_.Reset();
     client2_.Reset();
     client3_.Reset();
+    clientm_.Reset();
   }
 
   void GenerateTouchEventAt(float x, float y) {
@@ -74,7 +76,7 @@
   }
 
   void ExpectHit(const TestViewClient& hitClient) {
-    TestViewClient* clients[3] = {&client1_, &client2_, &client3_};
+    TestViewClient* clients[4] = {&client1_, &client2_, &client3_, &clientm_};
     for (auto* client : clients) {
       if (&hitClient == client)
         EXPECT_TRUE(client->TouchEventHandled());
@@ -88,15 +90,16 @@
   TestViewAndroid view1_;
   TestViewAndroid view2_;
   TestViewAndroid view3_;
+  TestViewAndroid viewm_;  // match-parent view
   TestViewClient client1_;
   TestViewClient client2_;
   TestViewClient client3_;
+  TestViewClient clientm_;
 };
 
 TEST_F(ViewAndroidBoundsTest, MatchesViewInFront) {
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(50, 50, 400, 600);
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(50, 50, 400, 600);
-  view2_.layout_params_ = ViewAndroid::LayoutParams::Normal(50, 50, 400, 600);
+  view1_.SetLayoutForTesting(50, 50, 400, 600);
+  view2_.SetLayoutForTesting(50, 50, 400, 600);
   root_.AddChild(&view2_);
   root_.AddChild(&view1_);
 
@@ -110,8 +113,8 @@
 }
 
 TEST_F(ViewAndroidBoundsTest, MatchesViewArea) {
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(50, 50, 200, 200);
-  view2_.layout_params_ = ViewAndroid::LayoutParams::Normal(20, 20, 400, 600);
+  view1_.SetLayoutForTesting(50, 50, 200, 200);
+  view2_.SetLayoutForTesting(20, 20, 400, 600);
 
   root_.AddChild(&view2_);
   root_.AddChild(&view1_);
@@ -126,27 +129,26 @@
 }
 
 TEST_F(ViewAndroidBoundsTest, MatchesViewAfterMove) {
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(50, 50, 200, 200);
-  view2_.layout_params_ = ViewAndroid::LayoutParams::Normal(20, 20, 400, 600);
+  view1_.SetLayoutForTesting(50, 50, 200, 200);
+  view2_.SetLayoutForTesting(20, 20, 400, 600);
   root_.AddChild(&view2_);
   root_.AddChild(&view1_);
 
   GenerateTouchEventAt(100.f, 100.f);
   ExpectHit(client1_);
 
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(150, 150, 200, 200);
+  view1_.SetLayoutForTesting(150, 150, 200, 200);
   GenerateTouchEventAt(100.f, 100.f);
   ExpectHit(client2_);
 }
 
 TEST_F(ViewAndroidBoundsTest, MatchesViewSizeOfkMatchParent) {
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(20, 20, 400, 600);
-  view3_.layout_params_ = ViewAndroid::LayoutParams::MatchParent();
-  view2_.layout_params_ = ViewAndroid::LayoutParams::Normal(50, 50, 200, 200);
+  view1_.SetLayoutForTesting(20, 20, 400, 600);
+  view2_.SetLayoutForTesting(50, 50, 200, 200);
 
   root_.AddChild(&view1_);
   root_.AddChild(&view2_);
-  view1_.AddChild(&view3_);
+  view1_.AddChild(&viewm_);
 
   GenerateTouchEventAt(100.f, 100.f);
   ExpectHit(client2_);
@@ -157,13 +159,13 @@
   client1_.SetHandleEvent(false);
   GenerateTouchEventAt(300.f, 400.f);
   EXPECT_TRUE(client1_.TouchEventCalled());
-  ExpectHit(client3_);
+  ExpectHit(clientm_);
 }
 
 TEST_F(ViewAndroidBoundsTest, MatchesViewsWithOffset) {
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(10, 20, 150, 100);
-  view2_.layout_params_ = ViewAndroid::LayoutParams::Normal(20, 30, 40, 30);
-  view3_.layout_params_ = ViewAndroid::LayoutParams::Normal(70, 30, 40, 30);
+  view1_.SetLayoutForTesting(10, 20, 150, 100);
+  view2_.SetLayoutForTesting(20, 30, 40, 30);
+  view3_.SetLayoutForTesting(70, 30, 40, 30);
 
   root_.AddChild(&view1_);
   view1_.AddChild(&view2_);
@@ -184,38 +186,31 @@
 
 TEST_F(ViewAndroidBoundsTest, OnSizeChanged) {
   root_.AddChild(&view1_);
-  view1_.AddChild(&view2_);
+  view1_.AddChild(&viewm_);
   view1_.AddChild(&view3_);
 
-  view1_.layout_params_ = ViewAndroid::LayoutParams::Normal(0, 0, 0, 0);
-  view2_.layout_params_ = ViewAndroid::LayoutParams::MatchParent();
-  view3_.layout_params_ = ViewAndroid::LayoutParams::Normal(0, 0, 0, 0);
-
   // Size event propagates to non-match-parent children only.
   view1_.OnSizeChanged(100, 100);
   EXPECT_TRUE(client1_.OnSizeCalled());
-  EXPECT_TRUE(client2_.OnSizeCalled());
+  EXPECT_TRUE(clientm_.OnSizeCalled());
   EXPECT_FALSE(client3_.OnSizeCalled());
 
   Reset();
 
-  // TODO(jinsukkim): Enable following test once the top view can be
-  //     set to have match-parent property.
-
-  // Match-parent view should ignore the size event.
-  // view2_.OnSizeChanged(100, 200);
-  // EXPECT_FALSE(client2_.OnSizeCalled());
-  // EXPECT_FALSE(client3_.OnSizeCalled());
+  // Match-parent view should not receivee size events in the first place.
+  EXPECT_DCHECK_DEATH(viewm_.OnSizeChanged(100, 200));
+  EXPECT_FALSE(clientm_.OnSizeCalled());
+  EXPECT_FALSE(client3_.OnSizeCalled());
 
   Reset();
 
-  view2_.RemoveFromParent();
+  viewm_.RemoveFromParent();
   view1_.OnSizeChanged(100, 100);
 
   // Size event is generated for a newly added, match-parent child view.
-  EXPECT_FALSE(client2_.OnSizeCalled());
-  view1_.AddChild(&view2_);
-  EXPECT_TRUE(client2_.OnSizeCalled());
+  EXPECT_FALSE(clientm_.OnSizeCalled());
+  view1_.AddChild(&viewm_);
+  EXPECT_TRUE(clientm_.OnSizeCalled());
   EXPECT_FALSE(client3_.OnSizeCalled());
 }
 
diff --git a/ui/events/blink/blink_features.cc b/ui/events/blink/blink_features.cc
index 13e9c1c7..6fd8d82 100644
--- a/ui/events/blink/blink_features.cc
+++ b/ui/events/blink/blink_features.cc
@@ -9,7 +9,7 @@
 // Enables VSync aligned input for GestureScroll/Pinch on compositor thread.
 // Tracking: https://crbug.com/625689
 const base::Feature kVsyncAlignedInputEvents{"VsyncAlignedInput",
-                                             base::FEATURE_DISABLED_BY_DEFAULT};
+                                             base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kSendMouseLeaveEvents{"SendMouseLeaveEvents",
                                           base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ui/views/bubble/tray_bubble_view.cc b/ui/views/bubble/tray_bubble_view.cc
index 21f640cb..bdc738b 100644
--- a/ui/views/bubble/tray_bubble_view.cc
+++ b/ui/views/bubble/tray_bubble_view.cc
@@ -256,7 +256,7 @@
 void TrayBubbleView::UpdateBubble() {
   if (GetWidget()) {
     SizeToContents();
-    bubble_content_mask_->layer()->SetBounds(layer()->bounds());
+    bubble_content_mask_->layer()->SetBounds(GetBubbleBounds());
     GetWidget()->GetRootView()->SchedulePaint();
 
     // When extra keyboard accessibility is enabled, focus the default item if
@@ -301,7 +301,7 @@
 
 void TrayBubbleView::SizeToContents() {
   BubbleDialogDelegateView::SizeToContents();
-  bubble_content_mask_->layer()->SetBounds(layer()->bounds());
+  bubble_content_mask_->layer()->SetBounds(GetBubbleBounds());
 }
 
 void TrayBubbleView::OnBeforeBubbleWidgetInit(Widget::InitParams* params,